Skip to content

HTTP: allow "header;" to replace an internal header with a blank one#2362

Closed
bagder wants to merge 4 commits intomasterfrom
bagder/replace-internal-header-with-blank
Closed

HTTP: allow "header;" to replace an internal header with a blank one#2362
bagder wants to merge 4 commits intomasterfrom
bagder/replace-internal-header-with-blank

Conversation

@bagder
Copy link
Member

@bagder bagder commented Mar 5, 2018

Reported-by: Michael Kaufmann
Fixes #2357

@bagder bagder added the HTTP label Mar 5, 2018
mkauf
mkauf previously requested changes Mar 6, 2018
char *cptr = Curl_checkheaders(conn, "Connection:");
char *cptr = Curl_checkheaders(conn, "Connection");
#define TE_HEADER "TE: gzip\r\n"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before creating an updated "Connection" header, a check is necessary that the header is not empty, e.g.

char *cptr = Curl_checkheaders(conn, "Connection");
if(cptr && cptr[10] != ':')
  cptr = NULL;

if(cptr) {
  while(*cptr && ISSPACE(*cptr))
    cptr++;

  if (!*cptr)
    cptr = NULL;
}

Copy link
Member Author

@bagder bagder Mar 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow.

For transfer-encoding it must send a Connection: header which is what this ensures. It will override the user's (conflicting) decision to remove or blank it, if there is one. This is actually a bug already in the current code, as passing -H Connection: and --tr-encoding will send the somewhat odd-looking header Connection:, TE.

Are you suggesting the order to remove or blank the Connection: header should be stronger than the request to ask for transfer-encoding? I'm proposing the other way around since a user can't get transfer-encoding without the header, and if a user really doesn't want the Connection: header it makes no sense to ask for transfer-encoding!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting the order to remove or blank the Connection: header should be stronger than the request to ask for transfer-encoding?

Yes, that was my intention. But now I think you're right, we should not change the existing behavior. So a "TE" should be added to "Connection", even if the user specified "Connection;" in the header list.

The existing code needs to be tweaked a bit to avoid adding a "Connection; TE" (with semicolon instead of colon).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I'll add a test case doing exactly that to make sure it gets right...

@bagder bagder dismissed mkauf’s stale review March 10, 2018 13:11

addressed!

@bagder
Copy link
Member Author

bagder commented Mar 10, 2018

@mkauf, can you think of or detect any other problems?

@mkauf
Copy link
Contributor

mkauf commented Mar 10, 2018

@bagder : In the function Curl_add_custom_headers(), anything after the ; is ignored, because this can be used for some feature in the future:

        ptr = strchr(headers->data, ';');
        if(ptr) {

          ptr++; /* pass the semicolon */
          while(*ptr && ISSPACE(*ptr))
            ptr++;

          if(*ptr) {
            /* this may be used for something else in the future */
          }
...

When adding the "TE" to "Connection", anything after "Connection;" is not ignored, I think "Connection; some-future-feature" would be changed to "Connection; some-future-feature, TE"

I think it would be a good idea to use Curl_copy_header_value() to get the "Connection" header's value. This function already returns the empty string for "Connection; some-future-feature".

lib/http.c Outdated

Curl_safefree(conn->allocptr.te);

cptr = Curl_copy_header_value(cptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cptr is NULL if there's no custom "Connection" header in the list.

Fix:

if(cptr) {
  cptr = Curl_copy_header_value(cptr);
  if(!cptr)
    return CURLE_OUT_OF_MEMORY;
}

lib/http.c Outdated
/* Create the (updated) Connection: header */
conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
conn->allocptr.te = (cptr && *cptr) ?
aprintf("%s, TE\r\n" TE_HEADER, cptr) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now cptr contains only the header value.

"%s, TE\r\n" must be changed to "Connection: %s, TE\r\n"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack, and it even broke some test cases because of this...

@bagder bagder closed this in 8123560 Mar 11, 2018
@bagder
Copy link
Member Author

bagder commented Mar 11, 2018

Thanks!

@bagder bagder deleted the bagder/replace-internal-header-with-blank branch March 11, 2018 10:46
@lock lock bot locked as resolved and limited conversation to collaborators Jun 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Development

Successfully merging this pull request may close these issues.

2 participants