15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/http_interface.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/balsa_frame.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/url_utilities.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/flip_config.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/sm_connection.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/spdy_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpSM::HttpSM(SMConnection* connection, 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SMInterface* sm_spdy_interface, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCache* memory_cache, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FlipAcceptor* acceptor) 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : http_framer_(new BalsaFrame), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id_(0), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_idx_(-1), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(connection), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_(sm_spdy_interface), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_list_(connection->output_list()), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_(connection), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_cache_(connection->memory_cache()), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acceptor_(acceptor) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_balsa_visitor(this); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_balsa_headers(&headers_); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_is_request(false); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpSM::~HttpSM() { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete http_framer_; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void HttpSM::ProcessBodyData(const char* input, size_t size) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process Body Data: stream " 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_ << ": size " << size; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendDataFrame(stream_id_, input, size, 0, false); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::ProcessHeaders(const BalsaHeaders& headers) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host = 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UrlUtilities::GetUrlHost(headers.GetHeader("Host").as_string()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string method = headers.request_method().as_string(); 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << "Received Request: " << headers.request_uri().as_string() << " " 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << method; 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string filename = 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EncodeURL(headers.request_uri().as_string(), host, method); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewStream(stream_id_, 0, filename); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id_ += 2; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Received Response from " 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << connection_->server_ip_ << ":" << connection_->server_port_ 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << " "; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendSynReply(stream_id_, headers); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::MessageDone() { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone. Sending EOF: " 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "stream " << stream_id_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendEOF(stream_id_); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone."; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::HandleHeaderError(BalsaFrame* framer) { HandleError(); } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::HandleChunkingError(BalsaFrame* framer) { HandleError(); } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::HandleBodyError(BalsaFrame* framer) { HandleError(); } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::HandleError() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected"; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::AddToOutputOrder(const MemCacheIter& mci) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.AddToOutputOrder(mci); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::InitSMInterface(SMInterface* sm_spdy_interface, int32 server_idx) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_ = sm_spdy_interface; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_idx_ = server_idx; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::InitSMConnection(SMConnectionPoolInterface* connection_pool, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SMInterface* sm_interface, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* epoll_server, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_ip, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_port, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string remote_ip, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_ssl) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server " 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "connection."; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->InitSMConnection(connection_pool, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_interface, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ip, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_port, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_ip, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_ssl); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::ProcessReadInput(const char* data, size_t len) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream " 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_framer_->ProcessInput(data, len); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::ProcessWriteInput(const char* data, size_t len) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size " 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << len << ": stream " << stream_id_; 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char* dataPtr = new char[len]; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dataPtr, data, len); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* data_frame = new DataFrame; 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) data_frame->data = dataPtr; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame->size = len; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame->delete_when_done = true; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->EnqueueDataFrame(data_frame); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpSM::MessageFullyRead() const { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_framer_->MessageFullyRead(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::SetStreamID(uint32 stream_id) { stream_id_ = stream_id; } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool HttpSM::Error() const { return http_framer_->Error(); } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* HttpSM::ErrorAsString() const { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BalsaFrameEnums::ErrorCodeToString(http_framer_->ErrorCode()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::Reset() { 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Reset: stream " << stream_id_; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->Reset(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::ResetForNewConnection() { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Server connection closing " 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << "to: " << connection_->server_ip_ << ":" 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << connection_->server_port_ << " "; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Message has not been fully read, either it is incomplete or the 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server is closing the connection to signal message end. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MessageFullyRead()) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "HTTP response closed before end of file detected. " 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Sending EOF to spdy."; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendEOF(stream_id_); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.Reset(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->Reset(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sm_spdy_interface_) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->ResetForNewInterface(server_idx_); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::Cleanup() { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "HttpSM Request Fully Read; stream_id: " << stream_id_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Cleanup("request complete"); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int HttpSM::PostAcceptHook() { return 1; } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::NewStream(uint32 stream_id, 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 priority, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& filename) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter mci; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.stream_id = stream_id; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.priority = priority; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memory_cache_->AssignFileData(filename, &mci)) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error creating new stream. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound"; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorNotFound(stream_id); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToOutputOrder(mci); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendEOF(uint32 stream_id) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOFImpl(stream_id); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->ResetForNewInterface(server_idx_); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendErrorNotFound(uint32 stream_id) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorNotFoundImpl(stream_id); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SendSynReplyImpl(stream_id, headers); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::SendDataFrame(uint32 stream_id, 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* data, 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64 len, 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 flags, 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool compress) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrameImpl(stream_id, data, len, flags, compress); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendEOFImpl(uint32 stream_id) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = "0\r\n\r\n"; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = 5; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendErrorNotFoundImpl(uint32 stream_id) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders my_headers; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.RemoveAllOfHeader("content-length"); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.AppendHeader("transfer-encoding", "chunked"); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendSynReplyImpl(stream_id, my_headers); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrame(stream_id, "page not found", 14, 0, false); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOFImpl(stream_id); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.RemoveStreamId(stream_id); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleBuffer sb; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers.WriteHeaderAndEndingToBuffer(&sb); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = sb.ReadableBytes(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sb.Read(buffer, df->size); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t df_size = df->size; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return df_size; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynStreamImpl(uint32 stream_id, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BalsaHeaders& headers) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleBuffer sb; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers.WriteHeaderAndEndingToBuffer(&sb); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = sb.ReadableBytes(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sb.Read(buffer, df->size); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t df_size = df->size; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return df_size; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HttpSM::SendDataFrameImpl(uint32 stream_id, 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* data, 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64 len, 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 flags, 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool compress) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char chunk_buf[128]; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string chunk_description(chunk_buf); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = chunk_description.size() + len + 2; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer, chunk_description.data(), chunk_description.size()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer + chunk_description.size(), data, len); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer + chunk_description.size() + len, "\r\n", 2); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::EnqueueDataFrame(DataFrame* df) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream " 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->EnqueueDataFrame(df); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::GetOutput() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter* mci = output_ordering_.GetIter(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mci == NULL) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to " 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "output!?: stream " << stream_id_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mci->transformed_header) { 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mci->bytes_sent = 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SendSynReply(mci->stream_id, *(mci->file_data->headers())); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->transformed_header = true; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput transformed " 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "header stream_id: [" << mci->stream_id << "]"; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (mci->body_bytes_consumed >= mci->file_data->body().size()) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOF(mci->stream_id); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.RemoveStreamId(mci->stream_id); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "GetOutput remove_stream_id: [" 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << mci->stream_id << "]"; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_to_write = 325ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mci->file_data->body().size() - mci->body_bytes_consumed; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_to_write > mci->max_segment_size) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_to_write = mci->max_segment_size; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrame(mci->stream_id, 330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mci->file_data->body().data() + mci->body_bytes_consumed, 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) num_to_write, 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 0, 333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) true); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput SendDataFrame[" 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << mci->stream_id << "]: " << num_to_write; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->body_bytes_consumed += num_to_write; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->bytes_sent += num_to_write; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 341