how to access a body of POST request using fastcgi C/C++ application

user1495653 picture user1495653 · Oct 18, 2012 · Viewed 12.7k times · Source

I am using a library from http://fastcgi.com/ in C++ application as a backend and nginx web-server as a front-end.

Posting files from HTML-form successfully and can see the temporary files on nginx server side. But I can't figure out how to access a body of multipart POST request using fastcgi_stdio. This is my HTML-form.

<html>
    <head>
        <title>Test Server</title>
        <script src="http://code.jquery.com/jquery.min.js"></script>
    </head>
    <body>
        <form id="upload-form" method="post" target="upload_target"   enctype="multipart/form-data" action="/upload">
            <input name="file" id="file" size="27" type="file" /><br />
            <input type="submit" name="action" value="Upload" /><br />
            <iframe id="upload_target" name="upload_target" src="" style="width:100%;height:100px;border:0px solid #fff;"></iframe>
        </form>
    </body>
</html>

My nginx conf file:

location /upload {

# Pass altered request body to this location
upload_pass @test;

# Store files to this directory
# The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
upload_store /www/test;

# Allow uploaded files to be read only by user
upload_store_access user:rw group:r all:r;

# Set specified fields in request body
upload_set_form_field $upload_field_name.name $upload_file_name;
upload_set_form_field $upload_field_name.content_type "$upload_content_type";
upload_set_form_field $upload_field_name.path "$upload_tmp_path";

# Inform backend about hash and size of a file
upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

upload_pass_form_field "^submit$|^description$";
upload_cleanup 400 404 499 500-505;
}

include fastcgi.conf;

# Pass altered request body to a backend
location @test {
        fastcgi_pass  localhost:8080
}

Now, how can handle/get the POST request body in my fastcgi c++ application and how to write it in proper file at the fastcgi app side ?

Is there any better fast module to achieve this?

Thank you.

Answer

MvG picture MvG · Oct 18, 2012

You can access the POST body via the FCGI_stdin stream. For example, you can read from it one byte at a time using FCGI_getchar, which is a short form for FCGI_fgetc(FCGI_stdin). You can read larger chunks of data in a single call using FCGI_fread. All of this I found looking at the source. These sources often reference something called ”H&S”—this stands for "Harbison and Steele", the authors of the book C: A Reference Manual, and the numbers refer to chapters and sections of that book.

And by the way, it's called “stdio” for “STanDard Input/Output”. Not “studio”. The functions should mostly behave like their counterparts without FCGI_ prefixed. So for details, look at the man pages of getchar, fread and so on.

Once you have the bytes in your application, you can write them to file, either using normal stdio operations or files opened via FCGI_fopen. Note however that the input stream will not directly correspond to the content of an uploaded file. Instead, MIME encoding is used to transfer all form data, including files. You'll have to parse that stream if you want to access the file data.