diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2002-11-28 15:45:06 +0000 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2002-11-28 15:45:06 +0000 | 
| commit | eef6c835032cb4eb7bb6140b17263593ff0ad29e (patch) | |
| tree | 7904bffb2e12b573e2a52b3c6f29e343d0df141f /lib | |
| parent | ceb5648eb7fcb635da659b8cb90ff7c5dc14f47b (diff) | |
Moved the compareheader function into this file and added Curl_ prefix
We now check if the chunked transfer-encoding header has been added "by force"
and if so, we enabled the chunky upload!
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/http.c | 83 | 
1 files changed, 75 insertions, 8 deletions
diff --git a/lib/http.c b/lib/http.c index 92143c4a7..6b60f66db 100644 --- a/lib/http.c +++ b/lib/http.c @@ -224,20 +224,74 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)  /* ------------------------------------------------------------------------- */  /* + * Curl_compareheader() + * + * Returns TRUE if 'headerline' contains the 'header' with given 'content'. + * Pass headers WITH the colon. + */ +bool +Curl_compareheader(char *headerline,    /* line to check */ +                   const char *header,  /* header keyword _with_ colon */ +                   const char *content) /* content string to find */ +{ +  /* RFC2616, section 4.2 says: "Each header field consists of a name followed +   * by a colon (":") and the field value. Field names are case-insensitive. +   * The field value MAY be preceded by any amount of LWS, though a single SP +   * is preferred." */ + +  size_t hlen = strlen(header); +  size_t clen; +  size_t len; +  char *start; +  char *end; + +  if(!strnequal(headerline, header, hlen)) +    return FALSE; /* doesn't start with header */ + +  /* pass the header */ +  start = &headerline[hlen]; + +  /* pass all white spaces */ +  while(*start && isspace((int)*start)) +    start++; + +  /* find the end of the header line */ +  end = strchr(start, '\r'); /* lines end with CRLF */ +  if(!end) { +    /* in case there's a non-standard compliant line here */ +    end = strchr(start, '\n'); + +    if(!end) +      /* hm, there's no line ending here, use the zero byte! */ +      end = strchr(start, '\0'); +  } + +  len = end-start; /* length of the content part of the input line */ +  clen = strlen(content); /* length of the word to find */ + +  /* find the content string in the rest of the line */ +  for(;len>=clen;len--, start++) { +    if(strnequal(start, content, clen)) +      return TRUE; /* match! */ +  } + +  return FALSE; /* no match */ +} + +/*   * This function checks the linked list of custom HTTP headers for a particular   * header (prefix).   */ -static bool checkheaders(struct SessionHandle *data, const char *thisheader) +static char *checkheaders(struct SessionHandle *data, const char *thisheader)  {    struct curl_slist *head;    size_t thislen = strlen(thisheader);    for(head = data->set.headers; head; head=head->next) { -    if(strnequal(head->data, thisheader, thislen)) { -      return TRUE; -    } +    if(strnequal(head->data, thisheader, thislen)) +      return head->data;    } -  return FALSE; +  return NULL;  }  /* @@ -527,7 +581,7 @@ CURLcode Curl_http(struct connectdata *conn)         host due to a location-follow, we do some weirdo checks here */      if(!data->state.this_is_a_follow ||         !data->state.auth_host || -       strequal(data->state.auth_host, conn->hostname)) { +       curl_strequal(data->state.auth_host, conn->hostname)) {        sprintf(data->state.buffer, "%s:%s",                data->state.user, data->state.passwd);        if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), @@ -551,12 +605,25 @@ CURLcode Curl_http(struct connectdata *conn)      conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie);    } +  if(!conn->bits.upload_chunky && (data->set.httpreq != HTTPREQ_GET)) { +    /* not a chunky transfer but data is to be sent */ +    char *ptr = checkheaders(data, "Transfer-Encoding:"); +    if(ptr) { +      /* Some kind of TE is requested, check if 'chunked' is chosen */ +      if(Curl_compareheader(ptr, "Transfer-Encoding:", "chunked")) +        /* we have been told explicitly to upload chunky so deal with it! */ +        conn->bits.upload_chunky = TRUE; +    } +  } +    if(conn->bits.upload_chunky) {      if(!checkheaders(data, "Transfer-Encoding:")) {        te = "Transfer-Encoding: chunked\r\n";      } -    /* else -       our header was already added, what to do now? */ +    else { +      /* The "Transfer-Encoding:" header was already added. */ +      te = ""; +    }    }    if(data->cookies) {  | 
