Uploaded image for project: 'Community Development'
  1. Community Development
  2. COMDEV-371

Apache httpd Module: How to retain original POST "response body" when using SetHandler?

VotersWatch issueWatchersLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Important

    Description

      QUESTION: How can I trigger my C code and set variable in response header BUT still retain original Response body which server is generating for client.

      Requirement: Write custom Apache module to read POST request body >> Take out data from request body >> Set particular response header attribute using request body >> Send response back to client

      Details: I am using Apache as proxy for my ElasticSearch. I have successfully developed Apache Module in C and added it to httpd.conf. I have used "SetHandler" directive to trigger my custom C code.

      It is all working fine. Request generated from client browser is going through my custom C Apache Module and in my C code, I am able to read POST request body from request_rec. I am also able to set response header with that value I am readying from request body.

      Issue: If I invoke my module/code using SetHandler, when it comes out it does not have any response body and blank response body is sent to client browser. Where as when I disable my module/code, response is well generated a sent to client. So looks like by using SetHandler, response is lost.

       

      My config/code are below:

      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;

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            hartz_2004 Harshil Fadia
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment