Alister West

home is where your code is ...

Post Data to a cgi script.

We had a production server and I needed to test file uploads on it. Turning on logging wasn't an option (very verbose). Yes we have a dev server - but this bug was inconsistant across the environments.

GET debug.cgi

Normally with a CGI script we can run GET's on the commandline.

#!/usr/bin/env perl
# debug.cgi - and example cgi commandline script.

use CGI qw/:cgi/;
use Data::Dumper;

# print "Content-Type: text/plain\n\n";
foreach (param()) {
    print "   $_ : ", param($_);
    print ref param($_) ? ", ". Dumper (param($_)) : "\n"
}



#!/bin/sh
# Various ways of calling a perl cgi script via the command line

./debug.cgi 'foo=123&pirate=arrg'
./debug.cgi foo=123 pirate=arrg
# foo : 123
# pirate : arrg

Pretend to be a browser and POST

#!/bin/sh

# Setup netcat
nc -l 1234 | tee post.multipart

# In a different terminal
curl -F "Filename=Sheep" -F "Image=@stuff.jpg" http://localhost:1234

# Have a look at what we have
head -n20 post.multipart
    POST / HTTP/1.1
    User-Agent: curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
    Host: localhost:1234
    Accept: */*
    Content-Length: 18846
    Expect: 100-continue
    Content-Type: multipart/form-data; boundary=----------------------------38772753712c

    ------------------------------38772753712c
    Content-Disposition: form-data; name="Filename"

    Sheep
    ------------------------------38772753712c
    Content-Disposition: form-data; name="Image"; filename="stuff.jpg"
    Content-Type: image/jpeg
    .. binary data ..

Now open up post.multipart and cut out the headers (including the \n\n). Make sure you keep the headers around we'll need them soon.

POST debug.cgi

Now we do what apache/et al. does and copies the headers into the environment and run our script.

#!/bin/sh
HTTP_HOST=localhost:1234 \
CONTENT_LENGTH=18846 \
CONTENT_TYPE='multipart/form-data; boundary=----------------------------38772753712c' \
REQUEST_METHOD=POST \
./debug.cgi  < form.multipart

#   Filename : Filename
#   Image : $VAR1 = bless( \*{'Fh::fh00001stuff.jpg'}, 'Fh' );

There must be an easier way!

Please let me know if you know an easier way.

By Alister West