Skip to content

HTTPClient doesn't preserve request headers over multiple redirects #3173

@skaringa

Description

@skaringa

I'm using the following code to make a HTTP request:

  http.begin(url);
  http.setReuse(true);
  http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
  http.addHeader("Icy-MetaData", "1");
  int code = http.GET();
  if (code != HTTP_CODE_OK) {
      // ...

On the first request to url, the headers added with addHeader are correctly sent to the target host.
However, if one or more redirects happen during the GET method, then those headers are not sent again to the redirected URLs.

I would expect to re-send the headers over multiple redirects, because the description of the redirection modes states clearly:

HTTPC_FORCE_FOLLOW_REDIRECTS - all redirections will be followed,
regardless of a used method. New request will use the same method,
and they will include the same body data and the same headers.
In the sense of the RFC, it's just like every redirection is confirmed.

The reason for the wrong behavior is that the method HTTPClient::clear is called multiple times during handling of the request, but it clears all headers.

I fixed this locally with the following patch:

diff -p HTTPClient.cpp ~/.arduino15/packages/rp2040/hardware/rp2040/5.1.0/libraries/HTTPClient/src/HTTPClient.cpp 
*** HTTPClient.cpp	2025-10-02 17:58:12.619006816 +0200
--- ~.arduino15/packages/rp2040/hardware/rp2040/5.1.0/libraries/HTTPClient/src/HTTPClient.cpp	2025-10-02 18:07:18.688822906 +0200
*************** public:
*** 104,109 ****
--- 104,110 ----
  
  
  void HTTPClient::clear() {
+       DEBUG_HTTPCLIENT("[HTTP-Client][clear]\n");
      _returnCode = 0;
      _size = -1;
      _headers = "";
*************** int HTTPClient::sendRequest(const char *
*** 578,591 ****
      int code;
      bool redirect = false;
      uint16_t redirectCount = 0;
      do {
!         // wipe out any existing headers from previous request
          for (size_t i = 0; i < _headerKeysCount; i++) {
              if (_currentHeaders[i].value.length() > 0) {
                  _currentHeaders[i].value = "";
              }
          }
  
          DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] type: '%s' redirCount: %d\n", type, redirectCount);
  
          // connect to server
--- 579,600 ----
      int code;
      bool redirect = false;
      uint16_t redirectCount = 0;
+     String headers;
      do {
!         // wipe out any existing response headers from previous request
          for (size_t i = 0; i < _headerKeysCount; i++) {
              if (_currentHeaders[i].value.length() > 0) {
                  _currentHeaders[i].value = "";
              }
          }
  
+         // keep request headers for redirects
+         if (redirect) {
+             _headers = headers;
+         } else {
+             headers = _headers;
+         }
+ 
          DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] type: '%s' redirCount: %d\n", type, redirectCount);

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