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 // A toy server specific QuicSession subclass. | 5 // A toy server specific QuicSession subclass. |
6 | 6 |
7 #ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_ | 7 #ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_ |
8 #define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_ | 8 #define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_ |
9 | 9 |
10 #include <stdint.h> | 10 #include <stdint.h> |
11 | 11 |
12 #include <set> | 12 #include <set> |
13 #include <string> | 13 #include <string> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/containers/hash_tables.h" | 16 #include "base/containers/hash_tables.h" |
17 #include "base/macros.h" | 17 #include "base/macros.h" |
18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
19 #include "net/quic/quic_crypto_server_stream.h" | 19 #include "net/quic/quic_crypto_server_stream.h" |
20 #include "net/quic/quic_protocol.h" | 20 #include "net/quic/quic_protocol.h" |
21 #include "net/quic/quic_spdy_session.h" | 21 #include "net/quic/quic_spdy_session.h" |
| 22 #include "net/tools/quic/quic_in_memory_cache.h" |
22 #include "net/tools/quic/quic_server_session_base.h" | 23 #include "net/tools/quic/quic_server_session_base.h" |
23 #include "net/tools/quic/quic_simple_server_stream.h" | 24 #include "net/tools/quic/quic_simple_server_stream.h" |
24 | 25 |
25 namespace net { | 26 namespace net { |
26 | 27 |
27 class QuicBlockedWriterInterface; | 28 class QuicBlockedWriterInterface; |
28 class QuicConfig; | 29 class QuicConfig; |
29 class QuicConnection; | 30 class QuicConnection; |
30 class QuicCryptoServerConfig; | 31 class QuicCryptoServerConfig; |
31 class ReliableQuicStream; | 32 class ReliableQuicStream; |
32 | 33 |
33 namespace tools { | 34 namespace tools { |
34 | 35 |
35 namespace test { | 36 namespace test { |
36 class QuicSimpleServerSessionPeer; | 37 class QuicSimpleServerSessionPeer; |
37 } // namespace test | 38 } // namespace test |
38 | 39 |
39 class QuicSimpleServerSession : public QuicServerSessionBase { | 40 class QuicSimpleServerSession : public QuicServerSessionBase { |
40 public: | 41 public: |
| 42 // A PromisedStreamInfo is an element of the queue to store promised |
| 43 // stream which hasn't been created yet. It keeps a mapping between promised |
| 44 // stream id with its priority and the headers sent out in PUSH_PROMISE. |
| 45 struct PromisedStreamInfo { |
| 46 public: |
| 47 PromisedStreamInfo(SpdyHeaderBlock request_headers, |
| 48 QuicStreamId stream_id, |
| 49 SpdyPriority priority) |
| 50 : request_headers(request_headers), |
| 51 stream_id(stream_id), |
| 52 priority(priority), |
| 53 is_cancelled(false) {} |
| 54 SpdyHeaderBlock request_headers; |
| 55 QuicStreamId stream_id; |
| 56 SpdyPriority priority; |
| 57 bool is_cancelled; |
| 58 }; |
| 59 |
41 QuicSimpleServerSession(const QuicConfig& config, | 60 QuicSimpleServerSession(const QuicConfig& config, |
42 QuicConnection* connection, | 61 QuicConnection* connection, |
43 QuicServerSessionVisitor* visitor, | 62 QuicServerSessionVisitor* visitor, |
44 const QuicCryptoServerConfig* crypto_config); | 63 const QuicCryptoServerConfig* crypto_config); |
45 | 64 |
46 ~QuicSimpleServerSession() override; | 65 ~QuicSimpleServerSession() override; |
47 | 66 |
| 67 // When a stream is marked draining, it will decrease the number of open |
| 68 // streams. If it is an outgoing stream, try to open a new stream to send |
| 69 // remaing push responses. |
| 70 void StreamDraining(QuicStreamId id) override; |
| 71 |
| 72 // Override base class to detact client sending data on server push stream. |
| 73 void OnStreamFrame(const QuicStreamFrame& frame) override; |
| 74 |
| 75 // Send out PUSH_PROMISE for all |resources| promised stream id in each frame |
| 76 // will increase by 2 for each item in |resources|. |
| 77 // And enqueue HEADERS block in those PUSH_PROMISED for sending push response |
| 78 // later. |
| 79 virtual void PromisePushResources( |
| 80 const string& request_url, |
| 81 const list<QuicInMemoryCache::ServerPushInfo>& resources, |
| 82 QuicStreamId original_stream_id, |
| 83 const SpdyHeaderBlock& original_request_headers); |
| 84 |
48 protected: | 85 protected: |
49 // QuicSession methods: | 86 // QuicSession methods: |
50 QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override; | 87 QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override; |
51 QuicSimpleServerStream* CreateOutgoingDynamicStream( | 88 QuicSimpleServerStream* CreateOutgoingDynamicStream( |
52 SpdyPriority priority) override; | 89 SpdyPriority priority) override; |
| 90 // Closing an outgoing stream can reduce open outgoing stream count, try |
| 91 // to handle queued promised streams right now. |
| 92 void CloseStreamInner(QuicStreamId stream_id, bool locally_reset) override; |
| 93 // Override to return true for locally preserved server push stream. |
| 94 void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override; |
| 95 // Override to handle reseting locally preserved streams. |
| 96 void HandleRstOnValidNonexistentStream( |
| 97 const QuicRstStreamFrame& frame) override; |
53 | 98 |
| 99 // QuicServerSessionBaseMethod: |
54 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( | 100 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( |
55 const QuicCryptoServerConfig* crypto_config) override; | 101 const QuicCryptoServerConfig* crypto_config) override; |
56 | 102 |
57 private: | 103 private: |
58 friend class test::QuicSimpleServerSessionPeer; | 104 friend class test::QuicSimpleServerSessionPeer; |
59 | 105 |
| 106 // Create a server push headers block by copying request's headers block. |
| 107 // But replace or add these pseudo-headers as they are specific to each |
| 108 // request: |
| 109 // :authority, :path, :method, :scheme, referer. |
| 110 // Copying the rest headers ensures they are the same as the original |
| 111 // request, especially cookies. |
| 112 SpdyHeaderBlock SynthesizePushRequestHeaders( |
| 113 string request_url, |
| 114 QuicInMemoryCache::ServerPushInfo resource, |
| 115 const SpdyHeaderBlock& original_request_headers); |
| 116 |
| 117 // Send PUSH_PROMISE frame on headers stream. |
| 118 void SendPushPromise(QuicStreamId original_stream_id, |
| 119 QuicStreamId promised_stream_id, |
| 120 const SpdyHeaderBlock& headers); |
| 121 |
| 122 // Fetch response from cache for request headers enqueued into |
| 123 // promised_headers_and_streams_ and send them on dedicated stream until |
| 124 // reaches max_open_stream_ limit. |
| 125 // Called when return value of GetNumOpenOutgoingStreams() changes: |
| 126 // CloseStreamInner(); |
| 127 // StreamDraining(); |
| 128 // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the |
| 129 // return value becasue all push streams are impossible to become locally |
| 130 // closed. Since a locally preserved stream becomes remotely closed after |
| 131 // HandlePromisedPushRequests() starts to process it, and if it is reset |
| 132 // locally afterwards, it will be immediately become closed and never get into |
| 133 // locally_closed_stream_highest_offset_. So all the streams in this map |
| 134 // are not outgoing streams. |
| 135 void HandlePromisedPushRequests(); |
| 136 |
| 137 // Keep track of the highest stream id which has been sent in PUSH_PROMISE. |
| 138 QuicStreamId highest_promised_stream_id_; |
| 139 |
| 140 // Promised streams which hasn't been created yet because of max_open_stream_ |
| 141 // limit. New element is added to the end of the queue. |
| 142 // Since outgoing stream is created in sequence, stream_id of each element in |
| 143 // the queue also increases by 2 from previous one's. The front element's |
| 144 // stream_id is always next_outgoing_stream_id_, and the last one is always |
| 145 // highest_promised_stream_id_. |
| 146 std::deque<PromisedStreamInfo> promised_streams_; |
| 147 |
60 DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerSession); | 148 DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerSession); |
61 }; | 149 }; |
62 | 150 |
63 } // namespace tools | 151 } // namespace tools |
64 } // namespace net | 152 } // namespace net |
65 | 153 |
66 #endif // NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_ | 154 #endif // NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_ |
OLD | NEW |