简体   繁体   中英

Apache module - get request body

I am creating simple apache module to capture all HTTP traffic for real time processing by security software. My goal is to get headers and body from both request and response. So far I managed to get all i need except request body. What's the best way to get request body in output filter, or in any other hook/handler to get request-response "tuple" with all releated information ?

static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    apr_status_t rv;

    request_rec *r = f->r;

    apr_bucket *e = APR_BRIGADE_FIRST(bb);
    const char *data;
    apr_size_t length;

    std::ofstream outfile;
    outfile.open("/var/log/apache2/test.txt", std::ios_base::app);

    outfile << r->method << r->unparsed_uri << std::endl;
    apr_table_do(loop_table, &outfile, r->headers_in, NULL);
    //!!! READ REQUST BODY HERE !!!!

    outfile << r->status << std::endl;
    apr_table_do(loop_table, &outfile, r->headers_out, NULL);
    outfile << std::endl;

    while (e != APR_BRIGADE_SENTINEL(bb)) {
        apr_bucket_read(e, &data, &length, APR_BLOCK_READ);
        e = APR_BUCKET_NEXT(e);
        outfile << data;
    }

    outfile.flush();
    outfile.close();

    return ap_pass_brigade(f->next, bb);
}

Any help appriciated

You can read the body from the request_rec pointer you're deriving from the ap_filter_t pointer variable.

  1. As a first step, you should tell apache you want to read data from the client, by calling ap_setup_client_block , passing the request_rec pointer and a "read policy" as argument.
  2. Second, you call ap_should_client_block (passing the request_rec pointer as argument) to check everything is OK, especially on the client side (expecting true as result).
  3. Then you call (as many times as needed) ap_get_client_block , with the request_rec as argument, a buffer where the data will go, and the size of your buffer. You should get as a response the number of bytes read, and the data should be in your buffer. If you tried to read X bytes maximum and got X bytes returned, you should call again to get the remaining bytes. Note that the header "Content-length" should be use to avoid trying to read too many data, which might cause crashes...

So you'd go for something along the lines of:

char buffer[SOME_BUFER_SIZE];
int ret_code = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
if (ret_code == OK) {
    if (ap_should_client_block(r)) {
        int dataBytesRead = ap_get_client_block(r, buffer, SOME_BUFFER_SIZE);
        ...
    }
}

As of writing, you can find more info here: https://docstore.mik.ua/orelly/apache_mod/139.htm or here: http://byteandbits.blogspot.com/2013/09/example-apache-module-for-reading.html

Hope it helps...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM