| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/flip_server/spdy_interface.h" | 5 #include "net/tools/flip_server/spdy_interface.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
| 10 #include "net/spdy/spdy_protocol.h" | 10 #include "net/spdy/spdy_protocol.h" |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 138 } |
| 139 | 139 |
| 140 sm_http_interface->InitSMInterface(this, server_idx); | 140 sm_http_interface->InitSMInterface(this, server_idx); |
| 141 sm_http_interface->InitSMConnection(NULL, sm_http_interface, | 141 sm_http_interface->InitSMConnection(NULL, sm_http_interface, |
| 142 epoll_server_, -1, | 142 epoll_server_, -1, |
| 143 server_ip, server_port, "", false); | 143 server_ip, server_port, "", false); |
| 144 | 144 |
| 145 return sm_http_interface; | 145 return sm_http_interface; |
| 146 } | 146 } |
| 147 | 147 |
| 148 int SpdySM::SpdyHandleNewStream(const SpdyControlFrame* frame, | 148 int SpdySM::SpdyHandleNewStream( |
| 149 std::string &http_data, | 149 const SpdySynStreamControlFrame* syn_stream, |
| 150 bool *is_https_scheme) { | 150 const linked_ptr<spdy::SpdyHeaderBlock>& headers, |
| 151 bool parsed_headers = false; | 151 std::string &http_data, |
| 152 SpdyHeaderBlock headers; | 152 bool* is_https_scheme) { |
| 153 const SpdySynStreamControlFrame* syn_stream = | |
| 154 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); | |
| 155 | |
| 156 *is_https_scheme = false; | 153 *is_https_scheme = false; |
| 157 parsed_headers = buffered_spdy_framer_->ParseHeaderBlock(frame, &headers); | |
| 158 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" | 154 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" |
| 159 << syn_stream->stream_id() << ")"; | 155 << syn_stream->stream_id() << ")"; |
| 160 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: headers parsed?: " | 156 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: # headers: " |
| 161 << (parsed_headers? "yes": "no"); | 157 << headers->size(); |
| 162 if (parsed_headers) { | 158 |
| 163 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: # headers: " | 159 SpdyHeaderBlock::iterator url = headers->find("url"); |
| 164 << headers.size(); | 160 SpdyHeaderBlock::iterator method = headers->find("method"); |
| 165 } | 161 if (url == headers->end() || method == headers->end()) { |
| 166 SpdyHeaderBlock::iterator url = headers.find("url"); | |
| 167 SpdyHeaderBlock::iterator method = headers.find("method"); | |
| 168 if (url == headers.end() || method == headers.end()) { | |
| 169 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: didn't find method or url " | 162 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: didn't find method or url " |
| 170 << "or method. Not creating stream"; | 163 << "or method. Not creating stream"; |
| 171 return 0; | 164 return 0; |
| 172 } | 165 } |
| 173 | 166 |
| 174 SpdyHeaderBlock::iterator scheme = headers.find("scheme"); | 167 SpdyHeaderBlock::iterator scheme = headers->find("scheme"); |
| 175 if (scheme->second.compare("https") == 0) { | 168 if (scheme->second.compare("https") == 0) { |
| 176 *is_https_scheme = true; | 169 *is_https_scheme = true; |
| 177 } | 170 } |
| 178 | 171 |
| 179 // url->second here only ever seems to contain just the path. When this | 172 // url->second here only ever seems to contain just the path. When this |
| 180 // path contains a query string with a http:// in one of its values, | 173 // path contains a query string with a http:// in one of its values, |
| 181 // UrlUtilities::GetUrlPath will fail and always return a / breaking | 174 // UrlUtilities::GetUrlPath will fail and always return a / breaking |
| 182 // the request. GetUrlPath assumes the absolute URL is being passed in. | 175 // the request. GetUrlPath assumes the absolute URL is being passed in. |
| 183 std::string uri; | 176 std::string uri; |
| 184 if (url->second.compare(0,4,"http") == 0) | 177 if (url->second.compare(0,4,"http") == 0) |
| 185 uri = UrlUtilities::GetUrlPath(url->second); | 178 uri = UrlUtilities::GetUrlPath(url->second); |
| 186 else | 179 else |
| 187 uri = std::string(url->second); | 180 uri = std::string(url->second); |
| 188 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { | 181 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { |
| 189 std::string host = UrlUtilities::GetUrlHost(url->second); | 182 std::string host = UrlUtilities::GetUrlHost(url->second); |
| 190 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second | 183 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second |
| 191 << " " << uri; | 184 << " " << uri; |
| 192 std::string filename = EncodeURL(uri, host, method->second); | 185 std::string filename = EncodeURL(uri, host, method->second); |
| 193 NewStream(syn_stream->stream_id(), | 186 NewStream(syn_stream->stream_id(), |
| 194 reinterpret_cast<const SpdySynStreamControlFrame*> | 187 syn_stream->priority(), |
| 195 (frame)->priority(), | |
| 196 filename); | 188 filename); |
| 197 } else { | 189 } else { |
| 198 SpdyHeaderBlock::iterator version = headers.find("version"); | 190 SpdyHeaderBlock::iterator version = headers->find("version"); |
| 199 http_data += method->second + " " + uri + " " + version->second + "\r\n"; | 191 http_data += method->second + " " + uri + " " + version->second + "\r\n"; |
| 200 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " " | 192 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " " |
| 201 << uri << " " << version->second; | 193 << uri << " " << version->second; |
| 202 for (SpdyHeaderBlock::iterator i = headers.begin(); | 194 for (SpdyHeaderBlock::iterator i = headers->begin(); |
| 203 i != headers.end(); ++i) { | 195 i != headers->end(); ++i) { |
| 204 http_data += i->first + ": " + i->second + "\r\n"; | 196 http_data += i->first + ": " + i->second + "\r\n"; |
| 205 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":" | 197 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":" |
| 206 << i->second.c_str(); | 198 << i->second.c_str(); |
| 207 } | 199 } |
| 208 if (forward_ip_header_.length()) { | 200 if (forward_ip_header_.length()) { |
| 209 // X-Client-Cluster-IP header | 201 // X-Client-Cluster-IP header |
| 210 http_data += forward_ip_header_ + ": " + | 202 http_data += forward_ip_header_ + ": " + |
| 211 connection_->client_ip() + "\r\n"; | 203 connection_->client_ip() + "\r\n"; |
| 212 } | 204 } |
| 213 http_data += "\r\n"; | 205 http_data += "\r\n"; |
| 214 } | 206 } |
| 215 | 207 |
| 216 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data; | 208 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data; |
| 217 return 1; | 209 return 1; |
| 218 } | 210 } |
| 219 | 211 |
| 220 void SpdySM::OnControl(const SpdyControlFrame* frame) { | |
| 221 SpdyHeaderBlock headers; | |
| 222 bool parsed_headers = false; | |
| 223 switch (frame->type()) { | |
| 224 case SYN_STREAM: | |
| 225 { | |
| 226 const SpdySynStreamControlFrame* syn_stream = | |
| 227 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); | |
| 228 | |
| 229 std::string http_data; | |
| 230 bool is_https_scheme; | |
| 231 int ret = SpdyHandleNewStream(frame, http_data, &is_https_scheme); | |
| 232 if (!ret) { | |
| 233 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; | |
| 234 break; | |
| 235 } | |
| 236 // We've seen a valid looking SYN_STREAM, consider this to have | |
| 237 // been a real spdy session. | |
| 238 valid_spdy_session_ = true; | |
| 239 | |
| 240 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { | |
| 241 std::string server_ip; | |
| 242 std::string server_port; | |
| 243 if (is_https_scheme) { | |
| 244 server_ip = acceptor_->https_server_ip_; | |
| 245 server_port = acceptor_->https_server_port_; | |
| 246 } else { | |
| 247 server_ip = acceptor_->http_server_ip_; | |
| 248 server_port = acceptor_->http_server_port_; | |
| 249 } | |
| 250 SMInterface *sm_http_interface = | |
| 251 FindOrMakeNewSMConnectionInterface(server_ip, server_port); | |
| 252 stream_to_smif_[syn_stream->stream_id()] = sm_http_interface; | |
| 253 sm_http_interface->SetStreamID(syn_stream->stream_id()); | |
| 254 sm_http_interface->ProcessWriteInput(http_data.c_str(), | |
| 255 http_data.size()); | |
| 256 } | |
| 257 } | |
| 258 break; | |
| 259 | |
| 260 case SYN_REPLY: | |
| 261 parsed_headers = buffered_spdy_framer_->ParseHeaderBlock(frame, &headers); | |
| 262 DCHECK(parsed_headers); | |
| 263 // TODO(willchan): if there is an error parsing headers, we | |
| 264 // should send a RST_STREAM. | |
| 265 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSynReply(" << | |
| 266 reinterpret_cast<const SpdySynReplyControlFrame*>(frame)->stream_id() | |
| 267 << ")"; | |
| 268 break; | |
| 269 case RST_STREAM: | |
| 270 { | |
| 271 const SpdyRstStreamControlFrame* rst_stream = | |
| 272 reinterpret_cast<const SpdyRstStreamControlFrame*>(frame); | |
| 273 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnRst(" | |
| 274 << rst_stream->stream_id() << ")"; | |
| 275 client_output_ordering_.RemoveStreamId(rst_stream ->stream_id()); | |
| 276 } | |
| 277 break; | |
| 278 | |
| 279 default: | |
| 280 LOG(ERROR) << "SpdySM: Unknown control frame type"; | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 bool SpdySM::OnControlFrameHeaderData(spdy::SpdyStreamId stream_id, | |
| 285 const char* header_data, | |
| 286 size_t len) { | |
| 287 DCHECK(false); | |
| 288 return false; | |
| 289 } | |
| 290 | |
| 291 void SpdySM::OnDataFrameHeader(const spdy::SpdyDataFrame* frame) { | |
| 292 buffered_spdy_framer_->OnDataFrameHeader(frame); | |
| 293 } | |
| 294 | |
| 295 void SpdySM::OnStreamFrameData(SpdyStreamId stream_id, | 212 void SpdySM::OnStreamFrameData(SpdyStreamId stream_id, |
| 296 const char* data, size_t len) { | 213 const char* data, size_t len) { |
| 297 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: StreamData(" << stream_id | 214 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: StreamData(" << stream_id |
| 298 << ", [" << len << "])"; | 215 << ", [" << len << "])"; |
| 299 StreamToSmif::iterator it = stream_to_smif_.find(stream_id); | 216 StreamToSmif::iterator it = stream_to_smif_.find(stream_id); |
| 300 if (it == stream_to_smif_.end()) { | 217 if (it == stream_to_smif_.end()) { |
| 301 VLOG(2) << "Dropping frame from unknown stream " << stream_id; | 218 VLOG(2) << "Dropping frame from unknown stream " << stream_id; |
| 302 if (!valid_spdy_session_) | 219 if (!valid_spdy_session_) |
| 303 close_on_error_ = true; | 220 close_on_error_ = true; |
| 304 return; | 221 return; |
| 305 } | 222 } |
| 306 | 223 |
| 307 SMInterface* interface = it->second; | 224 SMInterface* interface = it->second; |
| 308 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) | 225 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) |
| 309 interface->ProcessWriteInput(data, len); | 226 interface->ProcessWriteInput(data, len); |
| 310 } | 227 } |
| 311 | 228 |
| 312 bool SpdySM::OnCredentialFrameData(const char* frame_data, | 229 void SpdySM::OnSynStream(const spdy::SpdySynStreamControlFrame& syn_stream, |
| 313 size_t len) { | 230 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 314 return false; | 231 std::string http_data; |
| 315 } | 232 bool is_https_scheme; |
| 233 int ret = SpdyHandleNewStream(&syn_stream, headers, http_data, |
| 234 &is_https_scheme); |
| 235 if (!ret) { |
| 236 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; |
| 237 return; |
| 238 } |
| 239 // We've seen a valid looking SYN_STREAM, consider this to have |
| 240 // been a real spdy session. |
| 241 valid_spdy_session_ = true; |
| 316 | 242 |
| 317 void SpdySM::OnSyn(const spdy::SpdySynStreamControlFrame& frame, | 243 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { |
| 318 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 244 std::string server_ip; |
| 245 std::string server_port; |
| 246 if (is_https_scheme) { |
| 247 server_ip = acceptor_->https_server_ip_; |
| 248 server_port = acceptor_->https_server_port_; |
| 249 } else { |
| 250 server_ip = acceptor_->http_server_ip_; |
| 251 server_port = acceptor_->http_server_port_; |
| 252 } |
| 253 SMInterface* sm_http_interface = |
| 254 FindOrMakeNewSMConnectionInterface(server_ip, server_port); |
| 255 stream_to_smif_[syn_stream.stream_id()] = sm_http_interface; |
| 256 sm_http_interface->SetStreamID(syn_stream.stream_id()); |
| 257 sm_http_interface->ProcessWriteInput(http_data.c_str(), |
| 258 http_data.size()); |
| 259 } |
| 319 } | 260 } |
| 320 | 261 |
| 321 void SpdySM::OnSynReply(const spdy::SpdySynReplyControlFrame& frame, | 262 void SpdySM::OnSynReply(const spdy::SpdySynReplyControlFrame& frame, |
| 322 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 263 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 264 // TODO(willchan): if there is an error parsing headers, we |
| 265 // should send a RST_STREAM. |
| 266 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSynReply(" |
| 267 << frame.stream_id() << ")"; |
| 323 } | 268 } |
| 324 | 269 |
| 325 void SpdySM::OnHeaders(const spdy::SpdyHeadersControlFrame& frame, | 270 void SpdySM::OnHeaders(const spdy::SpdyHeadersControlFrame& frame, |
| 326 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 271 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 272 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnHeaders(" |
| 273 << frame.stream_id() << ")"; |
| 274 } |
| 275 |
| 276 void SpdySM::OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) { |
| 277 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnRstStream(" |
| 278 << frame.stream_id() << ")"; |
| 279 client_output_ordering_.RemoveStreamId(frame.stream_id()); |
| 327 } | 280 } |
| 328 | 281 |
| 329 size_t SpdySM::ProcessReadInput(const char* data, size_t len) { | 282 size_t SpdySM::ProcessReadInput(const char* data, size_t len) { |
| 330 return buffered_spdy_framer_->ProcessInput(data, len); | 283 return buffered_spdy_framer_->ProcessInput(data, len); |
| 331 } | 284 } |
| 332 | 285 |
| 333 size_t SpdySM::ProcessWriteInput(const char* data, size_t len) { | 286 size_t SpdySM::ProcessWriteInput(const char* data, size_t len) { |
| 334 return 0; | 287 return 0; |
| 335 } | 288 } |
| 336 | 289 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 mci->file_data->body.data() + mci->body_bytes_consumed, | 573 mci->file_data->body.data() + mci->body_bytes_consumed, |
| 621 num_to_write, 0, should_compress); | 574 num_to_write, 0, should_compress); |
| 622 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput SendDataFrame[" | 575 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput SendDataFrame[" |
| 623 << mci->stream_id << "]: " << num_to_write; | 576 << mci->stream_id << "]: " << num_to_write; |
| 624 mci->body_bytes_consumed += num_to_write; | 577 mci->body_bytes_consumed += num_to_write; |
| 625 mci->bytes_sent += num_to_write; | 578 mci->bytes_sent += num_to_write; |
| 626 } | 579 } |
| 627 } | 580 } |
| 628 | 581 |
| 629 } // namespace net | 582 } // namespace net |
| OLD | NEW |