blob: 58c7d65be583aeb6f15cb06c84c6b2d852e8a5ad [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/macros.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_spdy_session.h"
namespace net {
class QuicClientPromisedInfo;
class QuicClientPushPromiseIndex;
class QuicSpdyClientStream;
// For client/http layer code. Lookup promised streams based on
// matching promised request url. The same map can be shared across
// multiple sessions, since cross-origin pushes are allowed (subject
// to authority constraints). Clients should use this map to enforce
// session affinity for requests corresponding to cross-origin push
// promised streams.
using QuicPromisedByUrlMap =
std::unordered_map<std::string, QuicClientPromisedInfo*>;
// The maximum time a promises stream can be reserved without being
// claimed by a client request.
const int64_t kPushPromiseTimeoutSecs = 60;
// Base class for all client-specific QuicSession subclasses.
class NET_EXPORT_PRIVATE QuicClientSessionBase
: public QuicSpdySession,
public QuicCryptoClientStream::ProofHandler {
// Caller retains ownership of |promised_by_url|.
QuicClientSessionBase(QuicConnection* connection,
QuicClientPushPromiseIndex* push_promise_index,
const QuicConfig& config);
~QuicClientSessionBase() override;
// Override base class to set FEC policy before any data is sent by client.
void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
// Called by |headers_stream_| when push promise headers have been
// received for a stream.
void OnPromiseHeaders(QuicStreamId stream_id,
base::StringPiece headers_data) override;
// Called by |headers_stream_| when push promise headers have been
// completely received.
void OnPromiseHeadersComplete(QuicStreamId stream_id,
QuicStreamId promised_stream_id,
size_t frame_len) override;
// Called by |headers_stream_| when push promise headers have been
// completely received.
void OnPromiseHeaderList(QuicStreamId stream_id,
QuicStreamId promised_stream_id,
size_t frame_len,
const QuicHeaderList& header_list) override;
// Called by |QuicSpdyClientStream| on receipt of response headers,
// needed to detect promised server push streams, as part of
// client-request to push-stream rendezvous.
void OnInitialHeadersComplete(QuicStreamId stream_id,
const SpdyHeaderBlock& response_headers);
// Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
// some session level validation and creates the
// |QuicClientPromisedInfo| inserting into maps by (promised) id and
// url.
virtual void HandlePromised(QuicStreamId associated_id,
QuicStreamId promised_id,
const SpdyHeaderBlock& headers);
// For cross-origin server push, this should verify the server is
// authoritative per [RFC2818], Section 3. Roughly, subjectAltName
// std::list in the certificate should contain a matching DNS name, or IP
// address. |hostname| is derived from the ":authority" header field of
// the PUSH_PROMISE frame, port if present there will be dropped.
virtual bool IsAuthorized(const std::string& hostname) = 0;
// Session retains ownership.
QuicClientPromisedInfo* GetPromisedByUrl(const std::string& url);
// Session retains ownership.
QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
// Removes |promised| from the maps by url.
void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
// Removes |promised| from the maps by url and id and destroys
// promised.
virtual void DeletePromised(QuicClientPromisedInfo* promised);
// Sends Rst for the stream, and makes sure that future calls to
// IsClosedStream(id) return true, which ensures that any subsequent
// frames related to this stream will be ignored (modulo flow
// control accounting).
void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
size_t get_max_promises() const {
return max_open_incoming_streams() * kMaxPromisedStreamsMultiplier;
QuicClientPushPromiseIndex* push_promise_index() {
return push_promise_index_;
// For QuicSpdyClientStream to detect that a response corresponds to a
// promise.
using QuicPromisedByIdMap =
std::unordered_map<QuicStreamId, std::unique_ptr<QuicClientPromisedInfo>>;
// As per rfc7540, section 10.5: track promise streams in "reserved
// (remote)". The primary key is URL from he promise request
// headers. The promised stream id is a secondary key used to get
// promise info when the response headers of the promised stream
// arrive.
QuicClientPushPromiseIndex* push_promise_index_;
QuicPromisedByIdMap promised_by_id_;
QuicStreamId largest_promised_stream_id_;
} // namespace net