Branch: Tag:

2017-04-12

2017-04-12 07:05:20 by Pontus Östlund <ponost@roxen.com>

HTTPClient: Added content-length header (if missing) if method is POST.

The underlying Pike API doesn't seem to add the content-length automatically if it's not explicitly set. Some services requires it to be set to accept the (POST) request.

343:    public bool `ok() { return true; }       //! The response body, i.e the content of the requested URL -  public string `data() { return result->data; } +  public string `data() +  { +  string data = result->data;    -  +  if (content_encoding && content_encoding == "gzip") { +  data = Gz.uncompress(data[10..<8], true); +  } +  +  return data; +  } +     //! Returns the value of the @tt{content-length@} header.    public int `length()    {
360:    }    }    -  //! Returns the content encoding of the requested document, if given by the +  //! Returns the charset of the requested document, if given by the    //! response headers. -  public string `content_encoding() +  public string `charset()    {    if (string ce = (headers && headers["content-type"])) {    if (sscanf (ce, "%*s;%*scharset=%s", ce) == 3) {
373:    }    }    } +  +  //! Returns the content encoding of the response if set by the remote server. +  public string `content_encoding() +  { +  if (string ce = (headers && headers["content-encoding"])) { +  return ce;    } -  +  } + }         //! A class representing a failed request. An instance of
437:    TRACE("Host header set?: %O\n", extra_headers);    }    +  if (upper_case(method) == "POST") { +  TRACE("Got post request: %O, %O, %O, %O\n", +  url, query_variables, data, extra_headers); +  // In Pike < 8.1 the content-length header isn't auotmatically added so +  // we have to take care of that explicitly +  bool has_content_len = false; +  bool has_content_type = false; +  +  if (extra_headers) { +  array(string) lc_headers = map(indices(extra_headers), lower_case); +  +  if (has_value(lc_headers, "content-length")) { +  has_content_len = true; +  } +  +  if (has_value(lc_headers, "content-type")) { +  has_content_type = true; +  } +  } +  +  if (!has_content_len) { +  mapping(string:string) qvars = url->get_query_variables(); +  data = data||""; +  +  if (qvars && sizeof(qvars)) { +  if (!query_variables) { +  query_variables = qvars; +  } +  else { +  query_variables |= qvars; +  } +  } +  +  if (sizeof(data) && query_variables) { +  data += "&" + Protocols.HTTP.http_encode_query(query_variables); +  } +  else if (query_variables) { +  data = Protocols.HTTP.http_encode_query(query_variables); +  } +  +  if (!extra_headers) { +  extra_headers = ([]); +  } +  +  extra_headers["Content-Length"] = (string) sizeof(data); +  +  if (!has_content_type) { +  extra_headers["Content-Type"] = "application/x-www-form-urlencoded"; +  } +  +  query_variables = 0; +  } +  } +     TRACE("Request: %O\n", url);       return ::async_do_method_url(method, url, query_variables, data,