Factored out Curl_copy_header_value
This commit is contained in:
		
							
								
								
									
										82
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -180,6 +180,60 @@ static char *checkheaders(struct SessionHandle *data, const char *thisheader) | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Strip off leading and trailing whitespace from the value in the | ||||
|  * given HTTP header line and return a strdupped copy. Returns NULL in | ||||
|  * case of allocation failure. Returns an empty string if the header value | ||||
|  * consists entirely of whitespace. | ||||
|  */ | ||||
| char *Curl_copy_header_value(const char *h) | ||||
| { | ||||
|   const char *start; | ||||
|   const char *end; | ||||
|   char *value; | ||||
|   size_t len; | ||||
|  | ||||
|   DEBUGASSERT(h); | ||||
|  | ||||
|   /* Find the end of the header name */ | ||||
|   while (*h && (*h != ':')) | ||||
|     ++h; | ||||
|  | ||||
|   if (*h) | ||||
|     /* Skip over colon */ | ||||
|     ++h; | ||||
|  | ||||
|   /* Find the first non-space letter */ | ||||
|   for(start=h; | ||||
|       *start && ISSPACE(*start); | ||||
|       start++) | ||||
|     ;  /* empty loop */ | ||||
|  | ||||
|   /* data is in the host encoding so | ||||
|      use '\r' and '\n' instead of 0x0d and 0x0a */ | ||||
|   end = strchr(start, '\r'); | ||||
|   if(!end) | ||||
|     end = strchr(start, '\n'); | ||||
|   if(!end) | ||||
|     end = strchr(start, '\0'); | ||||
|  | ||||
|   /* skip all trailing space letters */ | ||||
|   for(; ISSPACE(*end) && (end > start); end--) | ||||
|     ;  /* empty loop */ | ||||
|  | ||||
|   /* get length of the type */ | ||||
|   len = end-start+1; | ||||
|  | ||||
|   value = malloc(len + 1); | ||||
|   if(!value) | ||||
|     return NULL; | ||||
|  | ||||
|   memcpy(value, start, len); | ||||
|   value[len] = 0; /* zero terminate */ | ||||
|  | ||||
|   return value; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * http_output_basic() sets up an Authorization: header (or the proxy version) | ||||
|  * for HTTP Basic authentication. | ||||
| @@ -668,6 +722,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|       /* if exactly this is wanted, go */ | ||||
|       int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); | ||||
|       if(neg == 0) { | ||||
|         DEBUGASSERT(!data->req.newurl); | ||||
|         data->req.newurl = strdup(data->change.url); | ||||
|         data->state.authproblem = (data->req.newurl == NULL); | ||||
|       } | ||||
| @@ -2094,23 +2149,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|        custom Host: header if this is NOT a redirect, as setting Host: in the | ||||
|        redirected request is being out on thin ice. Except if the host name | ||||
|        is the same as the first one! */ | ||||
|     char *start = ptr+strlen("Host:"); | ||||
|     while(*start && ISSPACE(*start )) | ||||
|       start++; | ||||
|     ptr = start; /* start host-scanning here */ | ||||
|  | ||||
|     /* scan through the string to find the end (space or colon) */ | ||||
|     while(*ptr && !ISSPACE(*ptr) && !(':'==*ptr)) | ||||
|       ptr++; | ||||
|  | ||||
|     if(ptr != start) { | ||||
|       size_t len=ptr-start; | ||||
|     char *cookiehost = Curl_copy_header_value(ptr); | ||||
|     if (!cookiehost) | ||||
|       return CURLE_OUT_OF_MEMORY; | ||||
|     if (!*cookiehost) | ||||
|       /* ignore empty data */ | ||||
|       free(cookiehost); | ||||
|     else { | ||||
|       char *colon = strchr(cookiehost, ':'); | ||||
|       if (colon) | ||||
|         *colon = 0; /* The host must not include an embedded port number */ | ||||
|       Curl_safefree(conn->allocptr.cookiehost); | ||||
|       conn->allocptr.cookiehost = malloc(len+1); | ||||
|       if(!conn->allocptr.cookiehost) | ||||
|         return CURLE_OUT_OF_MEMORY; | ||||
|       memcpy(conn->allocptr.cookiehost, start, len); | ||||
|       conn->allocptr.cookiehost[len]=0; | ||||
|       conn->allocptr.cookiehost = cookiehost; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -35,6 +35,8 @@ bool Curl_compareheader(const char *headerline,  /* line to check */ | ||||
|                         const char *header,   /* header keyword _with_ colon */ | ||||
|                         const char *content); /* content string to find */ | ||||
|  | ||||
| char *Curl_copy_header_value(const char *h); | ||||
|  | ||||
| /* ftp can use this as well */ | ||||
| CURLcode Curl_proxyCONNECT(struct connectdata *conn, | ||||
|                            int tunnelsocket, | ||||
|   | ||||
| @@ -109,6 +109,7 @@ | ||||
|  | ||||
| #define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This function will call the read callback to fill our buffer with data | ||||
|  * to upload. | ||||
| @@ -927,42 +928,17 @@ CURLcode Curl_readwrite(struct connectdata *conn, | ||||
|                     ", closing after transfer\n", contentlength); | ||||
|             } | ||||
|           } | ||||
|           /* check for Content-Type: header lines to get the mime-type */ | ||||
|           /* check for Content-Type: header lines to get the MIME-type */ | ||||
|           else if(checkprefix("Content-Type:", k->p)) { | ||||
|             char *start; | ||||
|             char *end; | ||||
|             size_t len; | ||||
|  | ||||
|             /* Find the first non-space letter */ | ||||
|             for(start=k->p+13; | ||||
|                 *start && ISSPACE(*start); | ||||
|                 start++) | ||||
|               ;  /* empty loop */ | ||||
|  | ||||
|             /* data is now in the host encoding so | ||||
|                use '\r' and '\n' instead of 0x0d and 0x0a */ | ||||
|             end = strchr(start, '\r'); | ||||
|             if(!end) | ||||
|               end = strchr(start, '\n'); | ||||
|  | ||||
|             if(end) { | ||||
|               /* skip all trailing space letters */ | ||||
|               for(; ISSPACE(*end) && (end > start); end--) | ||||
|                 ;  /* empty loop */ | ||||
|  | ||||
|               /* get length of the type */ | ||||
|               len = end-start+1; | ||||
|  | ||||
|               /* allocate memory of a cloned copy */ | ||||
|             char *contenttype = Curl_copy_header_value(k->p); | ||||
|             if (!contenttype) | ||||
|               return CURLE_OUT_OF_MEMORY; | ||||
|             if (!*contenttype) | ||||
|               /* ignore empty data */ | ||||
|               free(contenttype); | ||||
|             else { | ||||
|               Curl_safefree(data->info.contenttype); | ||||
|  | ||||
|               data->info.contenttype = malloc(len + 1); | ||||
|               if(NULL == data->info.contenttype) | ||||
|                 return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|               /* copy the content-type string */ | ||||
|               memcpy(data->info.contenttype, start, len); | ||||
|               data->info.contenttype[len] = 0; /* zero terminate */ | ||||
|               data->info.contenttype = contenttype; | ||||
|             } | ||||
|           } | ||||
| #ifndef CURL_DISABLE_HTTP | ||||
| @@ -1123,36 +1099,19 @@ CURLcode Curl_readwrite(struct connectdata *conn, | ||||
|           } | ||||
|           else if((k->httpcode >= 300 && k->httpcode < 400) && | ||||
|                   checkprefix("Location:", k->p)) { | ||||
|             /* this is the URL that the server advices us to use instead */ | ||||
|             char *ptr; | ||||
|             char *start=k->p; | ||||
|             char backup; | ||||
|             /* this is the URL that the server advises us to use instead */ | ||||
|             char *location = Curl_copy_header_value(k->p); | ||||
|             if (!location) | ||||
|               return CURLE_OUT_OF_MEMORY; | ||||
|             if (!*location) | ||||
|               /* ignore empty data */ | ||||
|               free(location); | ||||
|             else { | ||||
|               DEBUGASSERT(!data->req.location); | ||||
|               data->req.location = location; | ||||
|  | ||||
|             start += 9; /* pass "Location:" */ | ||||
|  | ||||
|             /* Skip spaces and tabs. We do this to support multiple | ||||
|                white spaces after the "Location:" keyword. */ | ||||
|             while(*start && ISSPACE(*start )) | ||||
|               start++; | ||||
|  | ||||
|             /* Scan through the string from the end to find the last | ||||
|                non-space. k->end_ptr points to the actual terminating zero | ||||
|                letter, move pointer one letter back and start from | ||||
|                there. This logic strips off trailing whitespace, but keeps | ||||
|                any embedded whitespace. */ | ||||
|             ptr = k->end_ptr-1; | ||||
|             while((ptr>=start) && ISSPACE(*ptr)) | ||||
|               ptr--; | ||||
|             ptr++; | ||||
|  | ||||
|             backup = *ptr; /* store the ending letter */ | ||||
|             if(ptr != start) { | ||||
|               *ptr = '\0';   /* zero terminate */ | ||||
|               data->req.location = strdup(start); /* clone string */ | ||||
|               *ptr = backup; /* restore ending letter */ | ||||
|               if(!data->req.location) | ||||
|                 return CURLE_OUT_OF_MEMORY; | ||||
|               if(data->set.http_follow_location) { | ||||
|                 DEBUGASSERT(!data->req.newurl); | ||||
|                 data->req.newurl = strdup(data->req.location); /* clone */ | ||||
|                 if(!data->req.newurl) | ||||
|                   return CURLE_OUT_OF_MEMORY; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Dan Fandrich
					Dan Fandrich