summaryrefslogtreecommitdiffstats
path: root/fbench/src/httpclient/httpclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fbench/src/httpclient/httpclient.cpp')
-rw-r--r--fbench/src/httpclient/httpclient.cpp142
1 files changed, 140 insertions, 2 deletions
diff --git a/fbench/src/httpclient/httpclient.cpp b/fbench/src/httpclient/httpclient.cpp
index ce2157335e4..1a9564c5dd4 100644
--- a/fbench/src/httpclient/httpclient.cpp
+++ b/fbench/src/httpclient/httpclient.cpp
@@ -187,6 +187,103 @@ HTTPClient::Connect(const char *url)
return false;
}
+bool
+HTTPClient::ConnectForPost(const char *url, const char *content, int cLen)
+{
+ char tmp[4096];
+ char *req = NULL;
+ uint32_t req_max = 0;
+ uint32_t url_len = strlen(url);
+ uint32_t host_len = _hostname.size();
+
+ // Add additional headers
+ std::string headers = _extraHeaders;
+
+ // this is always requested to get robust info on total hit count.
+ headers += "X-Yahoo-Vespa-Benchmarkdata: true\r\n";
+
+ if ( _headerBenchmarkdataCoverage ) {
+ headers += "X-Yahoo-Vespa-Benchmarkdata-Coverage: true\r\n";
+ }
+
+ if (url_len + host_len + headers.length() + FIXED_REQ_MAX < sizeof(tmp)) {
+ req = tmp;
+ req_max = sizeof(tmp);
+ } else {
+ req_max = url_len + host_len + headers.length() + FIXED_REQ_MAX;
+ req = new char[req_max];
+ assert(req != NULL);
+ }
+
+ // create request
+ if(_keepAlive) {
+ snprintf(req, req_max,
+ "POST %s HTTP/1.1\r\n"
+ "Host: %s\r\n"
+ "Content-Length: %d\r\n"
+ "User-Agent: fbench/4.2.10\r\n"
+ "%s"
+ "\r\n",
+ url, _authority.c_str(), cLen, headers.c_str());
+ } else {
+ snprintf(req, req_max,
+ "POST %s HTTP/1.1\r\n"
+ "Host: %s\r\n"
+ "Connection: close\r\n"
+ "Content-Length: %d\r\n"
+ "User-Agent: fbench/4.2.10\r\n"
+ "%s"
+ "\r\n",
+ url, _authority.c_str(), cLen, headers.c_str());
+ }
+
+ // try to reuse connection if keep-alive is enabled
+ if (_keepAlive
+ && _socket->IsOpened()
+ && _socket->Write(req, strlen(req)) == (ssize_t)strlen(req)
+ && _socket->Write(content, cLen) == (ssize_t)cLen
+ && FillBuffer() > 0) {
+
+ // DEBUG
+ // printf("Socket Connection reused!\n");
+ _reuseCount++;
+ if (req != tmp) {
+ delete [] req;
+ }
+ return true;
+ } else {
+ _socket->Close();
+ ResetBuffer();
+ }
+
+ // try to open new connection to server
+ if (_socket->SetSoBlocking(true)
+ && _socket->Connect()
+ && _socket->SetNoDelay(true)
+ && _socket->SetSoLinger(false, 0)
+ && _socket->Write(req, strlen(req)) == (ssize_t)strlen(req)
+ && _socket->Write(content, cLen) == (ssize_t)cLen)
+ {
+
+ // DEBUG
+ // printf("New Socket connection!\n");
+ if (req != tmp) {
+ delete [] req;
+ }
+ return true;
+ } else {
+ _socket->Close();
+ }
+
+ // DEBUG
+ // printf("Connect FAILED!\n");
+ if (req != tmp) {
+ delete [] req;
+ }
+ return false;
+}
+
+
char *
HTTPClient::SplitString(char *input, int &argc, char **argv, int maxargs)
{
@@ -338,7 +435,7 @@ HTTPClient::ReadChunkHeader()
}
bool
-HTTPClient::Open(const char *url)
+HTTPClient::Open(const char *url, bool usePost, const char *content, int cLen)
{
if (_isOpen)
Close();
@@ -346,7 +443,7 @@ HTTPClient::Open(const char *url)
ResetBuffer();
_dataRead = 0;
_dataDone = false;
- _isOpen = Connect(url);
+ _isOpen = usePost ? ConnectForPost(url, content, cLen) : Connect(url);
if(!_isOpen || !ReadHTTPHeader()) {
Close();
return false;
@@ -547,3 +644,44 @@ HTTPClient::Fetch(const char *url, std::ostream *file)
_totalHitCount,
written);
}
+
+HTTPClient::FetchStatus
+HTTPClient::Post(const char *url, const char *content, int contentLen, std::ostream *file)
+{
+ size_t buflen = FETCH_BUFLEN;
+ char buf[FETCH_BUFLEN]; // NB: ensure big enough thread stack.
+ ssize_t readRes = 0;
+ ssize_t written = 0;
+
+ if (!Open(url, true, content, contentLen)) {
+ return FetchStatus(false, _requestStatus, _totalHitCount, 0);
+ }
+
+ // Write headerinfo
+ if (file) {
+ file->write(_headerinfo.c_str(), _headerinfo.length());
+ if (file->fail()) {
+ Close();
+ return FetchStatus(false, _requestStatus, _totalHitCount, 0);
+ }
+ file->write("\r\n", 2);
+ // Reset header data.
+ _headerinfo = "";
+ }
+
+ while((readRes = Read(buf, buflen)) > 0) {
+ if(file != NULL) {
+ if (!file->write(buf, readRes)) {
+ Close();
+ return FetchStatus(false, _requestStatus, _totalHitCount, written);
+ }
+ }
+ written += readRes;
+ }
+ Close();
+
+ return FetchStatus(_requestStatus == 200 && readRes == 0 && _totalHitCount >= 0,
+ _requestStatus,
+ _totalHitCount,
+ written);
+}