babelouest / ulfius

Web Framework to build REST APIs, Webservices or any HTTP endpoint in C language. Can stream large amount of data, integrate JSON data with Jansson, and create websocket services
https://babelouest.github.io/ulfius
GNU Lesser General Public License v2.1
1.08k stars 182 forks source link

Segmentation fault in ulfius_send_http_request() #216

Closed moeschlerm closed 2 years ago

moeschlerm commented 2 years ago

Describe the issue

I encounter a Segmentation fault in ulfius_send_http_request(), when I call the function further down in my code (it works well when I call it at the beginning of my code).

Any ideas on why this happens and how to solve it? Thanks!

Screenshot corefile Info

error

System

babelouest commented 2 years ago

Hello @moeschlerm ,

It's very difficult to guess where the problem is using only the screenshot of your stack. Can you provide a minimal sample code to reproduce the problem?

moeschlerm commented 2 years ago

This is the function that I call and in which ulfius_send_http_request()fails:

    struct _u_request request;
    struct _u_response response;
    char body[100];

    ulfius_init_request(&request);
    snprintf(body, sizeof(body), "{ Some string with params: %s}", param); 

    ulfius_set_request_properties(&request,
                            U_OPT_HTTP_VERB, "POST",
                            U_OPT_HTTP_URL, url,
                            U_OPT_HTTP_URL_APPEND, "/api/endpoint",
                            U_OPT_HEADER_PARAMETER, "Content-Type", "application/json",
                            U_OPT_TIMEOUT, 20,
                            U_OPT_HEADER_PARAMETER, "Authorization", token,
                            U_OPT_STRING_BODY, body,
                            U_OPT_NONE); // Required to close the parameters list

    ulfius_init_response(&response);
    ulfius_set_response_properties(&response,
                            U_OPT_HEADER_PARAMETER, "Content-Type", "application/json");

    int res = ulfius_send_http_request(&request, &response);

    if (res != U_OK)
        printf("Error in http request: %d\n", res);

    ulfius_clean_response(&response);
    ulfius_clean_request(&request);

I am not using any other functionalities from ulfius.

babelouest commented 2 years ago

Can you retry with the last version: https://github.com/babelouest/ulfius/releases/download/v2.7.7/ulfius-dev-full_2.7.7_ubuntu_focal_x86_64.tar.gz for your system?

Or even better, try to build ulfius from the sources: https://github.com/babelouest/ulfius/blob/master/INSTALL.md#cmake---multi-architecture

I'm trying to narrow the problem

Also, in your sample code, the ulfius_set_response_properties is not necessary. I guess you need to use U_OPT_HEADER_PARAMETER, "Accept", "application/json" instead.

If I run your code like this:

#include <stdio.h>
#include <ulfius.h>

int main(void) {
  struct _u_request request;
  struct _u_response response;
  char body[100];

  ulfius_init_request(&request);
  snprintf(body, sizeof(body), "{ Some string with params: %s}", "test"); 

  ulfius_set_request_properties(&request,
                          U_OPT_HTTP_VERB, "POST",
                          U_OPT_HTTP_URL, "http://localhost/",
                          U_OPT_HTTP_URL_APPEND, "/api/endpoint",
                          U_OPT_HEADER_PARAMETER, "Content-Type", "application/json",
                          U_OPT_HEADER_PARAMETER, "Accept", "application/json",
                          U_OPT_TIMEOUT, 20,
                          U_OPT_HEADER_PARAMETER, "Authorization", "token",
                          U_OPT_STRING_BODY, body,
                          U_OPT_NONE); // Required to close the parameters list

  ulfius_init_response(&response);

  int res = ulfius_send_http_request(&request, &response);

  if (res != U_OK)
      printf("Error in http request: %d\n", res);

  ulfius_clean_response(&response);
  ulfius_clean_request(&request);
}

Compile, then run using valgrind, I see no problems:

~/workspace$ gcc -o moeschlerm moeschlerm.c -lulfius
~/workspace$ valgrind ./moeschlerm 
==184744== Memcheck, a memory error detector
==184744== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==184744== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==184744== Command: ./moeschlerm
==184744== 
==184744== 
==184744== HEAP SUMMARY:
==184744==     in use at exit: 93,178 bytes in 706 blocks
==184744==   total heap usage: 1,567 allocs, 861 frees, 175,529 bytes allocated
==184744== 
==184744== LEAK SUMMARY:
==184744==    definitely lost: 0 bytes in 0 blocks
==184744==    indirectly lost: 0 bytes in 0 blocks
==184744==      possibly lost: 0 bytes in 0 blocks
==184744==    still reachable: 93,178 bytes in 706 blocks
==184744==         suppressed: 0 bytes in 0 blocks
==184744== Rerun with --leak-check=full to see details of leaked memory
==184744== 
==184744== For lists of detected and suppressed errors, rerun with: -s
==184744== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
moeschlerm commented 2 years ago

I re-tried running my code today, and it worked. I still don't know what was causing the Seg fault, or what I modified in order for it to work today.

Thank you anyway for your quick response, and for your remark on ulfius_set_response_properties :)

babelouest commented 2 years ago

I still don't know what was causing the Seg fault, or what I modified in order for it to work today.

It may be bad luck, or even a butterfly. The good news is that now it works!

I'm closing the issue then, happy hacking!