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

Side by Side Diff: net/quic/quic_client_session_base.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months 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
« no previous file with comments | « net/quic/quic_client_session_base.h ('k') | net/quic/quic_clock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/quic/quic_client_session_base.h"
6
7 #include "net/quic/quic_client_promised_info.h"
8 #include "net/quic/quic_flags.h"
9 #include "net/quic/spdy_utils.h"
10
11 using base::StringPiece;
12 using std::string;
13
14 namespace net {
15
16 QuicClientSessionBase::QuicClientSessionBase(
17 QuicConnection* connection,
18 QuicClientPushPromiseIndex* push_promise_index,
19 const QuicConfig& config)
20 : QuicSpdySession(connection, config),
21 push_promise_index_(push_promise_index),
22 largest_promised_stream_id_(kInvalidStreamId) {}
23
24 QuicClientSessionBase::~QuicClientSessionBase() {
25 // all promised streams for this session
26 for (auto& it : promised_by_id_) {
27 DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
28 push_promise_index_->promised_by_url()->erase(it.second->url());
29 }
30 }
31
32 void QuicClientSessionBase::OnConfigNegotiated() {
33 QuicSpdySession::OnConfigNegotiated();
34 }
35
36 void QuicClientSessionBase::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
37 QuicSession::OnCryptoHandshakeEvent(event);
38 }
39
40 void QuicClientSessionBase::OnPromiseHeaders(QuicStreamId stream_id,
41 StringPiece headers_data) {
42 QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
43 if (!stream) {
44 // It's quite possible to receive headers after a stream has been reset.
45 return;
46 }
47 stream->OnPromiseHeaders(headers_data);
48 }
49
50 void QuicClientSessionBase::OnInitialHeadersComplete(
51 QuicStreamId stream_id,
52 const SpdyHeaderBlock& response_headers) {
53 // Note that the strong ordering of the headers stream means that
54 // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
55 // been called (on the associated stream) if this is a promised
56 // stream. However, this stream may not have existed at this time,
57 // hence the need to query the session.
58 QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
59 if (!promised)
60 return;
61
62 promised->OnResponseHeaders(response_headers);
63 }
64
65 void QuicClientSessionBase::OnPromiseHeadersComplete(
66 QuicStreamId stream_id,
67 QuicStreamId promised_stream_id,
68 size_t frame_len) {
69 if (promised_stream_id != kInvalidStreamId &&
70 promised_stream_id <= largest_promised_stream_id_) {
71 connection()->CloseConnection(
72 QUIC_INVALID_STREAM_ID,
73 "Received push stream id lesser or equal to the"
74 " last accepted before",
75 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
76 return;
77 }
78 largest_promised_stream_id_ = promised_stream_id;
79
80 QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
81 if (!stream) {
82 // It's quite possible to receive headers after a stream has been reset.
83 return;
84 }
85 stream->OnPromiseHeadersComplete(promised_stream_id, frame_len);
86 }
87
88 void QuicClientSessionBase::OnPromiseHeaderList(
89 QuicStreamId stream_id,
90 QuicStreamId promised_stream_id,
91 size_t frame_len,
92 const QuicHeaderList& header_list) {
93 if (promised_stream_id != kInvalidStreamId &&
94 promised_stream_id <= largest_promised_stream_id_) {
95 connection()->CloseConnection(
96 QUIC_INVALID_STREAM_ID,
97 "Received push stream id lesser or equal to the"
98 " last accepted before",
99 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
100 return;
101 }
102 largest_promised_stream_id_ = promised_stream_id;
103
104 QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
105 if (!stream) {
106 // It's quite possible to receive headers after a stream has been reset.
107 return;
108 }
109 stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
110 }
111
112 void QuicClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
113 QuicStreamId id,
114 const SpdyHeaderBlock& headers) {
115 // Due to pathalogical packet re-ordering, it is possible that
116 // frames for the promised stream have already arrived, and the
117 // promised stream could be active or closed.
118 if (IsClosedStream(id)) {
119 // There was a RST on the data stream already, perhaps
120 // QUIC_REFUSED_STREAM?
121 DVLOG(1) << "Promise ignored for stream " << id
122 << " that is already closed";
123 return;
124 }
125
126 if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
127 DVLOG(1) << "Too many promises, rejecting promise for stream " << id;
128 ResetPromised(id, QUIC_REFUSED_STREAM);
129 return;
130 }
131
132 const string url = SpdyUtils::GetUrlFromHeaderBlock(headers);
133 QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
134 if (old_promised) {
135 DVLOG(1) << "Promise for stream " << id << " is duplicate URL " << url
136 << " of previous promise for stream " << old_promised->id();
137 ResetPromised(id, QUIC_DUPLICATE_PROMISE_URL);
138 return;
139 }
140
141 if (GetPromisedById(id)) {
142 // OnPromiseHeadersComplete() would have closed the connection if
143 // promised id is a duplicate.
144 QUIC_BUG << "Duplicate promise for id " << id;
145 return;
146 }
147
148 QuicClientPromisedInfo* promised = new QuicClientPromisedInfo(this, id, url);
149 std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
150 promised->Init();
151 DVLOG(1) << "stream " << id << " emplace url " << url;
152 (*push_promise_index_->promised_by_url())[url] = promised;
153 promised_by_id_[id] = std::move(promised_owner);
154 promised->OnPromiseHeaders(headers);
155 }
156
157 QuicClientPromisedInfo* QuicClientSessionBase::GetPromisedByUrl(
158 const string& url) {
159 QuicPromisedByUrlMap::iterator it =
160 push_promise_index_->promised_by_url()->find(url);
161 if (it != push_promise_index_->promised_by_url()->end()) {
162 return it->second;
163 }
164 return nullptr;
165 }
166
167 QuicClientPromisedInfo* QuicClientSessionBase::GetPromisedById(
168 const QuicStreamId id) {
169 QuicPromisedByIdMap::iterator it = promised_by_id_.find(id);
170 if (it != promised_by_id_.end()) {
171 return it->second.get();
172 }
173 return nullptr;
174 }
175
176 QuicSpdyStream* QuicClientSessionBase::GetPromisedStream(
177 const QuicStreamId id) {
178 if (IsClosedStream(id)) {
179 return nullptr;
180 }
181 DynamicStreamMap::iterator it = dynamic_streams().find(id);
182 if (it != dynamic_streams().end()) {
183 return static_cast<QuicSpdyStream*>(it->second);
184 }
185 QUIC_BUG << "Open promised stream " << id << " is missing!";
186 return nullptr;
187 }
188
189 void QuicClientSessionBase::DeletePromised(QuicClientPromisedInfo* promised) {
190 push_promise_index_->promised_by_url()->erase(promised->url());
191 // Since promised_by_id_ contains the unique_ptr, this will destroy
192 // promised.
193 promised_by_id_.erase(promised->id());
194 }
195
196 void QuicClientSessionBase::ResetPromised(QuicStreamId id,
197 QuicRstStreamErrorCode error_code) {
198 SendRstStream(id, error_code, 0);
199 if (!IsOpenStream(id)) {
200 MaybeIncreaseLargestPeerStreamId(id);
201 InsertLocallyClosedStreamsHighestOffset(id, 0);
202 }
203 }
204
205 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_client_session_base.h ('k') | net/quic/quic_clock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698