void HTTPRequest::addDefaultHTTPHeaders() {
  addHeader(HTTPHeader("Host", url.getHost()));

  if(method != HTTP_METHOD_POST) {
    return;
  }

  if(!headers.contains("content-type")) {
    if(getFormEncoding() == HTTP_FORM_MULTIPART) {
      addHeader(HTTPHeader("Content-Type", "multipart/form-data; boundary=\"" +getBoundary() +"\""));
    }
    else if(getFormEncoding() == HTTP_FORM_URL_ENCODED) {
      addHeader(HTTPHeader("Content-Type", "application/x-www-form-urlencoded"));
    }
  }
}
// create the request string
bool HTTPRequest::toString(std::string& result) {

  // create the content string
  std::string http_body;
  if(!createBody(http_body)) {
    RX_ERROR("Cannot create request body");
    return false;
  }

  // create the headers.
  addDefaultHTTPHeaders();
  addHeader(HTTPHeader("Content-Length", http_body.size()));

  // construct the request
  result = getHTTPString() +"\r\n";

  result += headers.join();
  result += "\r\n";

#if 1
  printf("%s", result.c_str());
  for(size_t i = 0; i < http_body.size(); ++i) {
    if(i > 40) {
      break;
    }
    printf("%c", http_body[i]);
  }
  printf("\n");
  for(size_t i = 0; i < http_body.size(); ++i) {
    if(i > 40) {
      break;
    }
    printf("%02X ", (unsigned char)http_body[i]);
  }
  printf("\n");
#endif

  result += http_body;

#if 0 
  std::ofstream ofs(rx_to_data_path("out.raw").c_str(), std::ios::binary | std::ios::out);
  if(!ofs.is_open()) {
    RX_ERROR("Cannot open output file");
  }
  else {
    ofs.write(result.c_str(), result.size());
    ofs.close();
  }
#endif

  return true;
}
예제 #3
0
void OAuth::addAuthorizationHeadersToRequest(HTTPRequest& r) {
  std::string signature = createSignature(r);
  HTTPParameters params = collectParameters(r);
  
  params.add(HTTPParameter("oauth_signature", signature));
  params.percentEncode();

  std::string header = "OAuth ";

  OAUTH_CONCAT_HEADER(header, "oauth_callback", true);
  OAUTH_CONCAT_HEADER(header, "oauth_consumer_key", true);
  OAUTH_CONCAT_HEADER(header, "oauth_nonce", true);
  OAUTH_CONCAT_HEADER(header, "oauth_signature", true);
  OAUTH_CONCAT_HEADER(header, "oauth_signature_method", true);
  OAUTH_CONCAT_HEADER(header, "oauth_timestamp", true);
  OAUTH_CONCAT_HEADER(header, "oauth_token", true);
  OAUTH_CONCAT_HEADER(header, "oauth_version", false);

  r.addHeader(HTTPHeader("Authorization", header));
}
예제 #4
0
void HTTPMessage::parse(
    String& startLine,
    Array<HTTPHeader>& headers,
    Uint32& contentLength) const
{
    startLine.clear();
    headers.clear();
    contentLength = 0;

    char* data = (char*)message.getData();
    Uint32 size = message.size();
    char* line = data;
    char* sep;
    Boolean firstTime = true;

    while ((sep = findSeparator(line, (Uint32)(size - (line - data)))))
    {
        // Look for double separator which terminates the header?

        if (line == sep)
        {
            // Establish pointer to content (account for "\n" and "\r\n").

            char* content = line + ((*sep == '\r') ? 2 : 1);

            // Determine length of content:

            contentLength = (Uint32)(message.size() - (content - data));
            break;
        }

        Uint32 lineLength = (Uint32)(sep - line);

        if (firstTime)
            startLine.assign(line, lineLength);
        else
        {
            // Find the colon:

            char* colon = 0;

            for (Uint32 i = 0; i < lineLength; i++)
            {
                if (line[i] == ':')
                {
                    colon = &line[i];
                    break;
                }
            }

            // This should always be true:

            if (colon)
            {
                // Get the name part:

                char* end;

                for (end = colon - 1; end > line && isspace(*end); end--)
                    ;

                end++;

                String name(line, (Uint32)(end - line));

                // Get the value part:

                char* start;

                for (start = colon + 1; start < sep && isspace(*start); start++)
                    ;

                String value(start, (Uint32)(sep - start));

                // From the HTTP/1.1 specification (RFC 2616) section 4.2
                // Message Headers:
                //
                // Multiple message-header fields with the same field-name
                // MAY be present in a message if and only if the entire
                // field-value for that header field is defined as a
                // comma-separated list [i.e., #(values)]. It MUST be
                // possible to combine the multiple header fields into one
                // "field-name: field-value" pair, without changing the
                // semantics of the message, by appending each subsequent
                // field-value to the first, each separated by a comma.  The
                // order in which header fields with the same field-name are
                // received is therefore significant to the interpretation
                // of the combined field value, and thus a proxy MUST NOT
                // change the order of these field values when a message is
                // forwarded.

                // This implementation concatenates duplicate header values,
                // with a comma separator.  If the resulting value is invalid,
                // that should be detected when the value is used.

                Uint32 headerIndex = 0;
                for (; headerIndex < headers.size(); headerIndex++)
                {
                    if (headers[headerIndex].first == name)
                    {
                        break;
                    }
                }

                if (headerIndex == headers.size())
                {
                    headers.append(HTTPHeader(name, value));
                }
                else
                {
                    headers[headerIndex].second.append(", ").append(value);
                }
            }
        }

        line = sep + ((*sep == '\r') ? 2 : 1);
        firstTime = false;
    }
}
int httpconnection_on_header_value(http_parser* p, const char* at, size_t len) {
  HTTPConnection* c = static_cast<HTTPConnection*>(p->data);
  std::string header_value(at, len);
  c->headers.add(HTTPHeader(c->last_header, header_value));
  return 0;
}