http_interface.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
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) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/url_utilities.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/balsa_frame.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) EpollServer* epoll_server, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCache* memory_cache, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FlipAcceptor* acceptor) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : seq_num_(0), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_(new BalsaFrame), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id_(0), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_idx_(-1), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(connection), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_(sm_spdy_interface), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_list_(connection->output_list()), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_(connection), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_cache_(connection->memory_cache()), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acceptor_(acceptor) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_balsa_visitor(this); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_balsa_headers(&headers_); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->set_is_request(false); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpSM::~HttpSM() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete http_framer_; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::ProcessBodyData(const char *input, size_t size) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process Body Data: stream " 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_ << ": size " << size; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendDataFrame(stream_id_, input, size, 0, false); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::ProcessHeaders(const BalsaHeaders& headers) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UrlUtilities::GetUrlHost(headers.GetHeader("Host").as_string()); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string method = headers.request_method().as_string(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Received Request: " 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << headers.request_uri().as_string() << " " << method; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string filename = EncodeURL(headers.request_uri().as_string(), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host, method); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewStream(stream_id_, 0, filename); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id_ += 2; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Received Response from " 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << connection_->server_ip_ << ":" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << connection_->server_port_ << " "; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendSynReply(stream_id_, headers); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::MessageDone() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone. Sending EOF: " 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "stream " << stream_id_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendEOF(stream_id_); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone."; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::HandleHeaderError(BalsaFrame* framer) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleError(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::HandleChunkingError(BalsaFrame* framer) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleError(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::HandleBodyError(BalsaFrame* framer) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleError(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::HandleError() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected"; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::AddToOutputOrder(const MemCacheIter& mci) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.AddToOutputOrder(mci); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendOKResponse(uint32 stream_id, std::string* output) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendOKResponseImpl(stream_id, output); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::InitSMInterface(SMInterface* sm_spdy_interface, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 server_idx) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_ = sm_spdy_interface; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_idx_ = server_idx; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::InitSMConnection(SMConnectionPoolInterface* connection_pool, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SMInterface* sm_interface, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* epoll_server, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_ip, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_port, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string remote_ip, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_ssl) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server " 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "connection."; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->InitSMConnection(connection_pool, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_interface, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ip, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_port, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_ip, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_ssl); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::ProcessReadInput(const char* data, size_t len) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream " 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_framer_->ProcessInput(data, len); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::ProcessWriteInput(const char* data, size_t len) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size " 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << len << ": stream " << stream_id_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char * dataPtr = new char[len]; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dataPtr, data, len); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* data_frame = new DataFrame; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame->data = (const char *)dataPtr; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame->size = len; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame->delete_when_done = true; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->EnqueueDataFrame(data_frame); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpSM::MessageFullyRead() const { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_framer_->MessageFullyRead(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SetStreamID(uint32 stream_id) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id_ = stream_id; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpSM::Error() const { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_framer_->Error(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* HttpSM::ErrorAsString() const { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BalsaFrameEnums::ErrorCodeToString(http_framer_->ErrorCode()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::Reset() { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Reset: stream " 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->Reset(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::ResetForNewConnection() { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Server connection closing " 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "to: " << connection_->server_ip_ << ":" 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << connection_->server_port_ << " "; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Message has not been fully read, either it is incomplete or the 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server is closing the connection to signal message end. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MessageFullyRead()) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "HTTP response closed before end of file detected. " 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Sending EOF to spdy."; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->SendEOF(stream_id_); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) seq_num_ = 0; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.Reset(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_framer_->Reset(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sm_spdy_interface_) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->ResetForNewInterface(server_idx_); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::Cleanup() { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "HttpSM Request Fully Read; stream_id: " << stream_id_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Cleanup("request complete"); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpSM::PostAcceptHook() { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::NewStream(uint32 stream_id, uint32 priority, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& filename) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter mci; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.stream_id = stream_id; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.priority = priority; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memory_cache_->AssignFileData(filename, &mci)) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error creating new stream. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound"; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorNotFound(stream_id); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToOutputOrder(mci); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendEOF(uint32 stream_id) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOFImpl(stream_id); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_spdy_interface_->ResetForNewInterface(server_idx_); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendErrorNotFound(uint32 stream_id) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorNotFoundImpl(stream_id); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SendSynReplyImpl(stream_id, headers); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendDataFrame(uint32 stream_id, const char* data, int64 len, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 flags, bool compress) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrameImpl(stream_id, data, len, flags, compress); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendEOFImpl(uint32 stream_id) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = "0\r\n\r\n"; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = 5; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = false; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendErrorNotFoundImpl(uint32 stream_id) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders my_headers; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.RemoveAllOfHeader("content-length"); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.AppendHeader("transfer-encoding", "chunked"); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendSynReplyImpl(stream_id, my_headers); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrame(stream_id, "page not found", 14, 0, false); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOFImpl(stream_id); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.RemoveStreamId(stream_id); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendOKResponseImpl(uint32 stream_id, std::string* output) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders my_headers; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "200", "OK"); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.RemoveAllOfHeader("content-length"); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_headers.AppendHeader("transfer-encoding", "chunked"); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendSynReplyImpl(stream_id, my_headers); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrame(stream_id, output->c_str(), output->size(), 0, false); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOFImpl(stream_id); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.RemoveStreamId(stream_id); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleBuffer sb; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers.WriteHeaderAndEndingToBuffer(&sb); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = sb.ReadableBytes(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sb.Read(buffer, df->size); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t df_size = df->size; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return df_size; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t HttpSM::SendSynStreamImpl(uint32 stream_id, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BalsaHeaders& headers) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleBuffer sb; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers.WriteHeaderAndEndingToBuffer(&sb); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = sb.ReadableBytes(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sb.Read(buffer, df->size); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t df_size = df->size; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return df_size; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 flags, bool compress) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char chunk_buf[128]; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string chunk_description(chunk_buf); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataFrame* df = new DataFrame; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->size = chunk_description.size() + len + 2; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer = new char[df->size]; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->data = buffer; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) df->delete_when_done = true; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer, chunk_description.data(), chunk_description.size()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer + chunk_description.size(), data, len); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer + chunk_description.size() + len, "\r\n", 2); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueDataFrame(df); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::EnqueueDataFrame(DataFrame* df) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream " 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << stream_id_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->EnqueueDataFrame(df); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpSM::GetOutput() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter* mci = output_ordering_.GetIter(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mci == NULL) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to " 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "output!?: stream " << stream_id_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mci->transformed_header) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->bytes_sent = SendSynReply(mci->stream_id, 335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch *(mci->file_data->headers())); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->transformed_header = true; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput transformed " 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "header stream_id: [" << mci->stream_id << "]"; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (mci->body_bytes_consumed >= mci->file_data->body().size()) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendEOF(mci->stream_id); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_.RemoveStreamId(mci->stream_id); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "GetOutput remove_stream_id: [" 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << mci->stream_id << "]"; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_to_write = 349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mci->file_data->body().size() - mci->body_bytes_consumed; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_to_write > mci->max_segment_size) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_to_write = mci->max_segment_size; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDataFrame(mci->stream_id, 354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mci->file_data->body().data() + mci->body_bytes_consumed, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_to_write, 0, true); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput SendDataFrame[" 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << mci->stream_id << "]: " << num_to_write; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->body_bytes_consumed += num_to_write; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci->bytes_sent += num_to_write; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 363