| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/linked_ptr.h" | 8 #include "base/linked_ptr.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 write_callback_(this, &SpdySession::OnWriteComplete)), | 146 write_callback_(this, &SpdySession::OnWriteComplete)), |
| 147 host_port_pair_(host_port_pair), | 147 host_port_pair_(host_port_pair), |
| 148 session_(session), | 148 session_(session), |
| 149 connection_(new ClientSocketHandle), | 149 connection_(new ClientSocketHandle), |
| 150 read_buffer_(new IOBuffer(kReadBufferSize)), | 150 read_buffer_(new IOBuffer(kReadBufferSize)), |
| 151 read_pending_(false), | 151 read_pending_(false), |
| 152 stream_hi_water_mark_(1), // Always start at 1 for the first stream id. | 152 stream_hi_water_mark_(1), // Always start at 1 for the first stream id. |
| 153 write_pending_(false), | 153 write_pending_(false), |
| 154 delayed_write_pending_(false), | 154 delayed_write_pending_(false), |
| 155 is_secure_(false), | 155 is_secure_(false), |
| 156 certificate_error_code_(OK), |
| 156 error_(OK), | 157 error_(OK), |
| 157 state_(IDLE), | 158 state_(IDLE), |
| 158 streams_initiated_count_(0), | 159 streams_initiated_count_(0), |
| 159 streams_pushed_count_(0), | 160 streams_pushed_count_(0), |
| 160 streams_pushed_and_claimed_count_(0), | 161 streams_pushed_and_claimed_count_(0), |
| 161 streams_abandoned_count_(0), | 162 streams_abandoned_count_(0), |
| 162 sent_settings_(false), | 163 sent_settings_(false), |
| 163 received_settings_(false), | 164 received_settings_(false), |
| 164 in_session_pool_(true), | 165 in_session_pool_(true), |
| 165 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { | 166 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 184 // With Spdy we can't recycle sockets. | 185 // With Spdy we can't recycle sockets. |
| 185 connection_->socket()->Disconnect(); | 186 connection_->socket()->Disconnect(); |
| 186 } | 187 } |
| 187 | 188 |
| 188 RecordHistograms(); | 189 RecordHistograms(); |
| 189 | 190 |
| 190 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION, NULL); | 191 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION, NULL); |
| 191 } | 192 } |
| 192 | 193 |
| 193 net::Error SpdySession::InitializeWithSSLSocket( | 194 net::Error SpdySession::InitializeWithSSLSocket( |
| 194 ClientSocketHandle* connection) { | 195 ClientSocketHandle* connection, |
| 196 int certificate_error_code) { |
| 195 static StatsCounter spdy_sessions("spdy.sessions"); | 197 static StatsCounter spdy_sessions("spdy.sessions"); |
| 196 spdy_sessions.Increment(); | 198 spdy_sessions.Increment(); |
| 197 | 199 |
| 198 AdjustSocketBufferSizes(connection->socket()); | 200 AdjustSocketBufferSizes(connection->socket()); |
| 199 | 201 |
| 200 state_ = CONNECTED; | 202 state_ = CONNECTED; |
| 201 connection_.reset(connection); | 203 connection_.reset(connection); |
| 202 is_secure_ = true; // |connection| contains an SSLClientSocket. | 204 is_secure_ = true; // |connection| contains an SSLClientSocket. |
| 205 certificate_error_code_ = certificate_error_code; |
| 203 | 206 |
| 204 // This is a newly initialized session that no client should have a handle to | 207 // This is a newly initialized session that no client should have a handle to |
| 205 // yet, so there's no need to start writing data as in OnTCPConnect(), but we | 208 // yet, so there's no need to start writing data as in OnTCPConnect(), but we |
| 206 // should start reading data. | 209 // should start reading data. |
| 207 net::Error error = ReadSocket(); | 210 net::Error error = ReadSocket(); |
| 208 if (error == ERR_IO_PENDING) | 211 if (error == ERR_IO_PENDING) |
| 209 return OK; | 212 return OK; |
| 210 return error; | 213 return error; |
| 211 } | 214 } |
| 212 | 215 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 230 DCHECK(rv <= 0); | 233 DCHECK(rv <= 0); |
| 231 | 234 |
| 232 // If the connect is pending, we still return ok. The APIs enqueue | 235 // If the connect is pending, we still return ok. The APIs enqueue |
| 233 // work until after the connect completes asynchronously later. | 236 // work until after the connect completes asynchronously later. |
| 234 if (rv == net::ERR_IO_PENDING) | 237 if (rv == net::ERR_IO_PENDING) |
| 235 return net::OK; | 238 return net::OK; |
| 236 OnTCPConnect(rv); | 239 OnTCPConnect(rv); |
| 237 return static_cast<net::Error>(rv); | 240 return static_cast<net::Error>(rv); |
| 238 } | 241 } |
| 239 | 242 |
| 240 scoped_refptr<SpdyStream> SpdySession::GetPushStream( | 243 int SpdySession::GetPushStream( |
| 241 const GURL& url, | 244 const GURL& url, |
| 245 scoped_refptr<SpdyStream>* stream, |
| 242 const BoundNetLog& stream_net_log) { | 246 const BoundNetLog& stream_net_log) { |
| 243 CHECK_NE(state_, CLOSED); | 247 CHECK_NE(state_, CLOSED); |
| 248 |
| 249 *stream = NULL; |
| 250 |
| 251 // Don't allow access to secure push streams over an unauthenticated, but |
| 252 // encrypted SSL socket. |
| 253 if (is_secure_ && certificate_error_code_ != OK && |
| 254 (url.SchemeIs("https") || url.SchemeIs("wss"))) { |
| 255 LOG(DFATAL) << "Tried to get pushed spdy stream for secure content over an " |
| 256 << "unauthenticated session."; |
| 257 return certificate_error_code_; |
| 258 } |
| 259 |
| 244 const std::string& path = url.PathForRequest(); | 260 const std::string& path = url.PathForRequest(); |
| 245 | 261 |
| 246 scoped_refptr<SpdyStream> stream = GetActivePushStream(path); | 262 *stream = GetActivePushStream(path); |
| 247 if (stream) { | 263 if (stream->get()) { |
| 248 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); | 264 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); |
| 249 streams_pushed_and_claimed_count_++; | 265 streams_pushed_and_claimed_count_++; |
| 250 return stream; | 266 return OK; |
| 251 } | 267 } |
| 252 | 268 |
| 253 // Check if we have a pending push stream for this url. | 269 // Check if we have a pending push stream for this url. |
| 254 // Note that we shouldn't have a pushed stream for non-GET method. | 270 // Note that we shouldn't have a pushed stream for non-GET method. |
| 255 PendingStreamMap::iterator it; | 271 PendingStreamMap::iterator it; |
| 256 it = pending_streams_.find(path); | 272 it = pending_streams_.find(path); |
| 257 if (it != pending_streams_.end()) { | 273 if (it != pending_streams_.end()) { |
| 258 // Server has advertised a stream, but not yet sent it. | 274 // Server has advertised a stream, but not yet sent it. |
| 259 DCHECK(!it->second); | 275 DCHECK(!it->second); |
| 260 // Server will assign a stream id when the push stream arrives. Use 0 for | 276 // Server will assign a stream id when the push stream arrives. Use 0 for |
| 261 // now. | 277 // now. |
| 262 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM, NULL); | 278 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM, NULL); |
| 263 stream = new SpdyStream(this, 0, true); | 279 *stream = new SpdyStream(this, 0, true); |
| 264 stream->set_path(path); | 280 (*stream)->set_path(path); |
| 265 stream->set_net_log(stream_net_log); | 281 (*stream)->set_net_log(stream_net_log); |
| 266 it->second = stream; | 282 it->second = *stream; |
| 267 return stream; | 283 return OK; |
| 268 } | 284 } |
| 269 return NULL; | 285 return OK; |
| 270 } | 286 } |
| 271 | 287 |
| 272 const scoped_refptr<SpdyStream>& SpdySession::CreateStream( | 288 int SpdySession::CreateStream( |
| 273 const GURL& url, | 289 const GURL& url, |
| 274 RequestPriority priority, | 290 RequestPriority priority, |
| 291 scoped_refptr<SpdyStream>* spdy_stream, |
| 275 const BoundNetLog& stream_net_log) { | 292 const BoundNetLog& stream_net_log) { |
| 293 // Make sure that we don't try to send https/wss over an unauthenticated, but |
| 294 // encrypted SSL socket. |
| 295 if (is_secure_ && certificate_error_code_ != OK && |
| 296 (url.SchemeIs("https") || url.SchemeIs("wss"))) { |
| 297 LOG(DFATAL) << "Tried to create spdy stream for secure content over an " |
| 298 << "unauthenticated session."; |
| 299 return certificate_error_code_; |
| 300 } |
| 301 |
| 276 const std::string& path = url.PathForRequest(); | 302 const std::string& path = url.PathForRequest(); |
| 277 | 303 |
| 278 const spdy::SpdyStreamId stream_id = GetNewStreamId(); | 304 const spdy::SpdyStreamId stream_id = GetNewStreamId(); |
| 279 | 305 |
| 280 scoped_refptr<SpdyStream> stream(new SpdyStream(this, stream_id, false)); | 306 *spdy_stream = new SpdyStream(this, stream_id, false); |
| 307 const scoped_refptr<SpdyStream>& stream = *spdy_stream; |
| 281 | 308 |
| 282 stream->set_priority(priority); | 309 stream->set_priority(priority); |
| 283 stream->set_path(path); | 310 stream->set_path(path); |
| 284 stream->set_net_log(stream_net_log); | 311 stream->set_net_log(stream_net_log); |
| 285 ActivateStream(stream); | 312 ActivateStream(stream); |
| 286 | 313 |
| 287 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", | 314 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", |
| 288 static_cast<int>(priority), 0, 10, 11); | 315 static_cast<int>(priority), 0, 10, 11); |
| 289 | 316 |
| 290 LOG(INFO) << "SpdyStream: Creating stream " << stream_id << " for " << url; | 317 LOG(INFO) << "SpdyStream: Creating stream " << stream_id << " for " << url; |
| 291 // TODO(mbelshe): Optimize memory allocations | 318 // TODO(mbelshe): Optimize memory allocations |
| 292 DCHECK(priority >= SPDY_PRIORITY_HIGHEST && | 319 DCHECK(priority >= SPDY_PRIORITY_HIGHEST && |
| 293 priority <= SPDY_PRIORITY_LOWEST); | 320 priority <= SPDY_PRIORITY_LOWEST); |
| 294 | 321 |
| 295 DCHECK_EQ(active_streams_[stream_id].get(), stream.get()); | 322 DCHECK_EQ(active_streams_[stream_id].get(), stream.get()); |
| 296 return active_streams_[stream_id]; | 323 return OK; |
| 297 } | 324 } |
| 298 | 325 |
| 299 int SpdySession::WriteSynStream( | 326 int SpdySession::WriteSynStream( |
| 300 spdy::SpdyStreamId stream_id, | 327 spdy::SpdyStreamId stream_id, |
| 301 RequestPriority priority, | 328 RequestPriority priority, |
| 302 spdy::SpdyControlFlags flags, | 329 spdy::SpdyControlFlags flags, |
| 303 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 330 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 304 // Find our stream | 331 // Find our stream |
| 305 if (!IsStreamActive(stream_id)) | 332 if (!IsStreamActive(stream_id)) |
| 306 return ERR_INVALID_SPDY_STREAM; | 333 return ERR_INVALID_SPDY_STREAM; |
| (...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", | 1188 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", |
| 1162 setting.second, | 1189 setting.second, |
| 1163 1, 100, 50); | 1190 1, 100, 50); |
| 1164 break; | 1191 break; |
| 1165 } | 1192 } |
| 1166 } | 1193 } |
| 1167 } | 1194 } |
| 1168 } | 1195 } |
| 1169 | 1196 |
| 1170 } // namespace net | 1197 } // namespace net |
| OLD | NEW |