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 |