1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/tools/flip_server/streamer_interface.h" 6 7 #include <string> 8 9 #include "net/tools/flip_server/balsa_frame.h" 10 #include "net/tools/flip_server/constants.h" 11 #include "net/tools/flip_server/flip_config.h" 12 #include "net/tools/flip_server/sm_connection.h" 13 14 namespace net { 15 16 std::string StreamerSM::forward_ip_header_; 17 18 StreamerSM::StreamerSM(SMConnection* connection, 19 SMInterface* sm_other_interface, 20 EpollServer* epoll_server, 21 FlipAcceptor* acceptor) 22 : connection_(connection), 23 sm_other_interface_(sm_other_interface), 24 epoll_server_(epoll_server), 25 acceptor_(acceptor), 26 is_request_(false), 27 http_framer_(new BalsaFrame) { 28 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Creating StreamerSM object"; 29 http_framer_->set_balsa_visitor(this); 30 http_framer_->set_balsa_headers(&headers_); 31 http_framer_->set_is_request(false); 32 } 33 34 StreamerSM::~StreamerSM() { 35 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Destroying StreamerSM object"; 36 Reset(); 37 delete http_framer_; 38 } 39 40 void StreamerSM::set_is_request() { 41 is_request_ = true; 42 http_framer_->set_is_request(true); 43 } 44 45 void StreamerSM::InitSMInterface(SMInterface* sm_other_interface, 46 int32 server_idx) { 47 sm_other_interface_ = sm_other_interface; 48 } 49 50 void StreamerSM::InitSMConnection(SMConnectionPoolInterface* connection_pool, 51 SMInterface* sm_interface, 52 EpollServer* epoll_server, 53 int fd, 54 std::string server_ip, 55 std::string server_port, 56 std::string remote_ip, 57 bool use_ssl) { 58 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Initializing server " 59 << "connection."; 60 connection_->InitSMConnection(connection_pool, sm_interface, 61 epoll_server, fd, server_ip, 62 server_port, remote_ip, use_ssl); 63 } 64 65 size_t StreamerSM::ProcessReadInput(const char* data, size_t len) { 66 // For now we only want to parse http requests. Just stream responses 67 if (is_request_) { 68 return http_framer_->ProcessInput(data, len); 69 } else { 70 return sm_other_interface_->ProcessWriteInput(data, len); 71 } 72 } 73 74 size_t StreamerSM::ProcessWriteInput(const char* data, size_t len) { 75 char * dataPtr = new char[len]; 76 memcpy(dataPtr, data, len); 77 DataFrame* df = new DataFrame; 78 df->data = (const char *)dataPtr; 79 df->size = len; 80 df->delete_when_done = true; 81 connection_->EnqueueDataFrame(df); 82 return len; 83 } 84 85 bool StreamerSM::Error() const { 86 return false; 87 } 88 89 const char* StreamerSM::ErrorAsString() const { 90 return "(none)"; 91 } 92 93 bool StreamerSM::MessageFullyRead() const { 94 if (is_request_) { 95 return http_framer_->MessageFullyRead(); 96 } else { 97 return false; 98 } 99 } 100 101 void StreamerSM::Reset() { 102 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Reset"; 103 connection_->Cleanup("Server Reset"); 104 http_framer_->Reset(); 105 } 106 107 void StreamerSM::ResetForNewConnection() { 108 http_framer_->Reset(); 109 sm_other_interface_->Reset(); 110 } 111 112 void StreamerSM::Cleanup() { 113 if (is_request_) 114 http_framer_->Reset(); 115 } 116 117 int StreamerSM::PostAcceptHook() { 118 if (!sm_other_interface_) { 119 SMConnection *server_connection = 120 SMConnection::NewSMConnection(epoll_server_, NULL, NULL, 121 acceptor_, "server_conn: "); 122 if (server_connection == NULL) { 123 LOG(ERROR) << "StreamerSM: Could not create server conenction."; 124 return 0; 125 } 126 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Creating new server " 127 << "connection."; 128 sm_other_interface_ = new StreamerSM(server_connection, this, 129 epoll_server_, acceptor_); 130 sm_other_interface_->InitSMInterface(this, 0); 131 } 132 // The Streamer interface is used to stream HTTPS connections, so we 133 // will always use the https_server_ip/port here. 134 sm_other_interface_->InitSMConnection(NULL, sm_other_interface_, 135 epoll_server_, -1, 136 acceptor_->https_server_ip_, 137 acceptor_->https_server_port_, 138 "", 139 false); 140 141 return 1; 142 } 143 144 size_t StreamerSM::SendSynStream(uint32 stream_id, 145 const BalsaHeaders& headers) { 146 return 0; 147 } 148 149 size_t StreamerSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { 150 return 0; 151 } 152 153 void StreamerSM::ProcessBodyInput(const char *input, size_t size) { 154 VLOG(2) << ACCEPTOR_CLIENT_IDENT 155 << "StreamerHttpSM: Process Body Input Data: " 156 << "size " << size; 157 sm_other_interface_->ProcessWriteInput(input, size); 158 } 159 160 void StreamerSM::MessageDone() { 161 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 162 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerHttpSM: MessageDone."; 163 // TODO(kelindsay): anything need to be done ehre? 164 } else { 165 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StraemerHttpSM: MessageDone."; 166 } 167 } 168 169 void StreamerSM::ProcessHeaders(const BalsaHeaders& headers) { 170 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpStreamerSM: Process Headers"; 171 BalsaHeaders mod_headers; 172 mod_headers.CopyFrom(headers); 173 if (forward_ip_header_.length()) { 174 LOG(INFO) << "Adding forward header: " << forward_ip_header_; 175 mod_headers.ReplaceOrAppendHeader(forward_ip_header_, 176 connection_->client_ip()); 177 } else { 178 LOG(INFO) << "NOT adding forward header."; 179 } 180 SimpleBuffer sb; 181 char* buffer; 182 int size; 183 mod_headers.WriteHeaderAndEndingToBuffer(&sb); 184 sb.GetReadablePtr(&buffer, &size); 185 sm_other_interface_->ProcessWriteInput(buffer, size); 186 } 187 188 void StreamerSM::HandleHeaderError(BalsaFrame* framer) { 189 HandleError(); 190 } 191 192 void StreamerSM::HandleChunkingError(BalsaFrame* framer) { 193 HandleError(); 194 } 195 196 void StreamerSM::HandleBodyError(BalsaFrame* framer) { 197 HandleError(); 198 } 199 200 void StreamerSM::HandleError() { 201 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected"; 202 } 203 204 } // namespace net 205 206