4

I'm trying to write a little HTTP server using netcat. For plain text files this works fine but when I try to send a picture, the browser displays only the icon for broken images. What I do is extracting the mime-type and size of a requested file and cat it to the client. The header of a request of my example picture looks like this:

HTTP/1.0 200 OK
Content-Length: 197677 
Content-Type: image/jpeg

This is my bash script which I launch with -e option of the netcat tool:

#!/bin/bash

# -- OPTIONS
index_page=index.htm
error_page=notfound.htm

# -- CODE

# read request
read -s input
resource=$(echo $input | grep -P -o '(?<=GET \/).*(?=\ )') # extract requested file
[ ! -n "$resource" ] && resource=$index_page # if no file requested, set to default
[ ! -f "$resource" ] && resource=$error_page # if requested file not exists, show error pag

# generate output
http_content_type=$(file -b --mime-type $resource) # extract mime type
case "$(echo $http_content_type | cut -d '/' -f2)" in
    html|plain)
        output=$(cat $resource)

        # fix mime type for plain text documents
        echo $resource | grep -q '.css$' && http_content_type=${http_content_type//plain/css}
        echo $resource | grep -q '.js$' && http_content_type=${http_content_type//plain/javascript}
    ;;

    x-php)
        output=$(php $resource)
        http_content_type=${http_content_type//x-php/html} # fix mime type
    ;;

    jpeg)
        output=$(cat $resource)
    ;;

    png)
        output=$(cat $resource)
    ;;

    *)
        echo 'Unknown type'
esac

http_content_length="$(echo $output | wc -c | cut -d ' ' -f1)"

# sending reply
echo "HTTP/1.0 200 OK"
echo "Content-Length: $http_content_length"
echo -e "Content-Type: $http_content_type\n"
echo $output

Would be very happy if someone is able to help me :-)

Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
flappix
  • 2,038
  • 17
  • 28

1 Answers1

0

I'd expect that special characters in the binary data are active in your shell script.

I'd recommend that you get the file size with:

http_content_length=`stat -c '%s' $resource`

And you "send" it with:

...
echo -e "Content-Type: $http_content_type\n"
cat $resource
MattH
  • 37,273
  • 11
  • 82
  • 84
  • This works, thank you very much. I used this workaround with the output variable to parse php code but I will find a way without this – flappix Mar 27 '13 at 15:47
  • @flappix: create a temp file, write the php output to it, set $resource to the tempfile name? – MattH Mar 27 '13 at 15:51
  • I solved it this way, but thank you for you helpful thoughts http://ompldr.org/vaHdnYg/httpservera edit: okay, your idea is better, I changed it ;-) thx – flappix Mar 27 '13 at 15:57