Reading HTTP POST data using BASH

I recently needed to read the HTTP POST data using a BASH cgi script.

When using BASH this way most of the HTTP variables are set as environment variables, and can be accessed simply. The exception is the HTTP POST data, this goes to the stdin stream.

There were some examples of reading stdin like:

1
POST_DATA=$(</dev/stdin)

and

1
POST_DATA=`cat /dev/stdin`

However I found that these intermittently failed. I believe this is because at the point of execution you can not guarantee that all the data has been sent.

The solution to this is to use the CONTENT_LENGTH environment variable to read the correct number of bytes:

1
2
3
4
5
6
#!/bin/bash
if [ "$REQUEST_METHOD" = "POST" ]; then
    if [ "$CONTENT_LENGTH" -gt 0 ]; then
        read -n $CONTENT_LENGTH POST_DATA <&0
    fi
fi

7 Responses to “Reading HTTP POST data using BASH”

  1. This was a very helpful post ! Thanks,

  2. Cheers,

    I was using the POST_DATA=$(</dev/stdin) method in my scripts which was working on my desktop but failing on my embedded device, thanks for the info.
    G.

  3. Hi Paul,

    Thanks for sharing, it really helped me to fix some issues.

  4. Hi Paul,

    For some reason, above script is unable to read POST data for requests sent from IE.

    Could you please help me to resolve this.

    Thanks
    Mahesh

  5. linux 022…

    […]Reading HTTP POST data using BASH | Paul Turner[…]…

  6. John Kuriakose on April 4th, 2018 at 3:56 pm

    It should be -N instead of -n else it will stop on a delimiter.

  7. I guess you’re right. This was a long time ago and I didn’t have any issue with -n for what I needed. Looking at the manual http://linuxcommand.org/lc3_man_pages/readh.html it looks like -N is valid but I haven’t tested this.

Leave a Reply