2018-07-27 Fred Gleason <fredg@paravelsystems.com>

* Added a 'SaveFile' test method to the web API.
	* Added a 'SaveString' test method to the web API.
	* Refactored the multipart-mime parser in 'RDFormPost' to process
	UTF-8 strings correctly.
This commit is contained in:
Fred Gleason
2018-07-27 14:28:55 -04:00
parent 046ddb0264
commit 542fb7d6a6
18 changed files with 429 additions and 138 deletions

View File

@@ -17238,3 +17238,8 @@
2018-07-27 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in ripcd(8) that threw a segfault when executing
'DC!'.
2018-07-27 Fred Gleason <fredg@paravelsystems.com>
* Added a 'SaveFile' test method to the web API.
* Added a 'SaveString' test method to the web API.
* Refactored the multipart-mime parser in 'RDFormPost' to process
UTF-8 strings correctly.

View File

@@ -2916,6 +2916,66 @@
</table>
</sect1>
<sect1>
<title>SaveFile</title>
<subtitle>
Write a specified file to the '/tmp' directory. (Test only)
</subtitle>
<para>
Command Code: <code>RDXPORT_COMMAND_SAVEFILE</code>
</para>
<para>
Required User Permissions: none
</para>
<para>
NOTE: The method must be called with 'multipart/form-data' encoding.
</para>
<table xml:id="ex.savefile" frame="all">
<title>SaveString Call Fields</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="FIELD NAME" />
<colspec colname="MEANING" />
<colspec colname="REMARKS" />
<thead>
<row>
<entry>
FIELD NAME
</entry>
<entry>
MEANING
</entry>
<entry>
REMARKS
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
COMMAND
</entry>
<entry>
36
</entry>
<entry>
Mandatory
</entry>
</row>
<row>
<entry>
FILENAME
</entry>
<entry>
Binary file data
</entry>
<entry>
Mandatory
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1>
<title>SaveLog</title>
@@ -3466,6 +3526,64 @@
</table>
</sect1>
<sect1>
<title>SaveString</title>
<subtitle>
Write a specified string to the syslog. (Test only)
</subtitle>
<para>
Command Code: <code>RDXPORT_COMMAND_SAVESTRING</code>
</para>
<para>
Required User Permissions: none
</para>
<table xml:id="ex.savestring" frame="all">
<title>SaveString Call Fields</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="FIELD NAME" />
<colspec colname="MEANING" />
<colspec colname="REMARKS" />
<thead>
<row>
<entry>
FIELD NAME
</entry>
<entry>
MEANING
</entry>
<entry>
REMARKS
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
COMMAND
</entry>
<entry>
35
</entry>
<entry>
Mandatory
</entry>
</row>
<row>
<entry>
STRING
</entry>
<entry>
UTF-8 String
</entry>
<entry>
Mandatory
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1>
<title>TrimAudio</title>
<subtitle>

View File

@@ -481,19 +481,6 @@ void RDFormPost::LoadUrlEncoding(char first)
}
post_data[post_content_length]=0;
/*
* Uncomment this to dump the raw post data to "/tmp/output.dat".
*/
/*
int out=open("/tmp/output.dat",O_WRONLY|O_CREAT);
write(out,post_data,post_content_length);
::close(out);
printf("Content-type: text/html\n\n");
printf("POST DUMPED TO \"/tmp/output.dat\"!\n");
exit(0);
*/
lines=lines.split("&",post_data);
for(unsigned i=0;i<lines.size();i++) {
line=line.split("=",lines[i]);
@@ -516,108 +503,111 @@ void RDFormPost::LoadUrlEncoding(char first)
void RDFormPost::LoadMultipartEncoding(char first)
{
std::map<QString,QString> headers;
bool header=true;
post_data=NULL;
FILE *f=NULL;
ssize_t n=0;
QString sep;
QString name;
QString filename;
QString tempdir;
int fd=-1;
if((f=fdopen(0,"r"))==NULL) {
//
// Create Stream Readers
//
if((post_stream=fdopen(0,"r"))==NULL) {
post_error=RDFormPost::ErrorInternal;
return;
}
/*
* Uncomment this to dump the raw post data to "/tmp/output.dat".
*/
/*
int out=open("/tmp/output.dat",O_WRONLY|O_CREAT);
while((n=getline(&post_data,(size_t *)&n,f))>0) {
write(out,post_data,n);
}
::close(out);
printf("Content-type: text/html\n\n");
printf("POST DUMPED TO \"/tmp/output.dat\"!\n");
exit(0);
*/
if((n=getline(&post_data,(size_t *)&n,f))<=0) {
post_error=RDFormPost::ErrorMalformedData;
QFile *file=new QFile();
if(!file->open(IO_ReadOnly,post_stream)) {
delete file;
post_error=RDFormPost::ErrorInternal;
return;
}
sep=QString(post_data).simplifyWhiteSpace();
post_text_reader=new QTextStream(file);
post_text_reader->setEncoding(QTextStream::UnicodeUTF8);
//
// Get message parts
// Get Separator Line
//
while((n=getline(&post_data,(size_t *)&n,f))>0) {
if(QString(post_data).simplifyWhiteSpace().contains(sep)>0) { // End of part
if(fd>=0) {
ftruncate(fd,lseek(fd,0,SEEK_CUR)-2); // Remove extraneous final CR/LF
::close(fd);
fd=-1;
}
name="";
filename="";
headers.clear();
header=true;
continue;
}
if(header) { // Read header
if(QString(post_data).simplifyWhiteSpace().isEmpty()) {
if(!headers["content-disposition"].isNull()) {
QStringList fields;
fields=fields.split(";",headers["content-disposition"]);
if(fields.size()>0) {
if(fields[0].lower().simplifyWhiteSpace()=="form-data") {
for(unsigned i=1;i<fields.size();i++) {
QStringList pairs;
pairs=pairs.split("=",fields[i]);
if(pairs[0].lower().simplifyWhiteSpace()=="name") {
name=pairs[1].simplifyWhiteSpace();
name.replace("\"","");
}
if(pairs[0].lower().simplifyWhiteSpace()=="filename") {
filename=post_tempdir->path()+"/"+
pairs[1].simplifyWhiteSpace();
filename.replace("\"","");
fd=open(filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
}
}
post_separator=first+post_text_reader->readLine();
//
// Read Mime Parts
//
QString name;
QString value;
bool is_file;
bool again=false;
do {
again=GetMimePart(&name,&value,&is_file);
post_values[name]=value;
post_filenames[name]=is_file;
} while(again);
delete post_text_reader;
delete file;
post_error=RDFormPost::ErrorOk;
}
bool RDFormPost::GetMimePart(QString *name,QString *value,bool *is_file)
{
QString line;
int fd=-1;
*name="";
*value="";
*is_file=false;
//
// Headers
//
do {
line=post_text_reader->readLine();
QStringList f0=f0.split(":",line);
if(f0.size()==2) {
if(f0[0].lower()=="content-disposition") {
QStringList f1=f1.split(";",f0[1]);
for(unsigned i=0;i<f1.size();i++) {
QStringList f2=f2.split("=",f1[i].stripWhiteSpace());
if(f2.size()==2) {
if(f2[0]=="name") {
*name=f2[1].replace("\"","");
}
if(f2[0]=="filename") {
*value=post_tempdir->path()+"/"+f2[1].replace("\"","");
fd=open(value->utf8(),O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
*is_file=true;
}
}
}
header=false;
}
else {
QStringList hdr;
hdr=hdr.split(":",QString(post_data).simplifyWhiteSpace());
// Reconcaternate trailing sections so we don't split on the
// useless M$ drive letter supplied by IE
for(unsigned i=2;i<hdr.size();i++) {
hdr[1]+=hdr[i];
}
headers[hdr[0].lower()]=hdr[1];
}
}
else { // Read data
if(filename.isEmpty()) {
QString str=post_values[name].toString();
str+=QString(post_data);
post_filenames[name]=false;
post_values[name]=str.simplifyWhiteSpace();
}
else {
post_filenames[name]=true;
post_values[name]=filename;
write(fd,post_data,n);
}
} while(!line.stripWhiteSpace().isEmpty());
//
// Value
//
if(*is_file) {
char *data=NULL;
size_t n=0;
n=getline(&data,&n,post_stream);
line=QString(data).stripWhiteSpace();
while(!line.contains(post_separator)) {
write(fd,data,n);
n=getline(&data,&n,post_stream);
line=QString(data).stripWhiteSpace();
}
free(data);
}
else {
line=post_text_reader->readLine();
while(!line.contains(post_separator)) {
*value+=line;
line=post_text_reader->readLine();
}
}
post_error=RDFormPost::ErrorOk;
if(fd>=0) {
ftruncate(fd,lseek(fd,0,SEEK_CUR)-2); // Remove extraneous final CR/LF
close(fd);
}
return line.right(2)!="--";
}

View File

@@ -23,8 +23,10 @@
#include <map>
#include <qdatastream.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qvariant.h>
#include <qhostaddress.h>
@@ -64,6 +66,7 @@ class RDFormPost
private:
void LoadUrlEncoding(char first);
void LoadMultipartEncoding(char first);
bool GetMimePart(QString *name,QString *value,bool *is_file);
QHostAddress post_client_address;
RDFormPost::Encoding post_encoding;
RDFormPost::Error post_error;
@@ -74,6 +77,10 @@ class RDFormPost
unsigned post_content_length;
QString post_content_type;
char *post_data;
QString post_separator;
FILE *post_stream;
QTextStream *post_text_reader;
};

View File

@@ -55,6 +55,8 @@
#define RDXPORT_COMMAND_REHASH 32
#define RDXPORT_COMMAND_LISTSYSTEMSETTINGS 33
#define RDXPORT_COMMAND_LOCKLOG 34
#define RDXPORT_COMMAND_SAVESTRING 35
#define RDXPORT_COMMAND_SAVEFILE 36
#endif // RDXPORT_INTERFACE_H

View File

@@ -44,6 +44,7 @@ dist_rdxport_cgi_SOURCES = audioinfo.cpp\
logs.cpp\
rdxport.cpp rdxport.h\
rehash.cpp\
tests.cpp\
schedcodes.cpp\
services.cpp\
systemsettings.cpp\

View File

@@ -107,7 +107,7 @@ void Xport::AddCart()
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cartAdd>\n");
if(cart->exists()) {
printf("%s",(const char *)cart->xml(false,true));
printf("%s",(const char *)cart->xml(false,true).utf8());
SendNotification(RDNotification::CartType,RDNotification::AddAction,
QVariant(cart->number()));
}
@@ -151,11 +151,9 @@ void Xport::ListCarts()
where=RDAllCartSearchText(filter,"",rda->user()->name(),false);
}
else {
sql=QString().
sprintf("select GROUP_NAME from USER_PERMS \
where (GROUP_NAME=\"%s\")&&(USER_NAME=\"%s\")",
(const char *)RDEscapeString(group_name),
(const char *)RDEscapeString(rda->user()->name()));
sql=QString("select GROUP_NAME from USER_PERMS where ")+
"(GROUP_NAME=\""+RDEscapeString(group_name)+"\")&&"+
"(USER_NAME=\""+RDEscapeString(rda->user()->name())+"\")";
q=new RDSqlQuery(sql);
if(!q->first()) {
delete q;
@@ -176,7 +174,7 @@ void Xport::ListCarts()
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cartList>\n");
printf("%s\n",(const char *)RDCart::xml(q,include_cuts,true));
printf("%s\n",(const char *)RDCart::xml(q,include_cuts,true).utf8());
printf("</cartList>\n");
delete q;
Exit(0);
@@ -215,7 +213,7 @@ void Xport::ListCart()
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cartList>\n");
cart=new RDCart(cart_number);
printf("%s",(const char *)cart->xml(include_cuts,true));
printf("%s",(const char *)cart->xml(include_cuts,true).utf8());
delete cart;
printf("</cartList>\n");
@@ -395,7 +393,7 @@ void Xport::EditCart()
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cartList>\n");
printf("%s",(const char *)cart->xml(include_cuts,true));
printf("%s",(const char *)cart->xml(include_cuts,true).utf8());
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
QVariant(cart->number()));
delete cart;
@@ -488,7 +486,8 @@ void Xport::AddCut()
printf("<cutAdd>\n");
cut=new RDCut(cart_number,cut_number);
if(cut->exists()) {
printf("%s",(const char *)RDCart::cutXml(cart_number,cut_number,true));
printf("%s",
(const char *)RDCart::cutXml(cart_number,cut_number,true).utf8());
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
QVariant(cart->number()));
}
@@ -531,7 +530,7 @@ void Xport::ListCuts()
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cutList>\n");
while(q->next()) {
printf("%s\n",(const char *)RDCut::xml(q,false));
printf("%s\n",(const char *)RDCut::xml(q,false).utf8());
}
printf("</cutList>\n");
delete q;
@@ -575,7 +574,7 @@ void Xport::ListCut()
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cutList>\n");
printf("%s",(const char *)RDCart::cutXml(cart_number,cut_number,true));
printf("%s",(const char *)RDCart::cutXml(cart_number,cut_number,true).utf8());
printf("</cutList>\n");
delete cut;
@@ -849,7 +848,7 @@ void Xport::EditCut()
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<cutList>\n");
printf("%s",(const char *)RDCart::cutXml(cart_number,cut_number,true));
printf("%s",(const char *)RDCart::cutXml(cart_number,cut_number,true).utf8());
printf("</cutList>\n");
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
QVariant(cut->cartNumber()));

View File

@@ -65,7 +65,7 @@ void Xport::DeleteAudio()
delete q;
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
QVariant(cartnum));
syslog(LOG_NOTICE,"unlink(%s): %s",(const char *)RDCut::pathName(cartnum,cutnum),strerror(errno));
syslog(LOG_NOTICE,"unlink(%s): %s",(const char *)RDCut::pathName(cartnum,cutnum).utf8(),strerror(errno));
delete cut;
XmlExit("OK",200,"deleteaudio.cpp",LINE_NUMBER);
}

View File

@@ -43,9 +43,10 @@ void Xport::ListGroups()
//
// Generate Group List
//
sql=QString().sprintf("select GROUP_NAME from USER_PERMS \
where USER_NAME=\"%s\" order by GROUP_NAME",
(const char *)RDEscapeString(rda->user()->name()));
sql=QString("select ")+
"GROUP_NAME from USER_PERMS where "+
"USER_NAME=\""+RDEscapeString(rda->user()->name())+"\" "+
"order by GROUP_NAME";
q=new RDSqlQuery(sql);
//
@@ -57,7 +58,7 @@ void Xport::ListGroups()
printf("<groupList>\n");
while(q->next()) {
group=new RDGroup(q->value(0).toString());
printf("%s",(const char *)group->xml());
printf("%s",(const char *)group->xml().utf8());
delete group;
}
printf("</groupList>\n");
@@ -84,10 +85,10 @@ void Xport::ListGroup()
//
// Check Group Accessibility
//
sql=QString().sprintf("select GROUP_NAME from USER_PERMS \
where (USER_NAME=\"%s\")&&(GROUP_NAME=\"%s\")",
(const char *)RDEscapeString(rda->user()->name()),
(const char *)RDEscapeString(group_name));
sql=QString("select ")+
"GROUP_NAME from USER_PERMS where "+
"(USER_NAME=\""+RDEscapeString(rda->user()->name())+"\")&&"+
"(GROUP_NAME=\""+RDEscapeString(group_name)+"\")";
q=new RDSqlQuery(sql);
if(!q->first()) {
delete q;
@@ -101,7 +102,7 @@ void Xport::ListGroup()
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
group=new RDGroup(q->value(0).toString());
printf("%s",(const char *)group->xml());
printf("%s",(const char *)group->xml().utf8());
delete group;
delete q;

View File

@@ -192,7 +192,7 @@ void Xport::ListLogs()
printf("<logList>\n");
while(q->next()) {
log=new RDLog(q->value(0).toString());
printf("%s",(const char *)log->xml());
printf("%s",(const char *)log->xml().utf8());
delete log;
}
printf("</logList>\n");
@@ -233,7 +233,7 @@ void Xport::ListLog()
printf("Content-type: application/xml\n");
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("%s\n",(const char *)log_event->xml());
printf("%s\n",(const char *)log_event->xml().utf8());
Exit(0);
}
@@ -601,24 +601,24 @@ void Xport::LockLog()
addr=xport_remote_address;
lock_guid=RDLogLock::makeGuid(xport_remote_hostname);
if(RDLogLock::tryLock(&username,&stationname,&addr,log_name,lock_guid)) {
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr));
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr).utf8());
}
else {
printf("%s",(const char *)LogLockXml(false,log_name,"",username,
stationname,addr));
stationname,addr).utf8());
}
Exit(0);
break;
case Xport::LockLogUpdate:
RDLogLock::updateLock(log_name,lock_guid);
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr));
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr).utf8());
Exit(0);
break;
case Xport::LockLogClear:
RDLogLock::clearLock(lock_guid);
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr));
printf("%s",(const char *)LogLockXml(true,log_name,lock_guid,"","",addr).utf8());
Exit(0);
break;
}

View File

@@ -56,7 +56,7 @@ Xport::Xport(QObject *parent)
printf("Content-type: text/html\n");
printf("Status: 500\n");
printf("\n");
printf("rdxport.cgi: %s\n",(const char *)err_msg);
printf("rdxport.cgi: %s\n",(const char *)err_msg.utf8());
Exit(0);
}
@@ -69,7 +69,7 @@ Xport::Xport(QObject *parent)
printf("Status: 500\n");
printf("\n");
printf("rdxport.cgi: unknown command option \"%s\"\n",
(const char *)rda->cmdSwitch()->key(i));
(const char *)rda->cmdSwitch()->key(i).utf8());
Exit(0);
}
}
@@ -120,7 +120,11 @@ Xport::Xport(QObject *parent)
LINE_NUMBER);
Exit(0);
}
/*
printf("Content-type: text/html; charset=UTF-8\n\n");
xport_post->dump();
exit(0);
*/
//
// Authenticate Connection
//
@@ -282,6 +286,14 @@ void Xport::ripcConnectedData(bool state)
Rehash();
break;
case RDXPORT_COMMAND_SAVESTRING:
SaveString();
break;
case RDXPORT_COMMAND_SAVEFILE:
SaveFile();
break;
default:
printf("Content-type: text/html\n\n");
printf("rdxport: missing/invalid command\n");
@@ -400,9 +412,9 @@ void Xport::TryCreateTicket(const QString &name)
printf("Content-type: application/xml\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("<ticketInfo>\n");
printf(" %s\n",(const char *)RDXmlField("ticket",ticket));
printf(" %s\n",(const char *)RDXmlField("ticket",ticket).utf8());
printf(" %s\n",(const char *)
RDXmlField("expires",now.addSecs(rda->user()->webapiAuthTimeout())));
RDXmlField("expires",now.addSecs(rda->user()->webapiAuthTimeout())).utf8());
printf("</ticketInfo>\n");
exit(0);
}

View File

@@ -86,6 +86,8 @@ class Xport : public QObject
QString LogLockXml(bool result,const QString &log_name,const QString &guid,
const QString &username,const QString &stationname,
const QHostAddress addr) const;
void SaveString();
void SaveFile();
void SendNotification(RDNotification::Type type,RDNotification::Action action,
const QVariant &id);
void Exit(int code);

View File

@@ -78,7 +78,7 @@ void Xport::ListServices()
printf("<serviceList>\n");
while(q->next()) {
svc=new RDSvc(q->value(0).toString(),rda->station(),rda->config());
printf("%s",(const char *)svc->xml());
printf("%s",(const char *)svc->xml().utf8());
delete svc;
}
printf("</serviceList>\n");

View File

@@ -40,6 +40,6 @@ void Xport::ListSystemSettings()
//
printf("Content-type: application/xml\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("%s\n",(const char *)sys->xml());
printf("%s\n",(const char *)sys->xml().utf8());
Exit(0);
}

86
web/rdxport/tests.cpp Normal file
View File

@@ -0,0 +1,86 @@
// savestring.cpp
//
// Rivendell web service portal -- save string test
//
// (C) Copyright 2018 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <rdapplication.h>
#include <rdconf.h>
#include <rddb.h>
#include <rdescape_string.h>
#include <rdformpost.h>
#include <rdsvc.h>
#include <rduser.h>
#include <rdweb.h>
#include "rdxport.h"
void Xport::SaveString()
{
QString string;
//
// Get Options
//
if(!xport_post->getValue("STRING",&string)) {
XmlExit("Missing STRING",400,"tests.cpp",LINE_NUMBER);
}
//
// Process Request
//
syslog(LOG_NOTICE,"SAVESTRING: |%s|",(const char *)string.utf8());
printf("Content-type: application/xml; charset: UTF-8\n");
printf("Status: 200\n\n");
printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
printf("%s\n",(const char *)RDXmlField("string",string).utf8());
Exit(0);
}
void Xport::SaveFile()
{
QString filename;
QString msg="OK";
if(!xport_post->getValue("FILENAME",&filename)) {
XmlExit("Missing FILENAME",400,"tests.cpp",LINE_NUMBER);
}
if(!xport_post->isFile("FILENAME")) {
XmlExit("Missing file data",400,"tests.cpp",LINE_NUMBER);
}
if(RDCopy(filename,"/var/snd/"+RDGetBasePart(filename))) {
msg=QString("Saved file to \"/var/snd/")+RDGetBasePart(filename)+"\"";
}
else {
msg="File copy failed!";
}
printf("Content-type: text/html; charset: UTF-8\n");
printf("Status: 200\n\n");
printf("%s\n",(const char *)msg.utf8());
Exit(0);
}

View File

@@ -55,7 +55,9 @@ install-exec-am:
cp rehash.html $(DESTDIR)@libexecdir@
cp removecart.html $(DESTDIR)@libexecdir@
cp removecut.html $(DESTDIR)@libexecdir@
cp savefile.html $(DESTDIR)@libexecdir@
cp savelog.html $(DESTDIR)@libexecdir@
cp savestring.html $(DESTDIR)@libexecdir@
cp trimaudio.html $(DESTDIR)@libexecdir@
cp unassignschedcode.html $(DESTDIR)@libexecdir@
cp utils.js $(DESTDIR)@libexecdir@
@@ -94,7 +96,9 @@ uninstall-local:
rm -f $(DESTDIR)@libexecdir@/rehash.html
rm -f $(DESTDIR)@libexecdir@/removecart.html
rm -f $(DESTDIR)@libexecdir@/removecut.html
rm -f $(DESTDIR)@libexecdir@/savefile.html
rm -f $(DESTDIR)@libexecdir@/savelog.html
rm -f $(DESTDIR)@libexecdir@/savestring.html
rm -f $(DESTDIR)@libexecdir@/trimaudio.html
rm -f $(DESTDIR)@libexecdir@/unassignschedcode.html
rm -f $(DESTDIR)@libexecdir@/utils.js
@@ -132,7 +136,9 @@ EXTRA_DIST = addcart.html\
rehash.html\
removecart.html\
removecut.html\
savefile.html\
savelog.html\
savestring.html\
trimaudio.html\
unassignschedcode.html\
utils.js

33
web/tests/savefile.html Normal file
View File

@@ -0,0 +1,33 @@
<html>
<head>
<title>Rivendel SAVEFILE Service Test Harness</title>
<body>
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
<input type="hidden" name="COMMAND" value="36">
<table cellpadding="0" cellspacing="2" border="0">
<tr>
<td align="right">LOGIN NAME:</td>
<td><input type="text" name="LOGIN_NAME" size="20" maxlength="255"></td>
</tr>
<tr>
<td align="right">PASSWORD:</td>
<td><input type="password" name="PASSWORD" size="20" maxlength="32"></td>
</tr>
<tr>
<td align="right">TICKET:</td>
<td><input type="text" name="TICKET" size="40" maxlength="40"></td>
</tr>
<tr>
<td align="right">FILENAME:</td>
<td><input type="file" name="FILENAME" size="20" maxlength="64"></td>
</tr>
<tr>
<td colspan="2" align="right">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="OK"></td>
</tr>
</table>
</form>
</body>
</html>

29
web/tests/savestring.html Normal file
View File

@@ -0,0 +1,29 @@
<html>
<head>
<title>Rivendell SAVESTRING Test Harness</title>
<body>
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
<input type="hidden" name="COMMAND" value="35">
<table cellpadding="0" cellspacing="2" border="0">
<tr>
<td align="right">LOGIN NAME:</td>
<td><input type="text" name="LOGIN_NAME" size="20" maxlength="255"></td>
</tr>
<tr>
<td align="right">PASSWORD:</td>
<td><input type="password" name="PASSWORD" size="20" maxlength="32"></td>
</tr>
<tr>
<td align="right">STRING:</td>
<td><input type="text" name="STRING" size="40"></td>
</tr>
<tr>
<td colspan="2" align="right">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="OK"></td>
</tr>
</table>
</form>
</body>
</html>