Sending an image (png/jpeg) or binary data to server
This example proposes a method how to send and receive binary data via a linux shell script. It may be an image such as png or jpeg or just any binary data. Please note that this script is in the server. The uploading client is your browser.
HTML code for multipart upload
This is how the HTML code looks like:
<form enctype="multipart/form-data" action="/s/upload" method="post"> <p> Select File: <input type="file" size="35" name="uploadedfile" /> <br/> <input type="submit" name="Upload" value="Upload" /> </p> </form>
Shell script to download image or binary file into server
We have a script called 'upload' in our /usr/lib/s/ directory. This is where the HTML post method is targeted. Once user hits the 'Upload' button, the browser starts to upload the data into the server. There's a lot of comments in the script itself that should clarify things.
#!/bin/bash cd /home/imageserviceagent/ 2>/dev/null > /dev/null # Check what Apache gives env > environment.txt # Verify this is a multipart form we're expecting: echo "$CONTENT_TYPE" | grep "multipart/form-data" 2> /dev/null >/dev/null if [ $? -ne 0 ]; then echo "Error multipart" > error.txt echo "<PRE>Error #1</PRE>" echo "" exit fi # Verify it has the boundary set: echo "$CONTENT_TYPE" | grep "boundary=" 2> /dev/null >/dev/null if [ $? -ne 0 ]; then echo "Error boundary" > error.txt echo "<PRE>Error #2</PRE>" echo "" exit fi BOUNDARY=`echo "$CONTENT_TYPE" | sed 's/^.*boundary=//'` # Perform the actual download: /bin/dd count=$CONTENT_LENGTH bs=1 2>/dev/null > upload.bin # Copy the boundary into a separate file for debugging echo "$BOUNDARY" > upboundary.txt # For you to check the original contents before rework cp upload.bin upload.orig # Check the first line is the boundary LN=`head -1 upload.bin` echo "$LN" | grep "\-\-$BOUNDARY" >/dev/null 2>/dev/null if [ $? -ne 0 ]; then echo "ln:" "$LN" > error.txt echo "b:" "$BOUNDARY" >> error.txt exit fi # Delete the first line as it's verified already sed -i '1d' upload.bin >/dev/null 2>/dev/null # Delete all lines starting with "Content-" while : ; do LN=`head -1 upload.bin` echo $LN | grep -i "Content-" >/dev/null 2>/dev/null if [ $? -eq 0 ]; then sed -i '1d' upload.bin >/dev/null 2>/dev/null else # remove empty line sed -i '1d' upload.bin >/dev/null 2>/dev/null break; fi done # Delete everything from the boundary mark at the end of the file sed -i '/--'"$BOUNDARY"'/Q' upload.bin > /dev/null 2>/dev/null # Remove trailing line feed truncate -s -2 upload.bin > /dev/null 2>/dev/null if [ $? -eq 0 ]; then /bin/echo "Content-type: text/html" /bin/echo "" /bin/echo "<html><h2>Thanks for uploading!</h2></html>" /bin/echo "" exit fi
Use diff to check that the original binary and the uploaded one (upload.bin) match. At the end of the script we could check whether the png or jpeg file is corrupted or not.
This has been tested on IE, Firefox and Chrome browsers with various image sizes up to 140 megs on Ubuntu 16.04.4 LTS.
Speeding up the upload / download procedure
Large files don't transfer well with the above example. However, let's optimize it a bit. Instead of using the bs=1, let's use 1M instead:
# Perform the actual download: /bin/dd count=$CONTENT_LENGTH bs=1 2>/dev/null > upload.bin
# Perform the actual download: /bin/dd count=$CONTENT_LENGTH bs=1M 2>/dev/null > upload.bin
The download speed change is amazing: the latter uploads 30 megabytes at the blink of an eye while the former takes near a minute! This illustrates how adjusting a single parameter does make a change! Postprocessing also seems to consume around the seconds after uploading a 140 megabyte image. Amazingly, the binary is still exact; it doesn't get corrupted. However, there's quite a few things that may still be optimized.
Written on April 2018 by Eero Nurkkala