Search code examples
cfastcgimonkey

Access body of PUT or POST request using FastCGI in C


I'm facing some issues trying to get my body content in my monkey server. In fact, I don't really know how to access my data using fastcgi library functions.

I'm sending with Postman a PUT request on http://my.server.address:myport/cgi/something with the following JSON content:

{ "hello" : "bonjour" }

On the server side
running on the main thread :

int32_t SWEB_traiter_requette_f(int32_t i32_socket_listen) {
    FCGX_Request st_request;

    (void)FCGX_InitRequest(&st_request, i32_socket_listen, 0);

    if (FCGX_Accept_r(&st_request) == 0) {

        ULOG_log_f(ULOG_PRIO_INFO, "accepting request");
        (void)pthread_mutex_lock(gpu_mutex_s_web);
        traiter_requette_s_web_f(&st_request,FCGX_GetParam("REQUEST_URI", st_request.envp));
        (void)pthread_mutex_unlock(gpu_mutex_s_web);


        (void)FCGX_Finish_r(&st_request);
    }
    FCGX_Free(&st_request,i32_socket_listen);

    return 0;
}

And this is how I handle the request :

static void traiter_requette_s_web_f(FCGX_Request *pst_request,const char * pc_url) {
    size_t z_len;
    char_t *pc_data;
    int i = 0;
    int ch;
    char_t *sz_content_len = FCGX_GetParam("CONTENT_LENGTH" , pst_request->envp);
    char_t *sz_method      = FCGX_GetParam("REQUEST_METHOD" , pst_request->envp);
    char_t *sz_contenttype = FCGX_GetParam("CONTENT_TYPE"   , pst_request->envp);

    if (sz_contenttype != NULL){

        /* first method ..... not working */
        ch = FCGX_GetChar(pst_request->in);
        while(ch != -1){
            i++;
            z_len = strtol(sz_content_len, NULL, 10);
            pc_data = calloc(1,z_len+1);
            if (pc_data == NULL){
                //LCOV_EXCL_START
                ULOG_log_f(ULOG_PRIO_ERREUR, "Erreur d'allocation de psz_data");
                return;
                //LCOV_EXCL_STOP
            }
            pc_data[i-1] = (char_t) ch;
            ch = FCGX_GetChar(pst_request->in);
            if (ch == -1 )
            {
                pc_data=(char*)realloc(pc_data,(i + 1)*sizeof(char));
                pc_data[i] = '\0';
            }

        }
        printf("data !! : %s\n",pc_data);
        /* second method .... not working */

        z_len = strtol(sz_content_len, NULL, 10);
        pc_data = calloc(1,z_len+1);
        if (pc_data == NULL){
            //LCOV_EXCL_START
            ULOG_log_f(ULOG_PRIO_ERREUR, "Erreur d'allocation de psz_data");
            return;
            //LCOV_EXCL_STOP
        }
        (void)FCGX_GetStr(pc_data,z_len,pst_request->in);
        printf("data !! : %s\n",pc_data);   

    }
}

Maybe I'm doing something wrong with pc_data and this is not how to access the body.

How can I access the body of my request?


Solution

  • I would like to add a more modern C++ version

    std::string f_request_content;
    size_t f_request_length = <from the env variable called CONTENT_LENGTH>;
    if (f_request_method == "POST")
    {
      int ch = FCGX_GetChar (m_request.in);
      while (ch != -1)
      {
        f_request_content.push_back ((char16_t) ch);
        if (f_request_content.length() >= f_request_length)
          break;
        ch = FCGX_GetChar (m_request.in);
      }
    }