Commit cc0285da authored by Dan Fandrich's avatar Dan Fandrich
Browse files

Factored out Curl_copy_header_value

parent f3bc16f4
Loading
Loading
Loading
Loading
+66 −16
Original line number Diff line number Diff line
@@ -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;
      Curl_safefree(conn->allocptr.cookiehost);
      conn->allocptr.cookiehost = malloc(len+1);
      if(!conn->allocptr.cookiehost)
    char *cookiehost = Curl_copy_header_value(ptr);
    if (!cookiehost)
      return CURLE_OUT_OF_MEMORY;
      memcpy(conn->allocptr.cookiehost, start, len);
      conn->allocptr.cookiehost[len]=0;
    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 = cookiehost;
    }
#endif

+2 −0
Original line number Diff line number Diff line
@@ -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,
+22 −63
Original line number Diff line number Diff line
@@ -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 */
              Curl_safefree(data->info.contenttype);

              data->info.contenttype = malloc(len + 1);
              if(NULL == data->info.contenttype)
            char *contenttype = Curl_copy_header_value(k->p);
            if (!contenttype)
              return CURLE_OUT_OF_MEMORY;

              /* copy the content-type string */
              memcpy(data->info.contenttype, start, len);
              data->info.contenttype[len] = 0; /* zero terminate */
            if (!*contenttype)
              /* ignore empty data */
              free(contenttype);
            else {
              Curl_safefree(data->info.contenttype);
              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;

            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)
            /* 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;

              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;