1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/http_interface.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/dump_cache/url_utilities.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/balsa_frame.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/flip_config.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/sm_connection.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/spdy_util.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace net { 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 15dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHttpSM::HttpSM(SMConnection* connection, 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SMInterface* sm_spdy_interface, 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EpollServer* epoll_server, 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemoryCache* memory_cache, 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FlipAcceptor* acceptor) 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : seq_num_(0), 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_(new BalsaFrame), 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen stream_id_(0), 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen server_idx_(-1), 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_(connection), 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_(sm_spdy_interface), 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_list_(connection->output_list()), 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_(connection), 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memory_cache_(connection->memory_cache()), 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen acceptor_(acceptor) { 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_->set_balsa_visitor(this); 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_->set_balsa_headers(&headers_); 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_->set_is_request(false); 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 35dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHttpSM::~HttpSM() { 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Reset(); 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete http_framer_; 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::ProcessBodyData(const char *input, size_t size) { 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process Body Data: stream " 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_ << ": size " << size; 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_->SendDataFrame(stream_id_, input, size, 0, false); 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::ProcessHeaders(const BalsaHeaders& headers) { 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string host = 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UrlUtilities::GetUrlHost(headers.GetHeader("Host").as_string()); 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string method = headers.request_method().as_string(); 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Received Request: " 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << headers.request_uri().as_string() << " " << method; 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string filename = EncodeURL(headers.request_uri().as_string(), 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen host, method); 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewStream(stream_id_, 0, filename); 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen stream_id_ += 2; 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Received Response from " 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << connection_->server_ip_ << ":" 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << connection_->server_port_ << " "; 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_->SendSynReply(stream_id_, headers); 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::MessageDone() { 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone. Sending EOF: " 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "stream " << stream_id_; 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_->SendEOF(stream_id_); 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone."; 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::HandleHeaderError(BalsaFrame* framer) { 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HandleError(); 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::HandleChunkingError(BalsaFrame* framer) { 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HandleError(); 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::HandleBodyError(BalsaFrame* framer) { 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HandleError(); 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::HandleError() { 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected"; 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::AddToOutputOrder(const MemCacheIter& mci) { 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_.AddToOutputOrder(mci); 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendOKResponse(uint32 stream_id, std::string* output) { 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendOKResponseImpl(stream_id, output); 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::InitSMInterface(SMInterface* sm_spdy_interface, 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int32 server_idx) { 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_ = sm_spdy_interface; 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen server_idx_ = server_idx; 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::InitSMConnection(SMConnectionPoolInterface* connection_pool, 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SMInterface* sm_interface, 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EpollServer* epoll_server, 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int fd, 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string server_ip, 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string server_port, 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string remote_ip, 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool use_ssl) { 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server " 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "connection."; 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_->InitSMConnection(connection_pool, 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_interface, 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server, 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen fd, 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen server_ip, 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen server_port, 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen remote_ip, 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen use_ssl); 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::ProcessReadInput(const char* data, size_t len) { 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream " 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_; 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return http_framer_->ProcessInput(data, len); 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::ProcessWriteInput(const char* data, size_t len) { 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size " 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << len << ": stream " << stream_id_; 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char * dataPtr = new char[len]; 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memcpy(dataPtr, data, len); 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DataFrame* data_frame = new DataFrame; 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_frame->data = (const char *)dataPtr; 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_frame->size = len; 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_frame->delete_when_done = true; 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_->EnqueueDataFrame(data_frame); 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return len; 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool HttpSM::MessageFullyRead() const { 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return http_framer_->MessageFullyRead(); 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SetStreamID(uint32 stream_id) { 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen stream_id_ = stream_id; 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool HttpSM::Error() const { 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return http_framer_->Error(); 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char* HttpSM::ErrorAsString() const { 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return BalsaFrameEnums::ErrorCodeToString(http_framer_->ErrorCode()); 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::Reset() { 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Reset: stream " 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_; 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_->Reset(); 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::ResetForNewConnection() { 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Server connection closing " 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "to: " << connection_->server_ip_ << ":" 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << connection_->server_port_ << " "; 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Message has not been fully read, either it is incomplete or the 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // server is closing the connection to signal message end. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!MessageFullyRead()) { 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen VLOG(2) << "HTTP response closed before end of file detected. " 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << "Sending EOF to spdy."; 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sm_spdy_interface_->SendEOF(stream_id_); 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen seq_num_ = 0; 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_.Reset(); 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_framer_->Reset(); 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (sm_spdy_interface_) { 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_->ResetForNewInterface(server_idx_); 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::Cleanup() { 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) { 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << "HttpSM Request Fully Read; stream_id: " << stream_id_; 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_->Cleanup("request complete"); 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint HttpSM::PostAcceptHook() { 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return 1; 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::NewStream(uint32 stream_id, uint32 priority, 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& filename) { 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemCacheIter mci; 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci.stream_id = stream_id; 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci.priority = priority; 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!memory_cache_->AssignFileData(filename, &mci)) { 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // error creating new stream. 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound"; 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendErrorNotFound(stream_id); 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AddToOutputOrder(mci); 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendEOF(uint32 stream_id) { 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendEOFImpl(stream_id); 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sm_spdy_interface_->ResetForNewInterface(server_idx_); 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendErrorNotFound(uint32 stream_id) { 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendErrorNotFoundImpl(stream_id); 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) { 226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return 0; 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { 230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return SendSynReplyImpl(stream_id, headers); 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendDataFrame(uint32 stream_id, const char* data, int64 len, 234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 flags, bool compress) { 235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendDataFrameImpl(stream_id, data, len, flags, compress); 236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendEOFImpl(uint32 stream_id) { 239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DataFrame* df = new DataFrame; 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->data = "0\r\n\r\n"; 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->size = 5; 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->delete_when_done = false; 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EnqueueDataFrame(df); 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Reset(); 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendErrorNotFoundImpl(uint32 stream_id) { 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BalsaHeaders my_headers; 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.RemoveAllOfHeader("content-length"); 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.AppendHeader("transfer-encoding", "chunked"); 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendSynReplyImpl(stream_id, my_headers); 255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendDataFrame(stream_id, "page not found", 14, 0, false); 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendEOFImpl(stream_id); 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_.RemoveStreamId(stream_id); 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendOKResponseImpl(uint32 stream_id, std::string* output) { 261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BalsaHeaders my_headers; 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "200", "OK"); 263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.RemoveAllOfHeader("content-length"); 264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen my_headers.AppendHeader("transfer-encoding", "chunked"); 265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendSynReplyImpl(stream_id, my_headers); 266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendDataFrame(stream_id, output->c_str(), output->size(), 0, false); 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendEOFImpl(stream_id); 268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_.RemoveStreamId(stream_id); 269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SimpleBuffer sb; 273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen headers.WriteHeaderAndEndingToBuffer(&sb); 274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DataFrame* df = new DataFrame; 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->size = sb.ReadableBytes(); 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* buffer = new char[df->size]; 277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->data = buffer; 278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->delete_when_done = true; 279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sb.Read(buffer, df->size); 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_; 282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t df_size = df->size; 283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EnqueueDataFrame(df); 284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return df_size; 285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t HttpSM::SendSynStreamImpl(uint32 stream_id, 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const BalsaHeaders& headers) { 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SimpleBuffer sb; 290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen headers.WriteHeaderAndEndingToBuffer(&sb); 291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DataFrame* df = new DataFrame; 292dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->size = sb.ReadableBytes(); 293dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* buffer = new char[df->size]; 294dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->data = buffer; 295dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->delete_when_done = true; 296dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sb.Read(buffer, df->size); 297dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_; 299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t df_size = df->size; 300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EnqueueDataFrame(df); 301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return df_size; 302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, 305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 flags, bool compress) { 306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char chunk_buf[128]; 307dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len); 308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string chunk_description(chunk_buf); 309dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DataFrame* df = new DataFrame; 310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->size = chunk_description.size() + len + 2; 311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* buffer = new char[df->size]; 312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->data = buffer; 313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen df->delete_when_done = true; 314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memcpy(buffer, chunk_description.data(), chunk_description.size()); 315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memcpy(buffer + chunk_description.size(), data, len); 316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memcpy(buffer + chunk_description.size() + len, "\r\n", 2); 317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EnqueueDataFrame(df); 318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 320dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::EnqueueDataFrame(DataFrame* df) { 321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream " 322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << stream_id_; 323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_->EnqueueDataFrame(df); 324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpSM::GetOutput() { 327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemCacheIter* mci = output_ordering_.GetIter(); 328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (mci == NULL) { 329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to " 330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "output!?: stream " << stream_id_; 331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!mci->transformed_header) { 334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->bytes_sent = SendSynReply(mci->stream_id, 335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *(mci->file_data->headers)); 336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->transformed_header = true; 337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput transformed " 338dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "header stream_id: [" << mci->stream_id << "]"; 339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (mci->body_bytes_consumed >= mci->file_data->body.size()) { 342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendEOF(mci->stream_id); 343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_.RemoveStreamId(mci->stream_id); 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "GetOutput remove_stream_id: [" 345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << mci->stream_id << "]"; 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t num_to_write = 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->file_data->body.size() - mci->body_bytes_consumed; 350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (num_to_write > mci->max_segment_size) 351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen num_to_write = mci->max_segment_size; 352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendDataFrame(mci->stream_id, 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->file_data->body.data() + mci->body_bytes_consumed, 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen num_to_write, 0, true); 356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput SendDataFrame[" 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << mci->stream_id << "]: " << num_to_write; 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->body_bytes_consumed += num_to_write; 359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci->bytes_sent += num_to_write; 360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace net 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 364