mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
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!
This commit is contained in:
parent
ceb5648eb7
commit
eef6c83503
83
lib/http.c
83
lib/http.c
@ -223,21 +223,75 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
|
|||||||
/* end of the add_buffer functions */
|
/* end of the add_buffer functions */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* This function checks the linked list of custom HTTP headers for a particular
|
||||||
* header (prefix).
|
* header (prefix).
|
||||||
*/
|
*/
|
||||||
static bool checkheaders(struct SessionHandle *data, const char *thisheader)
|
static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||||
{
|
{
|
||||||
struct curl_slist *head;
|
struct curl_slist *head;
|
||||||
size_t thislen = strlen(thisheader);
|
size_t thislen = strlen(thisheader);
|
||||||
|
|
||||||
for(head = data->set.headers; head; head=head->next) {
|
for(head = data->set.headers; head; head=head->next) {
|
||||||
if(strnequal(head->data, thisheader, thislen)) {
|
if(strnequal(head->data, thisheader, thislen))
|
||||||
return TRUE;
|
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 */
|
host due to a location-follow, we do some weirdo checks here */
|
||||||
if(!data->state.this_is_a_follow ||
|
if(!data->state.this_is_a_follow ||
|
||||||
!data->state.auth_host ||
|
!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",
|
sprintf(data->state.buffer, "%s:%s",
|
||||||
data->state.user, data->state.passwd);
|
data->state.user, data->state.passwd);
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
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);
|
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(conn->bits.upload_chunky) {
|
||||||
if(!checkheaders(data, "Transfer-Encoding:")) {
|
if(!checkheaders(data, "Transfer-Encoding:")) {
|
||||||
te = "Transfer-Encoding: chunked\r\n";
|
te = "Transfer-Encoding: chunked\r\n";
|
||||||
}
|
}
|
||||||
/* else
|
else {
|
||||||
our header was already added, what to do now? */
|
/* The "Transfer-Encoding:" header was already added. */
|
||||||
|
te = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->cookies) {
|
if(data->cookies) {
|
||||||
|
Loading…
Reference in New Issue
Block a user