Response S3RESTfulService::put(const string &url, HTTPHeaders &headers, const S3VectorUInt8 &data) { Response response(RESPONSE_ERROR); headers.CreateList(); CURLWrapper wrapper(url, headers.GetList(), this->lowSpeedLimit, this->lowSpeedTime, this->debugCurl); CURL *curl = wrapper.curl; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, RESTfulServiceWriteFuncCallback); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, this->verifyCert); UploadData uploadData(data); curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&uploadData); curl_easy_setopt(curl, CURLOPT_READFUNCTION, RESTfulServiceReadFuncCallback); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)data.size()); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, RESTfulServiceHeadersWriteFuncCallback); this->performCurl(curl, response); return response; }
TEST(HTTPHeaders, AddStringPiece) { const char foo[] = "name:value"; HTTPHeaders headers; folly::StringPiece str(foo); folly::StringPiece name = str.split_step(':'); headers.add(name, str); EXPECT_EQ("value", headers.getSingleOrEmpty("name")); }
TEST(S3RESTfulService, GetWithWrongHeader) { HTTPHeaders headers; map<string, string> params; S3RESTfulService service; string url = "https://www.bing.com/"; headers.Add(HOST, url); headers.Add(CONTENTTYPE, "plain/text"); Response resp = service.get(url, headers, params); EXPECT_EQ(RESPONSE_ERROR, resp.getStatus()); }
// head() will execute HTTP HEAD RESTful API with given url/headers/params, and return the HTTP // response code. // // Currently, this method only return the HTTP code, will be extended if needed in the future // implementation. ResponseCode S3RESTfulService::head(const string &url, HTTPHeaders &headers) { Response response(RESPONSE_ERROR); headers.CreateList(); CURLWrapper wrapper(url, headers.GetList(), this->lowSpeedLimit, this->lowSpeedTime, this->debugCurl); CURL *curl = wrapper.curl; curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD"); curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, this->verifyCert); this->performCurl(curl, response); return response.getResponseCode(); }
CurlClient::CurlClient(EventBase* evb, HTTPMethod httpMethod, const URL& url, const HTTPHeaders& headers, const string& inputFilename): evb_(evb), httpMethod_(httpMethod), url_(url), inputFilename_(inputFilename) { headers.forEach([this] (const string& header, const string& val) { request_.getHeaders().add(header, val); }); }
// get() will execute HTTP GET RESTful API with given url/headers/params, // and return raw response content. // // This method does not care about response format, caller need to handle // response format accordingly. Response S3RESTfulService::get(const string &url, HTTPHeaders &headers) { Response response(RESPONSE_ERROR, this->s3MemContext); response.getRawData().reserve(this->chunkBufferSize); headers.CreateList(); CURLWrapper wrapper(url, headers.GetList(), this->lowSpeedLimit, this->lowSpeedTime, this->debugCurl); CURL *curl = wrapper.curl; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, RESTfulServiceWriteFuncCallback); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, this->verifyCert); this->performCurl(curl, response); return response; }
void SendHeaders(unsigned long size, int response, HTTPHeaders &rheaders) { WriteData(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n"); time_t local = ServerInstance->Time(); struct tm *timeinfo = gmtime(&local); char *date = asctime(timeinfo); date[strlen(date) - 1] = '\0'; rheaders.CreateHeader("Date", date); rheaders.CreateHeader("Server", BRANCH); rheaders.SetHeader("Content-Length", ConvToStr(size)); if (size) rheaders.CreateHeader("Content-Type", "text/html"); else rheaders.RemoveHeader("Content-Type"); /* Supporting Connection: keep-alive causes a whole world of hurt syncronizing timeouts, * so remove it, its not essential for what we need. */ rheaders.SetHeader("Connection", "Close"); WriteData(rheaders.GetFormattedHeaders()); WriteData("\r\n"); }
void Connection::SendError(int code, const std::string &text, bool fatal = false) { HTTPHeaders empty; empty.SetHeader("Content-Type", "text/html"); std::string data = "<html><head></head><body>" + text + "<br><small>Powered by Hottpd</small></body></html>"; ResponseBackend = NULL; this->SendHeaders(data.length(), code, text, empty); State = HTTP_SEND_DATA; this->Write(data); ResponseBufferDone = true; // Flush the write buffer now instead of waiting an iteration, since we've written all we need to this->FlushWriteBuf(); if (fatal) { // Semi-hack. Disabling keepalive means connection is closed ASAP. keepalive = false; } }
Response S3RESTfulService::deleteRequest(const string &url, HTTPHeaders &headers) { Response response(RESPONSE_ERROR); headers.CreateList(); CURLWrapper wrapper(url, headers.GetList(), this->lowSpeedLimit, this->lowSpeedTime, this->debugCurl); CURL *curl = wrapper.curl; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, RESTfulServiceAbortFuncCallback); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, this->verifyCert); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); S3VectorUInt8 data; UploadData uploadData(data); curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&uploadData); curl_easy_setopt(curl, CURLOPT_READFUNCTION, RESTfulServiceReadFuncCallback); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)data.size()); this->performCurl(curl, response); return response; }
TEST(Common, SignRequestV4) { S3Credential cred = {"keyid/foo", "secret/bar"}; HTTPHeaders *h = new HTTPHeaders(); ASSERT_NE((void *)NULL, h); ASSERT_TRUE(h->Add(HOST, "iam.amazonaws.com")); ASSERT_TRUE(h->Add(X_AMZ_DATE, "20150830T123600Z")); ASSERT_TRUE(h->Add(X_AMZ_CONTENT_SHA256, "UNSIGNED-PAYLOAD")); SignRequestV4("GET", h, "us-east-1", "/where/ever", "?parameter1=whatever1¶meter2=whatever2", cred); EXPECT_STREQ( "AWS4-HMAC-SHA256 " "Credential=keyid/foo/20150830/us-east-1/s3/" "aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date," "Signature=" "9f500a13e81c2dc6cb47551e416b2734e401d7b7b8f7ae99b09bccc22b81132d", h->Get(AUTHORIZATION)); delete h; }
TEST(Common, SignRequestV4) { S3Credential cred = {"keyid/foo", "secret/bar", ""}; HTTPHeaders *h = new HTTPHeaders(); ASSERT_NE((void *)NULL, h); ASSERT_TRUE(h->Add(HOST, "iam.amazonaws.com")); ASSERT_TRUE(h->Add(X_AMZ_DATE, "20150830T123600Z")); ASSERT_TRUE(h->Add(X_AMZ_CONTENT_SHA256, "UNSIGNED-PAYLOAD")); SignRequestV4("GET", h, "us-east-1", "/where/ever", "parameter1=whatever1¶meter2=whatever2", cred); EXPECT_STREQ( "AWS4-HMAC-SHA256 " "Credential=keyid/foo/20150830/us-east-1/s3/" "aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date," "Signature=" "bb2410787ac51cc7c41b679378d2586a557188ce2017569f5fc94a9b9bb901f8", h->Get(AUTHORIZATION)); delete h; }
void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext) { header.clear(); header["DNT"] = "1"; header["MaxAge"] = "0"; header["Connection"] = "Keep-Alive"; header["Server"] = "mbed Embedded"; if (fext == NULL) header["Content-Type"] = "text/html"; else { for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) { if (_stricmp(fileTypeMapping[i].key, fext) == 0) { header["Content-Type"] = fileTypeMapping[i].value; break; } } } }
void SendHeaders(unsigned long size, int response, HTTPHeaders &rheaders) { WriteData(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n"); rheaders.CreateHeader("Date", InspIRCd::TimeString(ServerInstance->Time(), "%a, %d %b %Y %H:%M:%S GMT", true)); rheaders.CreateHeader("Server", INSPIRCD_BRANCH); rheaders.SetHeader("Content-Length", ConvToStr(size)); if (size) rheaders.CreateHeader("Content-Type", "text/html"); else rheaders.RemoveHeader("Content-Type"); /* Supporting Connection: keep-alive causes a whole world of hurt syncronizing timeouts, * so remove it, its not essential for what we need. */ rheaders.SetHeader("Connection", "Close"); WriteData(rheaders.GetFormattedHeaders()); WriteData("\r\n"); }
Response mockGet(const string& url, HTTPHeaders& headers) { string range = headers.Get(RANGE); size_t index = range.find("="); string rangeNumber = range.substr(index + 1); index = rangeNumber.find("-"); // stoi is not available in C++98, use sscanf as workaround. int begin, end; if (index > 0) { sscanf(rangeNumber.substr(0, index).c_str(), "%d", &begin); } else { begin = 0; } if (rangeNumber.empty()) { end = data.size(); } else { sscanf(rangeNumber.substr(index + 1).c_str(), "%d", &end); } vector<uint8_t> responseData(data.begin() + begin, data.begin() + end + 1); return Response(RESPONSE_OK, responseData); }
bool bodyImplied(const HTTPHeaders& headers) { return headers.exists(HTTP_HEADER_TRANSFER_ENCODING) || headers.exists(HTTP_HEADER_CONTENT_LENGTH); }