Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: net/tools/flip_server/spdy_interface.cc

Issue 93793004: Format and Refactor Flip Server. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "net/spdy/spdy_framer.h" 10 #include "net/spdy/spdy_framer.h"
11 #include "net/spdy/spdy_protocol.h" 11 #include "net/spdy/spdy_protocol.h"
12 #include "net/tools/dump_cache/url_utilities.h" 12 #include "net/tools/dump_cache/url_utilities.h"
13 #include "net/tools/flip_server/constants.h" 13 #include "net/tools/flip_server/constants.h"
14 #include "net/tools/flip_server/flip_config.h" 14 #include "net/tools/flip_server/flip_config.h"
15 #include "net/tools/flip_server/http_interface.h" 15 #include "net/tools/flip_server/http_interface.h"
16 #include "net/tools/flip_server/spdy_util.h" 16 #include "net/tools/flip_server/spdy_util.h"
17 17
18 namespace net { 18 namespace net {
19 19
20 // static 20 // static
21 std::string SpdySM::forward_ip_header_; 21 std::string SpdySM::forward_ip_header_;
22 22
23 class SpdyFrameDataFrame : public DataFrame { 23 class SpdyFrameDataFrame : public DataFrame {
24 public: 24 public:
25 explicit SpdyFrameDataFrame(SpdyFrame* spdy_frame) 25 explicit SpdyFrameDataFrame(SpdyFrame* spdy_frame) : frame(spdy_frame) {
26 : frame(spdy_frame) {
27 data = spdy_frame->data(); 26 data = spdy_frame->data();
28 size = spdy_frame->size(); 27 size = spdy_frame->size();
29 } 28 }
30 29
31 virtual ~SpdyFrameDataFrame() { 30 virtual ~SpdyFrameDataFrame() { delete frame; }
32 delete frame;
33 }
34 31
35 const SpdyFrame* frame; 32 const SpdyFrame* frame;
36 }; 33 };
37 34
38 SpdySM::SpdySM(SMConnection* connection, 35 SpdySM::SpdySM(SMConnection* connection,
39 SMInterface* sm_http_interface, 36 SMInterface* sm_http_interface,
40 EpollServer* epoll_server, 37 EpollServer* epoll_server,
41 MemoryCache* memory_cache, 38 MemoryCache* memory_cache,
42 FlipAcceptor* acceptor, 39 FlipAcceptor* acceptor,
43 SpdyMajorVersion spdy_version) 40 SpdyMajorVersion spdy_version)
44 : buffered_spdy_framer_(new BufferedSpdyFramer(spdy_version, true)), 41 : buffered_spdy_framer_(new BufferedSpdyFramer(spdy_version, true)),
45 valid_spdy_session_(false), 42 valid_spdy_session_(false),
46 connection_(connection), 43 connection_(connection),
47 client_output_list_(connection->output_list()), 44 client_output_list_(connection->output_list()),
48 client_output_ordering_(connection), 45 client_output_ordering_(connection),
49 next_outgoing_stream_id_(2), 46 next_outgoing_stream_id_(2),
50 epoll_server_(epoll_server), 47 epoll_server_(epoll_server),
51 acceptor_(acceptor), 48 acceptor_(acceptor),
52 memory_cache_(memory_cache), 49 memory_cache_(memory_cache),
53 close_on_error_(false) { 50 close_on_error_(false) {
54 buffered_spdy_framer_->set_visitor(this); 51 buffered_spdy_framer_->set_visitor(this);
55 } 52 }
56 53
57 SpdySM::~SpdySM() { 54 SpdySM::~SpdySM() { delete buffered_spdy_framer_; }
58 delete buffered_spdy_framer_;
59 }
60 55
61 void SpdySM::InitSMConnection(SMConnectionPoolInterface* connection_pool, 56 void SpdySM::InitSMConnection(SMConnectionPoolInterface* connection_pool,
62 SMInterface* sm_interface, 57 SMInterface* sm_interface,
63 EpollServer* epoll_server, 58 EpollServer* epoll_server,
64 int fd, 59 int fd,
65 std::string server_ip, 60 std::string server_ip,
66 std::string server_port, 61 std::string server_port,
67 std::string remote_ip, 62 std::string remote_ip,
68 bool use_ssl) { 63 bool use_ssl) {
69 VLOG(2) << ACCEPTOR_CLIENT_IDENT 64 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Initializing server connection.";
70 << "SpdySM: Initializing server connection."; 65 connection_->InitSMConnection(connection_pool,
71 connection_->InitSMConnection(connection_pool, sm_interface, 66 sm_interface,
72 epoll_server, fd, server_ip, server_port, 67 epoll_server,
73 remote_ip, use_ssl); 68 fd,
69 server_ip,
70 server_port,
71 remote_ip,
72 use_ssl);
74 } 73 }
75 74
76 SMInterface* SpdySM::NewConnectionInterface() { 75 SMInterface* SpdySM::NewConnectionInterface() {
77 SMConnection* server_connection = 76 SMConnection* server_connection = SMConnection::NewSMConnection(
78 SMConnection::NewSMConnection(epoll_server_, 77 epoll_server_, NULL, memory_cache_, acceptor_, "http_conn: ");
79 NULL,
80 memory_cache_,
81 acceptor_,
82 "http_conn: ");
83 if (server_connection == NULL) { 78 if (server_connection == NULL) {
84 LOG(ERROR) << "SpdySM: Could not create server connection"; 79 LOG(ERROR) << "SpdySM: Could not create server connection";
85 return NULL; 80 return NULL;
86 } 81 }
87 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Creating new HTTP interface"; 82 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Creating new HTTP interface";
88 SMInterface *sm_http_interface = new HttpSM(server_connection, 83 SMInterface* sm_http_interface =
89 this, 84 new HttpSM(server_connection, this, memory_cache_, acceptor_);
90 memory_cache_,
91 acceptor_);
92 return sm_http_interface; 85 return sm_http_interface;
93 } 86 }
94 87
95 SMInterface* SpdySM::FindOrMakeNewSMConnectionInterface( 88 SMInterface* SpdySM::FindOrMakeNewSMConnectionInterface(
96 const std::string& server_ip, 89 const std::string& server_ip,
97 const std::string& server_port) { 90 const std::string& server_port) {
98 SMInterface *sm_http_interface; 91 SMInterface* sm_http_interface;
99 int32 server_idx; 92 int32 server_idx;
100 if (unused_server_interface_list.empty()) { 93 if (unused_server_interface_list.empty()) {
101 sm_http_interface = NewConnectionInterface(); 94 sm_http_interface = NewConnectionInterface();
102 server_idx = server_interface_list.size(); 95 server_idx = server_interface_list.size();
103 server_interface_list.push_back(sm_http_interface); 96 server_interface_list.push_back(sm_http_interface);
104 VLOG(2) << ACCEPTOR_CLIENT_IDENT 97 VLOG(2) << ACCEPTOR_CLIENT_IDENT
105 << "SpdySM: Making new server connection on index: " 98 << "SpdySM: Making new server connection on index: " << server_idx;
106 << server_idx;
107 } else { 99 } else {
108 server_idx = unused_server_interface_list.back(); 100 server_idx = unused_server_interface_list.back();
109 unused_server_interface_list.pop_back(); 101 unused_server_interface_list.pop_back();
110 sm_http_interface = server_interface_list.at(server_idx); 102 sm_http_interface = server_interface_list.at(server_idx);
111 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reusing connection on " 103 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reusing connection on "
112 << "index: " << server_idx; 104 << "index: " << server_idx;
113 } 105 }
114 106
115 sm_http_interface->InitSMInterface(this, server_idx); 107 sm_http_interface->InitSMInterface(this, server_idx);
116 sm_http_interface->InitSMConnection(NULL, 108 sm_http_interface->InitSMConnection(NULL,
117 sm_http_interface, 109 sm_http_interface,
118 epoll_server_, 110 epoll_server_,
119 -1, 111 -1,
120 server_ip, 112 server_ip,
121 server_port, 113 server_port,
122 std::string(), 114 std::string(),
123 false); 115 false);
124 116
125 return sm_http_interface; 117 return sm_http_interface;
126 } 118 }
127 119
128 int SpdySM::SpdyHandleNewStream( 120 int SpdySM::SpdyHandleNewStream(SpdyStreamId stream_id,
129 SpdyStreamId stream_id, 121 SpdyPriority priority,
130 SpdyPriority priority, 122 const SpdyHeaderBlock& headers,
131 const SpdyHeaderBlock& headers, 123 std::string& http_data,
132 std::string &http_data, 124 bool* is_https_scheme) {
133 bool* is_https_scheme) {
134 *is_https_scheme = false; 125 *is_https_scheme = false;
135 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" 126 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" << stream_id << ")";
136 << stream_id << ")"; 127 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: # headers: " << headers.size();
137 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: # headers: "
138 << headers.size();
139 128
140 SpdyHeaderBlock::const_iterator url = headers.find("url"); 129 SpdyHeaderBlock::const_iterator url = headers.find("url");
141 SpdyHeaderBlock::const_iterator method = headers.find("method"); 130 SpdyHeaderBlock::const_iterator method = headers.find("method");
142 if (url == headers.end() || method == headers.end()) { 131 if (url == headers.end() || method == headers.end()) {
143 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: didn't find method or url " 132 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: didn't find method or url "
144 << "or method. Not creating stream"; 133 << "or method. Not creating stream";
145 return 0; 134 return 0;
146 } 135 }
147 136
148 SpdyHeaderBlock::const_iterator scheme = headers.find("scheme"); 137 SpdyHeaderBlock::const_iterator scheme = headers.find("scheme");
149 if (scheme->second.compare("https") == 0) { 138 if (scheme->second.compare("https") == 0) {
150 *is_https_scheme = true; 139 *is_https_scheme = true;
151 } 140 }
152 141
153 // url->second here only ever seems to contain just the path. When this 142 // url->second here only ever seems to contain just the path. When this
154 // path contains a query string with a http:// in one of its values, 143 // path contains a query string with a http:// in one of its values,
155 // UrlUtilities::GetUrlPath will fail and always return a / breaking 144 // UrlUtilities::GetUrlPath will fail and always return a / breaking
156 // the request. GetUrlPath assumes the absolute URL is being passed in. 145 // the request. GetUrlPath assumes the absolute URL is being passed in.
157 std::string uri; 146 std::string uri;
158 if (url->second.compare(0, 4, "http") == 0) 147 if (url->second.compare(0, 4, "http") == 0)
159 uri = UrlUtilities::GetUrlPath(url->second); 148 uri = UrlUtilities::GetUrlPath(url->second);
160 else 149 else
161 uri = std::string(url->second); 150 uri = std::string(url->second);
162 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { 151 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) {
163 std::string host = UrlUtilities::GetUrlHost(url->second); 152 std::string host = UrlUtilities::GetUrlHost(url->second);
164 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second 153 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " "
165 << " " << uri; 154 << uri;
166 std::string filename = EncodeURL(uri, host, method->second); 155 std::string filename = EncodeURL(uri, host, method->second);
167 NewStream(stream_id, priority, filename); 156 NewStream(stream_id, priority, filename);
168 } else { 157 } else {
169 SpdyHeaderBlock::const_iterator version = headers.find("version"); 158 SpdyHeaderBlock::const_iterator version = headers.find("version");
170 http_data += method->second + " " + uri + " " + version->second + "\r\n"; 159 http_data += method->second + " " + uri + " " + version->second + "\r\n";
171 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " " 160 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " "
172 << uri << " " << version->second; 161 << uri << " " << version->second;
173 for (SpdyHeaderBlock::const_iterator i = headers.begin(); 162 for (SpdyHeaderBlock::const_iterator i = headers.begin();
174 i != headers.end(); ++i) { 163 i != headers.end();
164 ++i) {
175 http_data += i->first + ": " + i->second + "\r\n"; 165 http_data += i->first + ": " + i->second + "\r\n";
176 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":" 166 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":"
177 << i->second.c_str(); 167 << i->second.c_str();
178 } 168 }
179 if (forward_ip_header_.length()) { 169 if (forward_ip_header_.length()) {
180 // X-Client-Cluster-IP header 170 // X-Client-Cluster-IP header
181 http_data += forward_ip_header_ + ": " + 171 http_data +=
182 connection_->client_ip() + "\r\n"; 172 forward_ip_header_ + ": " + connection_->client_ip() + "\r\n";
183 } 173 }
184 http_data += "\r\n"; 174 http_data += "\r\n";
185 } 175 }
186 176
187 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data; 177 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data;
188 return 1; 178 return 1;
189 } 179 }
190 180
191 void SpdySM::OnStreamFrameData(SpdyStreamId stream_id, 181 void SpdySM::OnStreamFrameData(SpdyStreamId stream_id,
192 const char* data, 182 const char* data,
(...skipping 16 matching lines...) Expand all
209 199
210 void SpdySM::OnSynStream(SpdyStreamId stream_id, 200 void SpdySM::OnSynStream(SpdyStreamId stream_id,
211 SpdyStreamId associated_stream_id, 201 SpdyStreamId associated_stream_id,
212 SpdyPriority priority, 202 SpdyPriority priority,
213 uint8 credential_slot, 203 uint8 credential_slot,
214 bool fin, 204 bool fin,
215 bool unidirectional, 205 bool unidirectional,
216 const SpdyHeaderBlock& headers) { 206 const SpdyHeaderBlock& headers) {
217 std::string http_data; 207 std::string http_data;
218 bool is_https_scheme; 208 bool is_https_scheme;
219 int ret = SpdyHandleNewStream(stream_id, priority, headers, http_data, 209 int ret = SpdyHandleNewStream(
220 &is_https_scheme); 210 stream_id, priority, headers, http_data, &is_https_scheme);
221 if (!ret) { 211 if (!ret) {
222 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; 212 LOG(ERROR) << "SpdySM: Could not convert spdy into http.";
223 return; 213 return;
224 } 214 }
225 // We've seen a valid looking SYN_STREAM, consider this to have 215 // We've seen a valid looking SYN_STREAM, consider this to have
226 // been a real spdy session. 216 // been a real spdy session.
227 valid_spdy_session_ = true; 217 valid_spdy_session_ = true;
228 218
229 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { 219 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
230 std::string server_ip; 220 std::string server_ip;
231 std::string server_port; 221 std::string server_port;
232 if (is_https_scheme) { 222 if (is_https_scheme) {
233 server_ip = acceptor_->https_server_ip_; 223 server_ip = acceptor_->https_server_ip_;
234 server_port = acceptor_->https_server_port_; 224 server_port = acceptor_->https_server_port_;
235 } else { 225 } else {
236 server_ip = acceptor_->http_server_ip_; 226 server_ip = acceptor_->http_server_ip_;
237 server_port = acceptor_->http_server_port_; 227 server_port = acceptor_->http_server_port_;
238 } 228 }
239 SMInterface* sm_http_interface = 229 SMInterface* sm_http_interface =
240 FindOrMakeNewSMConnectionInterface(server_ip, server_port); 230 FindOrMakeNewSMConnectionInterface(server_ip, server_port);
241 stream_to_smif_[stream_id] = sm_http_interface; 231 stream_to_smif_[stream_id] = sm_http_interface;
242 sm_http_interface->SetStreamID(stream_id); 232 sm_http_interface->SetStreamID(stream_id);
243 sm_http_interface->ProcessWriteInput(http_data.c_str(), 233 sm_http_interface->ProcessWriteInput(http_data.c_str(), http_data.size());
244 http_data.size());
245 } 234 }
246 } 235 }
247 236
248 void SpdySM::OnSynReply(SpdyStreamId stream_id, 237 void SpdySM::OnSynReply(SpdyStreamId stream_id,
249 bool fin, 238 bool fin,
250 const SpdyHeaderBlock& headers) { 239 const SpdyHeaderBlock& headers) {
251 // TODO(willchan): if there is an error parsing headers, we 240 // TODO(willchan): if there is an error parsing headers, we
252 // should send a RST_STREAM. 241 // should send a RST_STREAM.
253 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSynReply(" 242 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSynReply(" << stream_id << ")";
254 << stream_id << ")";
255 } 243 }
256 244
257 void SpdySM::OnHeaders(SpdyStreamId stream_id, 245 void SpdySM::OnHeaders(SpdyStreamId stream_id,
258 bool fin, 246 bool fin,
259 const SpdyHeaderBlock& headers) { 247 const SpdyHeaderBlock& headers) {
260 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnHeaders(" 248 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnHeaders(" << stream_id << ")";
261 << stream_id << ")";
262 } 249 }
263 250
264 void SpdySM::OnRstStream(SpdyStreamId stream_id, 251 void SpdySM::OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) {
265 SpdyRstStreamStatus status) { 252 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnRstStream(" << stream_id
266 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnRstStream(" 253 << ")";
267 << stream_id << ")";
268 client_output_ordering_.RemoveStreamId(stream_id); 254 client_output_ordering_.RemoveStreamId(stream_id);
269 } 255 }
270 256
271 size_t SpdySM::ProcessReadInput(const char* data, size_t len) { 257 size_t SpdySM::ProcessReadInput(const char* data, size_t len) {
272 return buffered_spdy_framer_->ProcessInput(data, len); 258 return buffered_spdy_framer_->ProcessInput(data, len);
273 } 259 }
274 260
275 size_t SpdySM::ProcessWriteInput(const char* data, size_t len) { 261 size_t SpdySM::ProcessWriteInput(const char* data, size_t len) { return 0; }
276 return 0;
277 }
278 262
279 bool SpdySM::MessageFullyRead() const { 263 bool SpdySM::MessageFullyRead() const {
280 return buffered_spdy_framer_->MessageFullyRead(); 264 return buffered_spdy_framer_->MessageFullyRead();
281 } 265 }
282 266
283 bool SpdySM::Error() const { 267 bool SpdySM::Error() const {
284 return close_on_error_ || buffered_spdy_framer_->HasError(); 268 return close_on_error_ || buffered_spdy_framer_->HasError();
285 } 269 }
286 270
287 const char* SpdySM::ErrorAsString() const { 271 const char* SpdySM::ErrorAsString() const {
(...skipping 15 matching lines...) Expand all
303 valid_spdy_session_ = false; 287 valid_spdy_session_ = false;
304 client_output_ordering_.Reset(); 288 client_output_ordering_.Reset();
305 next_outgoing_stream_id_ = 2; 289 next_outgoing_stream_id_ = 2;
306 } 290 }
307 291
308 // Send a settings frame 292 // Send a settings frame
309 int SpdySM::PostAcceptHook() { 293 int SpdySM::PostAcceptHook() {
310 SettingsMap settings; 294 SettingsMap settings;
311 settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 295 settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
312 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 100); 296 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 100);
313 SpdyFrame* settings_frame = 297 SpdyFrame* settings_frame = buffered_spdy_framer_->CreateSettings(settings);
314 buffered_spdy_framer_->CreateSettings(settings);
315 298
316 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; 299 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame";
317 EnqueueDataFrame(new SpdyFrameDataFrame(settings_frame)); 300 EnqueueDataFrame(new SpdyFrameDataFrame(settings_frame));
318 return 1; 301 return 1;
319 } 302 }
320 303
321 void SpdySM::NewStream(uint32 stream_id, 304 void SpdySM::NewStream(uint32 stream_id,
322 uint32 priority, 305 uint32 priority,
323 const std::string& filename) { 306 const std::string& filename) {
324 MemCacheIter mci; 307 MemCacheIter mci;
(...skipping 12 matching lines...) Expand all
337 } 320 }
338 } else { 321 } else {
339 AddToOutputOrder(mci); 322 AddToOutputOrder(mci);
340 } 323 }
341 } 324 }
342 325
343 void SpdySM::AddToOutputOrder(const MemCacheIter& mci) { 326 void SpdySM::AddToOutputOrder(const MemCacheIter& mci) {
344 client_output_ordering_.AddToOutputOrder(mci); 327 client_output_ordering_.AddToOutputOrder(mci);
345 } 328 }
346 329
347 void SpdySM::SendEOF(uint32 stream_id) { 330 void SpdySM::SendEOF(uint32 stream_id) { SendEOFImpl(stream_id); }
348 SendEOFImpl(stream_id);
349 }
350 331
351 void SpdySM::SendErrorNotFound(uint32 stream_id) { 332 void SpdySM::SendErrorNotFound(uint32 stream_id) {
352 SendErrorNotFoundImpl(stream_id); 333 SendErrorNotFoundImpl(stream_id);
353 } 334 }
354 335
355 size_t SpdySM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) { 336 size_t SpdySM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) {
356 return SendSynStreamImpl(stream_id, headers); 337 return SendSynStreamImpl(stream_id, headers);
357 } 338 }
358 339
359 size_t SpdySM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { 340 size_t SpdySM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
360 return SendSynReplyImpl(stream_id, headers); 341 return SendSynReplyImpl(stream_id, headers);
361 } 342 }
362 343
363 void SpdySM::SendDataFrame(uint32 stream_id, const char* data, int64 len, 344 void SpdySM::SendDataFrame(uint32 stream_id,
364 uint32 flags, bool compress) { 345 const char* data,
346 int64 len,
347 uint32 flags,
348 bool compress) {
365 SpdyDataFlags spdy_flags = static_cast<SpdyDataFlags>(flags); 349 SpdyDataFlags spdy_flags = static_cast<SpdyDataFlags>(flags);
366 SendDataFrameImpl(stream_id, data, len, spdy_flags, compress); 350 SendDataFrameImpl(stream_id, data, len, spdy_flags, compress);
367 } 351 }
368 352
369 void SpdySM::SendEOFImpl(uint32 stream_id) { 353 void SpdySM::SendEOFImpl(uint32 stream_id) {
370 SendDataFrame(stream_id, NULL, 0, DATA_FLAG_FIN, false); 354 SendDataFrame(stream_id, NULL, 0, DATA_FLAG_FIN, false);
371 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending EOF: " << stream_id; 355 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending EOF: " << stream_id;
372 KillStream(stream_id); 356 KillStream(stream_id);
373 stream_to_smif_.erase(stream_id); 357 stream_to_smif_.erase(stream_id);
374 } 358 }
375 359
376 void SpdySM::SendErrorNotFoundImpl(uint32 stream_id) { 360 void SpdySM::SendErrorNotFoundImpl(uint32 stream_id) {
377 BalsaHeaders my_headers; 361 BalsaHeaders my_headers;
378 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); 362 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found");
379 SendSynReplyImpl(stream_id, my_headers); 363 SendSynReplyImpl(stream_id, my_headers);
380 SendDataFrame(stream_id, "wtf?", 4, DATA_FLAG_FIN, false); 364 SendDataFrame(stream_id, "wtf?", 4, DATA_FLAG_FIN, false);
381 client_output_ordering_.RemoveStreamId(stream_id); 365 client_output_ordering_.RemoveStreamId(stream_id);
382 } 366 }
383 367
384 void SpdySM::KillStream(uint32 stream_id) { 368 void SpdySM::KillStream(uint32 stream_id) {
385 client_output_ordering_.RemoveStreamId(stream_id); 369 client_output_ordering_.RemoveStreamId(stream_id);
386 } 370 }
387 371
388 void SpdySM::CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers) { 372 void SpdySM::CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers) {
389 for (BalsaHeaders::const_header_lines_iterator hi = 373 for (BalsaHeaders::const_header_lines_iterator hi =
390 headers.header_lines_begin(); 374 headers.header_lines_begin();
391 hi != headers.header_lines_end(); 375 hi != headers.header_lines_end();
392 ++hi) { 376 ++hi) {
393 // It is illegal to send SPDY headers with empty value or header 377 // It is illegal to send SPDY headers with empty value or header
394 // names. 378 // names.
395 if (!hi->first.length() || !hi->second.length()) 379 if (!hi->first.length() || !hi->second.length())
396 continue; 380 continue;
397 381
398 // Key must be all lower case in SPDY headers. 382 // Key must be all lower case in SPDY headers.
399 std::string key = hi->first.as_string(); 383 std::string key = hi->first.as_string();
400 std::transform(key.begin(), key.end(), key.begin(), ::tolower); 384 std::transform(key.begin(), key.end(), key.begin(), ::tolower);
401 SpdyHeaderBlock::iterator fhi = dest.find(key); 385 SpdyHeaderBlock::iterator fhi = dest.find(key);
402 if (fhi == dest.end()) { 386 if (fhi == dest.end()) {
403 dest[key] = hi->second.as_string(); 387 dest[key] = hi->second.as_string();
404 } else { 388 } else {
405 dest[key] = ( 389 dest[key] = (std::string(fhi->second.data(), fhi->second.size()) + "\0" +
406 std::string(fhi->second.data(), fhi->second.size()) + "\0" + 390 std::string(hi->second.data(), hi->second.size()));
407 std::string(hi->second.data(), hi->second.size()));
408 } 391 }
409 } 392 }
410 393
411 // These headers have no value 394 // These headers have no value
412 dest.erase("X-Associated-Content"); // TODO(mbelshe): case-sensitive 395 dest.erase("X-Associated-Content"); // TODO(mbelshe): case-sensitive
413 dest.erase("X-Original-Url"); // TODO(mbelshe): case-sensitive 396 dest.erase("X-Original-Url"); // TODO(mbelshe): case-sensitive
414 } 397 }
415 398
416 size_t SpdySM::SendSynStreamImpl(uint32 stream_id, 399 size_t SpdySM::SendSynStreamImpl(uint32 stream_id,
417 const BalsaHeaders& headers) { 400 const BalsaHeaders& headers) {
418 SpdyHeaderBlock block; 401 SpdyHeaderBlock block;
419 block["method"] = headers.request_method().as_string(); 402 block["method"] = headers.request_method().as_string();
420 if (!headers.HasHeader("version")) 403 if (!headers.HasHeader("version"))
421 block["version"] =headers.request_version().as_string(); 404 block["version"] = headers.request_version().as_string();
422 if (headers.HasHeader("X-Original-Url")) { 405 if (headers.HasHeader("X-Original-Url")) {
423 std::string original_url = headers.GetHeader("X-Original-Url").as_string(); 406 std::string original_url = headers.GetHeader("X-Original-Url").as_string();
424 block["url"] = UrlUtilities::GetUrlPath(original_url); 407 block["url"] = UrlUtilities::GetUrlPath(original_url);
425 } else { 408 } else {
426 block["url"] = headers.request_uri().as_string(); 409 block["url"] = headers.request_uri().as_string();
427 } 410 }
428 CopyHeaders(block, headers); 411 CopyHeaders(block, headers);
429 412
430 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynStream( 413 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynStream(
431 stream_id, 0, 0, 0, CONTROL_FLAG_NONE, &block); 414 stream_id, 0, 0, 0, CONTROL_FLAG_NONE, &block);
(...skipping 15 matching lines...) Expand all
447 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply( 430 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply(
448 stream_id, CONTROL_FLAG_NONE, &block); 431 stream_id, CONTROL_FLAG_NONE, &block);
449 size_t df_size = fsrcf->size(); 432 size_t df_size = fsrcf->size();
450 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf)); 433 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf));
451 434
452 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader " 435 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader "
453 << stream_id; 436 << stream_id;
454 return df_size; 437 return df_size;
455 } 438 }
456 439
457 void SpdySM::SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, 440 void SpdySM::SendDataFrameImpl(uint32 stream_id,
458 SpdyDataFlags flags, bool compress) { 441 const char* data,
442 int64 len,
443 SpdyDataFlags flags,
444 bool compress) {
459 // TODO(mbelshe): We can't compress here - before going into the 445 // TODO(mbelshe): We can't compress here - before going into the
460 // priority queue. Compression needs to be done 446 // priority queue. Compression needs to be done
461 // with late binding. 447 // with late binding.
462 if (len == 0) { 448 if (len == 0) {
463 SpdyFrame* fdf = buffered_spdy_framer_->CreateDataFrame( 449 SpdyFrame* fdf =
464 stream_id, data, len, flags); 450 buffered_spdy_framer_->CreateDataFrame(stream_id, data, len, flags);
465 EnqueueDataFrame(new SpdyFrameDataFrame(fdf)); 451 EnqueueDataFrame(new SpdyFrameDataFrame(fdf));
466 return; 452 return;
467 } 453 }
468 454
469 // Chop data frames into chunks so that one stream can't monopolize the 455 // Chop data frames into chunks so that one stream can't monopolize the
470 // output channel. 456 // output channel.
471 while (len > 0) { 457 while (len > 0) {
472 int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize)); 458 int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize));
473 SpdyDataFlags chunk_flags = flags; 459 SpdyDataFlags chunk_flags = flags;
474 460
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 mci->transformed_header = true; 492 mci->transformed_header = true;
507 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput transformed " 493 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput transformed "
508 << "header stream_id: [" << mci->stream_id << "]"; 494 << "header stream_id: [" << mci->stream_id << "]";
509 if ((mci->stream_id % 2) == 0) { 495 if ((mci->stream_id % 2) == 0) {
510 // this is a server initiated stream. 496 // this is a server initiated stream.
511 // Ideally, we'd do a 'syn-push' here, instead of a syn-reply. 497 // Ideally, we'd do a 'syn-push' here, instead of a syn-reply.
512 BalsaHeaders headers; 498 BalsaHeaders headers;
513 headers.CopyFrom(*(mci->file_data->headers())); 499 headers.CopyFrom(*(mci->file_data->headers()));
514 headers.ReplaceOrAppendHeader("status", "200"); 500 headers.ReplaceOrAppendHeader("status", "200");
515 headers.ReplaceOrAppendHeader("version", "http/1.1"); 501 headers.ReplaceOrAppendHeader("version", "http/1.1");
516 headers.SetRequestFirstlineFromStringPieces("PUSH", 502 headers.SetRequestFirstlineFromStringPieces(
517 mci->file_data->filename(), 503 "PUSH", mci->file_data->filename(), "");
518 "");
519 mci->bytes_sent = SendSynStream(mci->stream_id, headers); 504 mci->bytes_sent = SendSynStream(mci->stream_id, headers);
520 } else { 505 } else {
521 BalsaHeaders headers; 506 BalsaHeaders headers;
522 headers.CopyFrom(*(mci->file_data->headers())); 507 headers.CopyFrom(*(mci->file_data->headers()));
523 mci->bytes_sent = SendSynReply(mci->stream_id, headers); 508 mci->bytes_sent = SendSynReply(mci->stream_id, headers);
524 } 509 }
525 return; 510 return;
526 } 511 }
527 if (mci->body_bytes_consumed >= mci->file_data->body().size()) { 512 if (mci->body_bytes_consumed >= mci->file_data->body().size()) {
528 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput " 513 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput "
(...skipping 11 matching lines...) Expand all
540 if (mci->file_data->headers()->HasHeader("content-type")) { 525 if (mci->file_data->headers()->HasHeader("content-type")) {
541 std::string content_type = 526 std::string content_type =
542 mci->file_data->headers()->GetHeader("content-type").as_string(); 527 mci->file_data->headers()->GetHeader("content-type").as_string();
543 if (content_type.find("image") == content_type.npos) 528 if (content_type.find("image") == content_type.npos)
544 should_compress = true; 529 should_compress = true;
545 } 530 }
546 } 531 }
547 532
548 SendDataFrame(mci->stream_id, 533 SendDataFrame(mci->stream_id,
549 mci->file_data->body().data() + mci->body_bytes_consumed, 534 mci->file_data->body().data() + mci->body_bytes_consumed,
550 num_to_write, 0, should_compress); 535 num_to_write,
536 0,
537 should_compress);
551 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput SendDataFrame[" 538 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: GetOutput SendDataFrame["
552 << mci->stream_id << "]: " << num_to_write; 539 << mci->stream_id << "]: " << num_to_write;
553 mci->body_bytes_consumed += num_to_write; 540 mci->body_bytes_consumed += num_to_write;
554 mci->bytes_sent += num_to_write; 541 mci->bytes_sent += num_to_write;
555 } 542 }
556 } 543 }
557 544
558 } // namespace net 545 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698