Skip to content

http header parse invalid when request multiple url request in one session #72

Open

Description

@topelinux

to produce
start the ./functional-test-server
then

curl -X GET --header "content-type: application/json"  -v   http://127.0.0.1:8080/echo --next --header "content-type: application/json"  -v   http://127.0.0.1:8080/headers

the expected behavior is the receive on client side

Host: 127.0.0.1:8080
User-Agent: curl/8.1.2
Accept: */*
content-type: application/json

the acutul behavior is no response on server side, for the server the url is not valid parsed, added the screenshot for information

Screen Shot 2024-02-14 at 5 36 29 PM

Activity

  1. DarkCat5501 commented on Oct 26, 2024

    @DarkCat5501

    I'm facing almost the same problem,but noticed that it doest event need to call any methods, here's a quick example:

    image

    when making requests with insomnia:

    image

    i noticed that it is happenig whenever the target length increases it causes the next request to not reset the size and leak data from the rest of the header.

    Also, sometimes the oposite happens, and the target doesn't update, showing the last request's target

  2. jan-ekholm commented on Mar 31, 2025

    @jan-ekholm

    I see the same. The first URL is parsed ok, the second is not.

  3. zet23t commented on May 25, 2025

    @zet23t

    I modified the hs_request_begin_read function with this code to reset the buffer and parser state:

    void hs_request_begin_read(http_request_t *request) {
      // Reset buffer and tokens for the new request
      request->buffer.length = 0;
      request->buffer.index = 0;
      request->tokens.size = 0;
      hsh_parser_init(&request->parser);

    At least this seems to fix this issue.

  4. AI-Vectoring commented on Oct 30, 2026

    @AI-Vectoring

    Confirming this on a different application, with the fix from @zet23t verified.

    I hit this in a small C server embedding httpserver.h 0.9.0. Sequential reuse of a keep-alive connection (request sent, response fully read, then the next request) parsed the second request with the first request's tokens. A POST came back as method=[POS] path=[ /logi].

    Cause as I traced it: _hs_token_array_init is called once per connection, from _hs_request_init. _hs_token_array_push only appends and bumps size. Nothing resets tokens.size when a reused connection begins its next request, so the new tokens land after the previous request's, and the accessors that scan from index zero (http_request_header, http_request_method, http_request_target) return the stale entries first.

    The fix in @zet23t's comment works. I added only:

    void hs_request_begin_read(http_request_t *request) {
      request->tokens.size = 0;
      request->state = HTTP_SESSION_READ;
      ...
    }

    I did not need the buffer resets in that comment, since _hs_buffer_free already frees the buffer and _hs_buffer_init zeroes the rest on the next request.

    Verified after the change, with my previous Connection: close workaround removed: four ordered requests on a single socket (/login, a static file, /register, a session-protected route) each returned the correct body (751, 11868, 909 bytes and a 303), and curl reports Re-using existing http: connection with both requests parsed correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions