blob: 166c0f673f2c3dca33da0636ef69ac90c39a4fa8 [file] [log] [blame]
David Reisscdde1852010-08-13 02:06:08 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include <cstdlib>
21#include <sstream>
22#include <iostream>
23
24#include <transport/THttpServer.h>
25#include <transport/TSocket.h>
26
27namespace apache { namespace thrift { namespace transport {
28
29using namespace std;
30
31THttpServer::THttpServer(boost::shared_ptr<TTransport> transport) :
32 THttpTransport(transport) {
33}
34
35THttpServer::~THttpServer() {}
36
37void THttpServer::parseHeader(char* header) {
38 char* colon = strchr(header, ':');
39 if (colon == NULL) {
40 return;
41 }
42 uint32_t sz = colon - header;
43 char* value = colon+1;
44
45 if (strncmp(header, "Transfer-Encoding", sz) == 0) {
46 if (strstr(value, "chunked") != NULL) {
47 chunked_ = true;
48 }
49 } else if (strncmp(header, "Content-Length", sz) == 0) {
50 chunked_ = false;
51 contentLength_ = atoi(value);
52 }
53}
54
55bool THttpServer::parseStatusLine(char* status) {
56 char* method = status;
57
58 char* path = strchr(method, ' ');
59 if (path == NULL) {
60 throw TTransportException(string("Bad Status: ") + status);
61 }
62
63 *path = '\0';
Roger Meier3b771a12010-11-17 22:11:26 +000064 while (*(++path) == ' ') {};
David Reisscdde1852010-08-13 02:06:08 +000065
66 char* http = strchr(path, ' ');
67 if (http == NULL) {
68 throw TTransportException(string("Bad Status: ") + status);
69 }
70 *http = '\0';
71
72 if (strcmp(method, "POST") == 0) {
73 // POST method ok, looking for content.
74 return true;
75 }
76 throw TTransportException(string("Bad Status (unsupported method): ") + status);
77}
78
79void THttpServer::flush() {
80 // Fetch the contents of the write buffer
81 uint8_t* buf;
82 uint32_t len;
83 writeBuffer_.getBuffer(&buf, &len);
84
85 // Construct the HTTP header
86 std::ostringstream h;
87 h <<
88 "HTTP/1.1 200 OK" << CRLF <<
89 "Date: " << getTimeRFC1123() << CRLF <<
90 "Server: Thrift/" << VERSION << CRLF <<
91 "Content-Type: application/x-thrift" << CRLF <<
92 "Content-Length: " << len << CRLF <<
93 "Connection: Keep-Alive" << CRLF <<
94 CRLF;
95 string header = h.str();
96
97 // Write the header, then the data, then flush
98 transport_->write((const uint8_t*)header.c_str(), header.size());
99 transport_->write(buf, len);
100 transport_->flush();
101
102 // Reset the buffer and header variables
103 writeBuffer_.resetBuffer();
104 readHeaders_ = true;
105}
106
107std::string THttpServer::getTimeRFC1123()
108{
109 static const char* Days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
110 static const char* Months[] = {"Jan","Feb","Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct","Nov","Dec"};
111 char buff[128];
112 time_t t = time(NULL);
113 tm* broken_t = gmtime(&t);
114
115 sprintf(buff,"%s, %d %s %d %d:%d:%d GMT",
116 Days[broken_t->tm_wday], broken_t->tm_mday, Months[broken_t->tm_mon],
117 broken_t->tm_year + 1900,
118 broken_t->tm_hour,broken_t->tm_min,broken_t->tm_sec);
119 return std::string(buff);
120}
121
122}}} // apache::thrift::transport