You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by harshil fadia <ha...@yahoo.com.INVALID> on 2020/05/11 17:30:26 UTC

[users@httpd] Apache HTTPD: Read POST request body and set response header

How do I implement below requirement? Please help..
Read POST request body >> Take out some data from request body >> Set particular response header attribute based on request attribute >> Send response back to client


What I have tried to do so far is wrote Apache module in C, read the Post body and set response header. I am calling my custom module using SetHandler so I am losing the original server response and response becomes null. Where as, what I want to have is the actual server response to be sent to client and additionally I append one more parameter in response header.

1. httpd.conf
LoadModule example_module    /usr/lib64/httpd/modules/mycustommodule.so
<VirtualHost HOSTNAME:80>  <Location /elasticsearch/_msearch>        SetHandler readbody-handler #calling my custom module  </Location>    #My KIBANA application is running on 5601 on same machine  ProxyPass        / http://localhost:5601/   ProxyPassReverse / http://localhost:5601/
</VirtualHost>


2. My custom C module 
module AP_MODULE_DECLARE_DATA readbody_module = { 
    STANDARD20_MODULE_STUFF,
    NULL, /*Per-directory configuration handler */
    NULL, /*Merge handler for per-directory configurations */
    NULL, /*Per-server configuration handler */
    NULL, /*Merge handler for per-server configurations */
    NULL,
    regiter_hooks /*Our hook registering function */
};

static void register_hooks(apr_pool_t *pool)
{
    ap_hook_handler(readbody_handler, NULL, NULL, -10);
}

static int readbody_handler(request_rec *r)
{
    const char *buffer;

    if (!r->handler || strcmp(r->handler, "readbody-handler")) return (DECLINED);

    if (util_read(r, &buffer) == OK) //reading the body and assigning it into buffer
    {
        char s[2] = ":";
        char s2[2] = "\"";
        char *indexname;
        indexname = strtok(buffer, s);
        indexname = strtok(NULL, s);
        indexname = strtok(indexname, s2);
        indexname = strtok(NULL, s2);
        apr_table_setn(r->headers_out, "IndexPattern", indexname); //setting up response header
    }

    return OK;
}

static int util_read(request_rec *r, const char **rbuf)
{
    int rc;
    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
    {
        return rc;
    }
    if (ap_should_client_block(r))
    {
        char argsbuffer[HUGE_STRING_LEN];
        int rsize, len_read, rpos = 0;
        long length = r->remaining;
        *rbuf = apr_pcalloc(r->pool, length + 1);
        while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
        {
            if ((rpos + len_read) > length)
            {
                rsize = length - rpos;
            }
            else
            {
                rsize = len_read;
            }
            memcpy((char*) *rbuf + rpos, argsbuffer, rsize);
            rpos += rsize;
        }
    }
}
    return rc;
Regards,Harshil Fadia

Re: [users@httpd] Apache HTTPD: Read POST request body and set response header

Posted by Eric Covener <co...@gmail.com>.
I don't think you want to replace the handler.

I suggest reading how mod_auth_form uses mod_request to do similar
stuff w/ the body before the handler sees it.

On Mon, May 11, 2020 at 1:30 PM harshil fadia
<ha...@yahoo.com.invalid> wrote:
>
> How do I implement below requirement? Please help..
>
> Read POST request body >> Take out some data from request body >> Set particular response header attribute based on request attribute >> Send response back to client
>
>
> What I have tried to do so far is wrote Apache module in C, read the Post body and set response header. I am calling my custom module using SetHandler so I am losing the original server response and response becomes null. Where as, what I want to have is the actual server response to be sent to client and additionally I append one more parameter in response header.
>
> 1. httpd.conf
>
> LoadModule example_module    /usr/lib64/httpd/modules/mycustommodule.so
>
> <VirtualHost HOSTNAME:80>
>   <Location /elasticsearch/_msearch>
>         SetHandler readbody-handler #calling my custom module
>   </Location>
>
>   #My KIBANA application is running on 5601 on same machine
>   ProxyPass        / http://localhost:5601/
>   ProxyPassReverse / http://localhost:5601/
>
> </VirtualHost>
>
>
> 2. My custom C module
>
> module AP_MODULE_DECLARE_DATA readbody_module = {
>     STANDARD20_MODULE_STUFF,
>     NULL, /*Per-directory configuration handler */
>     NULL, /*Merge handler for per-directory configurations */
>     NULL, /*Per-server configuration handler */
>     NULL, /*Merge handler for per-server configurations */
>     NULL,
>     regiter_hooks /*Our hook registering function */
> };
>
> static void register_hooks(apr_pool_t *pool)
> {
>     ap_hook_handler(readbody_handler, NULL, NULL, -10);
> }
>
> static int readbody_handler(request_rec *r)
> {
>     const char *buffer;
>
>     if (!r->handler || strcmp(r->handler, "readbody-handler")) return (DECLINED);
>
>     if (util_read(r, &buffer) == OK) //reading the body and assigning it into buffer
>     {
>         char s[2] = ":";
>         char s2[2] = "\"";
>         char *indexname;
>         indexname = strtok(buffer, s);
>         indexname = strtok(NULL, s);
>         indexname = strtok(indexname, s2);
>         indexname = strtok(NULL, s2);
>         apr_table_setn(r->headers_out, "IndexPattern", indexname); //setting up response header
>     }
>
>     return OK;
> }
>
> static int util_read(request_rec *r, const char **rbuf)
> {
>     int rc;
>     if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
>     {
>         return rc;
>     }
>     if (ap_should_client_block(r))
>     {
>         char argsbuffer[HUGE_STRING_LEN];
>         int rsize, len_read, rpos = 0;
>         long length = r->remaining;
>         *rbuf = apr_pcalloc(r->pool, length + 1);
>         while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
>         {
>             if ((rpos + len_read) > length)
>             {
>                 rsize = length - rpos;
>             }
>             else
>             {
>                 rsize = len_read;
>             }
>             memcpy((char*) *rbuf + rpos, argsbuffer, rsize);
>             rpos += rsize;
>         }
>     }
> }
>     return rc;
>
>
> Regards,
> Harshil Fadia
>


-- 
Eric Covener
covener@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Apache HTTPD: Read POST request body and set response header

Posted by harshil fadia <ha...@yahoo.com.INVALID>.
 @Eric,Let me read that what you have suggested. My problem is, the POST request coming is not a login form but it is un-parsable JSON string (application/x-ndjson). I am using some C string function to extract that part from request and setting it in the response header as part of my C code. But as is said, actual response body is lost by using SetHandler.
@Anthony,
You are right, that is just typo on my post Anthony. Actual code/config is good and compiled successfully. I am also able to set response header but my problem is that I am using SetHandler directive and that way I am getting actual response from server. Probably request is getting hijacked by SetHandler directive.

So what should be right way to trigger my C code which can set response header but also continue its routine flow to go to backend server and get actual response body, is the question.
*Thank you for responses*
RegardsHarshil

    On Monday, 11 May, 2020, 02:19:34 pm GMT-4, Antony G <ag...@yahoo.com.invalid> wrote:  
 
 
Hello Harshil Fadia,

  

Just to be sure that the below are just typing errors.

  

1) In the util_read  procedure, the statement return rc; is outside the brackets

  

And 

  

2) You have different name in the MODULE DEFINITION (regiter_hooks) and in the name of the procedure (register_hooks)

  
module AP_MODULE_DECLARE_DATA readbody_module = {     STANDARD20_MODULE_STUFF,    NULL, /*Per-directory configuration handler */    NULL, /*Merge handler for per-directory configurations */    NULL, /*Per-server configuration handler */    NULL, /*Merge handler for per-server configurations */    NULL,    regiter_hooks /*Our hook registering function */};  static void register_hooks(apr_pool_t *pool)
  

Regards

  

From: harshil fadia <ha...@yahoo.com.INVALID> 
Sent: Monday, May 11, 2020 8:30 PM
To: users@httpd.apache.org
Subject: [users@httpd] Apache HTTPD: Read POST request body and set response header

  

How do I implement below requirement? Please help..

  

Read POST request body >> Take out some data from request body >> Set particular response header attribute based on request attribute >> Send response back to client

  

  

What I have tried to do so far is wrote Apache module in C, read the Post body and set response header. I am calling my custom module using SetHandler so I am losing the original server response and response becomes null. Where as, what I want to have is the actual server response to be sent to client and additionally I append one more parameter in response header.

  

1. httpd.conf

LoadModule example_module    /usr/lib64/httpd/modules/mycustommodule.so

  

<VirtualHost HOSTNAME:80>

  <Location /elasticsearch/_msearch>

        SetHandler readbody-handler #calling my custom module

  </Location>

  

  #My KIBANA application is running on 5601 on same machine

  ProxyPass        / http://localhost:5601/ 

  ProxyPassReverse / http://localhost:5601/

  

</VirtualHost>

  

  

2. My custom C module 
module AP_MODULE_DECLARE_DATA readbody_module = {     STANDARD20_MODULE_STUFF,    NULL, /*Per-directory configuration handler */    NULL, /*Merge handler for per-directory configurations */    NULL, /*Per-server configuration handler */    NULL, /*Merge handler for per-server configurations */    NULL,    regiter_hooks /*Our hook registering function */};  static void register_hooks(apr_pool_t *pool){    ap_hook_handler(readbody_handler, NULL, NULL, -10);}  static int readbody_handler(request_rec *r){    const char *buffer;      if (!r->handler || strcmp(r->handler, "readbody-handler")) return (DECLINED);      if (util_read(r, &buffer) == OK) //reading the body and assigning it into buffer    {        char s[2] = ":";        char s2[2] = "\"";        char *indexname;        indexname = strtok(buffer, s);        indexname = strtok(NULL, s);        indexname = strtok(indexname, s2);        indexname = strtok(NULL, s2);        apr_table_setn(r->headers_out, "IndexPattern", indexname); //setting up response header    }      return OK;}  static int util_read(request_rec *r, const char **rbuf){    int rc;    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)    {        return rc;    }    if (ap_should_client_block(r))    {        char argsbuffer[HUGE_STRING_LEN];        int rsize, len_read, rpos = 0;        long length = r->remaining;        *rbuf = apr_pcalloc(r->pool, length + 1);        while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)        {            if ((rpos + len_read) > length)            {                rsize = length - rpos;            }            else            {                rsize = len_read;            }            memcpy((char*) *rbuf + rpos, argsbuffer, rsize);            rpos += rsize;        }    }}    return rc;
  

Regards,

Harshil Fadia

  
  

RE: [users@httpd] Apache HTTPD: Read POST request body and set response header

Posted by Antony G <ag...@yahoo.com.INVALID>.
Hello Harshil Fadia,

 

Just to be sure that the below are just typing errors.

 

1) In the util_read  procedure, the statement return rc; is outside the brackets

 

And 

 

2) You have different name in the MODULE DEFINITION (regiter_hooks) and in the name of the procedure (register_hooks)

 

module AP_MODULE_DECLARE_DATA readbody_module = { 
    STANDARD20_MODULE_STUFF,
    NULL, /*Per-directory configuration handler */
    NULL, /*Merge handler for per-directory configurations */
    NULL, /*Per-server configuration handler */
    NULL, /*Merge handler for per-server configurations */
    NULL,
    regiter_hooks /*Our hook registering function */
};
 
static void register_hooks(apr_pool_t *pool)

 

Regards

 

From: harshil fadia <ha...@yahoo.com.INVALID> 
Sent: Monday, May 11, 2020 8:30 PM
To: users@httpd.apache.org
Subject: [users@httpd] Apache HTTPD: Read POST request body and set response header

 

How do I implement below requirement? Please help..

 

Read POST request body >> Take out some data from request body >> Set particular response header attribute based on request attribute >> Send response back to client

 

 

What I have tried to do so far is wrote Apache module in C, read the Post body and set response header. I am calling my custom module using SetHandler so I am losing the original server response and response becomes null. Where as, what I want to have is the actual server response to be sent to client and additionally I append one more parameter in response header.

 


1. httpd.conf


LoadModule example_module    /usr/lib64/httpd/modules/mycustommodule.so

 

<VirtualHost HOSTNAME:80>

  <Location /elasticsearch/_msearch>

        SetHandler readbody-handler #calling my custom module

  </Location>

  

  #My KIBANA application is running on 5601 on same machine

  ProxyPass        / http://localhost:5601/ 

  ProxyPassReverse / http://localhost:5601/

 

</VirtualHost>

 

 


2. My custom C module 

module AP_MODULE_DECLARE_DATA readbody_module = { 
    STANDARD20_MODULE_STUFF,
    NULL, /*Per-directory configuration handler */
    NULL, /*Merge handler for per-directory configurations */
    NULL, /*Per-server configuration handler */
    NULL, /*Merge handler for per-server configurations */
    NULL,
    regiter_hooks /*Our hook registering function */
};
 
static void register_hooks(apr_pool_t *pool)
{
    ap_hook_handler(readbody_handler, NULL, NULL, -10);
}
 
static int readbody_handler(request_rec *r)
{
    const char *buffer;
 
    if (!r->handler || strcmp(r->handler, "readbody-handler")) return (DECLINED);
 
    if (util_read(r, &buffer) == OK) //reading the body and assigning it into buffer
    {
        char s[2] = ":";
        char s2[2] = "\"";
        char *indexname;
        indexname = strtok(buffer, s);
        indexname = strtok(NULL, s);
        indexname = strtok(indexname, s2);
        indexname = strtok(NULL, s2);
        apr_table_setn(r->headers_out, "IndexPattern", indexname); //setting up response header
    }
 
    return OK;
}
 
static int util_read(request_rec *r, const char **rbuf)
{
    int rc;
    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
    {
        return rc;
    }
    if (ap_should_client_block(r))
    {
        char argsbuffer[HUGE_STRING_LEN];
        int rsize, len_read, rpos = 0;
        long length = r->remaining;
        *rbuf = apr_pcalloc(r->pool, length + 1);
        while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
        {
            if ((rpos + len_read) > length)
            {
                rsize = length - rpos;
            }
            else
            {
                rsize = len_read;
            }
            memcpy((char*) *rbuf + rpos, argsbuffer, rsize);
            rpos += rsize;
        }
    }
}
    return rc;

 

Regards,

Harshil Fadia