问题陈述:
我正在尝试使用HTTP post请求通过HTML表单上传文件,然后将其写入本地服务器上名为configuration.xml的文件。我只能使用服务器的库存功能,因此,尽管我喜欢,但我不能使用cURL,PHP,Perl或我必须安装的任何东西。服务器。我尝试做的是让HTML表单打开一个CGI文件作为表单操作,所有这些CGI文件都运行带有正确HTML格式的Bash脚本。我会直接从HTML表单中运行Bash脚本,但是我的研究让我相信这是不可能的,而不必编辑.htaccess或其他hacky替代品,这不是我想要的道路。 (如果这可以合理的方式完成,请赐教!)无论如何,我能够成功运行Bash脚本。我知道这是因为我放了一个" touch configuration.xml"脚本中的命令,每次都会创建它。我的脚本也能够告诉它它是一个HTTP Post,如浏览器中的回显文本所示,但是我似乎无法正确读取文件中的任何数据。我尝试回显数据以及将读取数据重定向到文件,但浏览器中没有任何内容,也没有写入我指定的文件。这很好,可能是我不太了解Bash脚本或者像这样的傻事,但我真的不知道如何从这里开始。
代码:
UploadToServer.html:
<form action="run_script.cgi" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="Submit">
</form>
run_script.c:
注意:我使用以下命令将其编译为CGI文件:gcc run_script.c -o run_script.cgi
#include <stdlib.h>
#include <stdio.h>
int main() {
system("./test.sh &");
printf("Content-Type: text/html\r\n\r\n");
printf(""); // print blank line for proper HTML header formatting
printf("<html>\n");
printf("</HTML>\n");
}
test.sh:
第二个if语句中的非注释代码来自here。评论的代码来自here。
#!/bin/bash
touch configuration.xml
if [[ $REQUEST_METHOD = 'POST' ]]; then
echo "this is a post!"
if [ "$CONTENT_LENGTH" -gt 0 ]; then
echo "entered second if statement!"
# read -n $CONTENT_LENGTH POST_DATA <&0
# echo "$CONTENT_LENGTH"
while read line
do eval "echo ${line}"
done
fi
fi
我也尝试了this post的第三个代码块中的方法,但没有得到任何输出。我还查看了this post,但它似乎并没有像我需要的那样从文件中获取所有数据。我也尝试过使用这篇文章中建议的CGI文件的方法(_http://blog.purplepixie.org/2013/08/cc-cgi-file-upload/),但是,再次没有输出。我一直在查看Apache错误日志,因为我尝试了新的东西并且没有出现错误。
有人对我可能做错了什么有任何想法吗?是否有值得研究的不同方法?非常感谢任何建议!
答案 0 :(得分:0)
在朋友们的帮助下,我想出了怎么做。我最终在CGI脚本中执行了所有操作,并在Bash组件之前进行了操作。虽然这不是我在原始问题中所要求的,但它可以为我完成工作,这正是问题所在。
以下是我现在用于在服务器上成功写入文件的C代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void print_empty_html_page();
int main() {
char * req_method_str = getenv("REQUEST_METHOD");
if (req_method_str != NULL) {
if (strcmp(req_method_str, "POST") == 0) {
// process POST arguments
char * len_str = getenv("CONTENT_LENGTH");
if (len_str != NULL) {
int len = atoi(len_str);
if (len > 0) {
FILE * fp;
fp = fopen("file.xml", "w");
char * postdata = malloc((len + 1) * sizeof(char));
fread(postdata, sizeof(char), len, stdin);
postdata[len] = '\0';
fprintf(fp, "%s\n", postdata);
free(postdata);
fclose(fp);
}
system("sed -e '/Content/d' -e '/[-][-][*][*][*][*][*]/d' -e '/^[s]*$/d' -e '/WebKitFormBoundary/d' -e '/Submit/d' < file.xml > file_trimmed.xml");
system("rm file.xml");
}
}
}
print_empty_html_page();
return 0;
}
void print_empty_html_page() {
// Send the content type, letting the browser know this is HTML
printf("Content-type: text/html\r\n\r\n");
// Header information that prevents browser from caching
printf(
"<META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE, NO-STORE\">\r\n\r\n");
// Top of the page
printf("<html>\n");
printf("<BODY>\n");
// Finish up the page
printf("</BODY></html>\n");
}
注意:此方法将整个HTTP POST写入文件'file.xml'。系统调用'sed'是从HTTP POST中删除与上载文件中的实际数据不对应的标记。如果您需要检查其他不需要的行,只需在该sed调用中添加另一个-e '/<line_with_expression_to_delete>/d'
,其中line_with_expression_to_delete是您要匹配的表达式,然后删除包含该表达式的所有行。根据我的研究,我无法弄清楚如何删除新上传文件中的所有空白行,即使'/^[s]*$/d'
应该这样做。必须要考虑更多...
另请注意:此方法仅适用于上传文本文件。它不适用于其他文件类型,例如JPEG或OGG。
希望这有助于其他人遇到同样的问题。如果您有任何问题,请告诉我。