blob: 400597e10b828b5d5d8258543fd0cc27ef7618ca [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <cstdlib>
#include <sstream>
#include <transport/THttpClient.h>
#include <transport/TSocket.h>
namespace apache { namespace thrift { namespace transport {
using namespace std;
THttpClient::THttpClient(boost::shared_ptr<TTransport> transport, std::string host, std::string path) :
THttpTransport(transport), host_(host), path_(path) {
}
THttpClient::THttpClient(string host, int port, string path) :
THttpTransport(boost::shared_ptr<TTransport>(new TSocket(host, port))), host_(host), path_(path) {
}
THttpClient::~THttpClient() {}
void THttpClient::parseHeader(char* header) {
char* colon = strchr(header, ':');
if (colon == NULL) {
return;
}
uint32_t sz = colon - header;
char* value = colon+1;
if (strncmp(header, "Transfer-Encoding", sz) == 0) {
if (strstr(value, "chunked") != NULL) {
chunked_ = true;
}
} else if (strncmp(header, "Content-Length", sz) == 0) {
chunked_ = false;
contentLength_ = atoi(value);
}
}
bool THttpClient::parseStatusLine(char* status) {
char* http = status;
char* code = strchr(http, ' ');
if (code == NULL) {
throw TTransportException(string("Bad Status: ") + status);
}
*code = '\0';
while (*(code++) == ' ');
char* msg = strchr(code, ' ');
if (msg == NULL) {
throw TTransportException(string("Bad Status: ") + status);
}
*msg = '\0';
if (strcmp(code, "200") == 0) {
// HTTP 200 = OK, we got the response
return true;
} else if (strcmp(code, "100") == 0) {
// HTTP 100 = continue, just keep reading
return false;
} else {
throw TTransportException(string("Bad Status: ") + status);
}
}
void THttpClient::flush() {
// Fetch the contents of the write buffer
uint8_t* buf;
uint32_t len;
writeBuffer_.getBuffer(&buf, &len);
// Construct the HTTP header
std::ostringstream h;
h <<
"POST " << path_ << " HTTP/1.1" << CRLF <<
"Host: " << host_ << CRLF <<
"Content-Type: application/x-thrift" << CRLF <<
"Content-Length: " << len << CRLF <<
"Accept: application/x-thrift" << CRLF <<
"User-Agent: Thrift/" << VERSION << " (C++/THttpClient)" << CRLF <<
CRLF;
string header = h.str();
// Write the header, then the data, then flush
transport_->write((const uint8_t*)header.c_str(), header.size());
transport_->write(buf, len);
transport_->flush();
// Reset the buffer and header variables
writeBuffer_.resetBuffer();
readHeaders_ = true;
}
}}} // apache::thrift::transport