androidcodeexamples.com
Offcode ltd logo
ANDROID
APACHE
THUMBNAILS
SCRIPTS
GFX
World-class examples brought to you by Offcode ltd
APACHE
Getting started Upload to server Image server Image manipulation Image cache reCAPTCHA Front Page
androidcodeexamples.com

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

contact information