I am trying to post a file using cURL and receive it on the other side via a CGI Bash script and store it with the same name. After upload is completed, diff
between the original file and reconstructed one should return zero.
The way cURL sends data:
curl --request POST --data-binary "@dummy.dat" 127.0.0.1/cgi-bin/upload-rpm
Receiver script:
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
echo '<title>Foo</title>'
echo '</head>'
echo '<body>'
echo "<p>Start</p>"
if [ "$REQUEST_METHOD" = "POST" ]; then
echo "<p>Post Method</p>"
if [ "$CONTENT_LENGTH" -gt 0 ]; then
echo "<p>Size=$CONTENT_LENGTH</p>"
while read -n 1 byte -t 3; do echo -n -e "$byte" >> ./foo.dat ; done
fi
fi
echo '</body>'
echo '</html>'
exit 0
But it's not working. File is not created on the server side. And how can I get the file name?
POST sends the data through standard input, while GET passes the information through environment variables. If no method is specified, the server defaults to GET.
CGI stands for Common Gateway Interface. It is a way to let Apache execute script files and send the output to the client. Those script files can be written in any language understood by the server. Yes, you can write a CGI script using BASH, Korn shell, Perl, Python or even C! Tools of the trade.
In computing, Common Gateway Interface (CGI) is an interface specification that enables web servers to execute an external program, typically to process user requests. Such programs are often written in a scripting language and are commonly referred to as CGI scripts, but they may include compiled programs.
as long as you're always uploading exactly 1 file using the multipart/form-data
format and the client always put the Content-Type
as the last header of the file upload (which curl always seem to do), this seem to work:
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
echo '<title>Foo</title>'
echo '</head>'
echo '<body>'
echo "<p>Start</p>"
if [ "$REQUEST_METHOD" = "POST" ]; then
echo "<p>Post Method</p>"
if [ "$CONTENT_LENGTH" -gt 0 ]; then
in_raw="$(cat)"
boundary=$(echo -n "$in_raw" | head -1 | tr -d '\r\n');
filename=$(echo -n "$in_raw" | grep --text --max-count=1 -oP "(?<=filename=\")[^\"]*");
file_content=$(echo -n "$in_raw" | sed '1,/Content-Type:/d' | tail -c +3 | head --lines=-1 | head --bytes=-4 );
echo "boundary: $boundary"
echo "filename: $filename"
#echo "file_content: $file_content"
fi
fi
echo '</body>'
echo '</html>'
exit 0
example upload invocation (which I used to debug the above):
curl http://localhost:81/cgi-bin/wtf.sh -F "[email protected]"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With