| /* |
| * 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 |