blob: 166c0f673f2c3dca33da0636ef69ac90c39a4fa8 [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 <iostream>
#include <transport/THttpServer.h>
#include <transport/TSocket.h>
namespace apache { namespace thrift { namespace transport {
using namespace std;
THttpServer::THttpServer(boost::shared_ptr<TTransport> transport) :
THttpTransport(transport) {
}
THttpServer::~THttpServer() {}
void THttpServer::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 THttpServer::parseStatusLine(char* status) {
char* method = status;
char* path = strchr(method, ' ');
if (path == NULL) {
throw TTransportException(string("Bad Status: ") + status);
}
*path = '\0';
while (*(++path) == ' ') {};
char* http = strchr(path, ' ');
if (http == NULL) {
throw TTransportException(string("Bad Status: ") + status);
}
*http = '\0';
if (strcmp(method, "POST") == 0) {
// POST method ok, looking for content.
return true;
}
throw TTransportException(string("Bad Status (unsupported method): ") + status);
}
void THttpServer::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 <<
"HTTP/1.1 200 OK" << CRLF <<
"Date: " << getTimeRFC1123() << CRLF <<
"Server: Thrift/" << VERSION << CRLF <<
"Content-Type: application/x-thrift" << CRLF <<
"Content-Length: " << len << CRLF <<
"Connection: Keep-Alive" << 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;
}
std::string THttpServer::getTimeRFC1123()
{
static const char* Days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static const char* Months[] = {"Jan","Feb","Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct","Nov","Dec"};
char buff[128];
time_t t = time(NULL);
tm* broken_t = gmtime(&t);
sprintf(buff,"%s, %d %s %d %d:%d:%d GMT",
Days[broken_t->tm_wday], broken_t->tm_mday, Months[broken_t->tm_mon],
broken_t->tm_year + 1900,
broken_t->tm_hour,broken_t->tm_min,broken_t->tm_sec);
return std::string(buff);
}
}}} // apache::thrift::transport