summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_client_push_promise_index.h
blob: c00a17eac540659ce0b4fea3ca27626304998708 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2016 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.

#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_

#include <string>

#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/spdy/core/http2_header_block.h"

namespace quic {

// QuicClientPushPromiseIndex is the interface to support rendezvous
// between client requests and resources delivered via server push.
// The same index can be shared across multiple sessions (e.g. for the
// same browser users profile), since cross-origin pushes are allowed
// (subject to authority constraints).

class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
 public:
  // Delegate is used to complete the rendezvous that began with
  // |Try()|.
  class QUIC_EXPORT_PRIVATE Delegate {
   public:
    virtual ~Delegate() {}

    // The primary lookup matched request with push promise by URL.  A
    // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
    // is honored.  If Vary is not present, return true.  If Vary is
    // present, return whether designated header fields of
    // |promise_request| and |client_request| match.
    virtual bool CheckVary(const spdy::Http2HeaderBlock& client_request,
                           const spdy::Http2HeaderBlock& promise_request,
                           const spdy::Http2HeaderBlock& promise_response) = 0;

    // On rendezvous success, provides the promised |stream|.  Callee
    // does not inherit ownership of |stream|.  On rendezvous failure,
    // |stream| is |nullptr| and the client should retry the request.
    // Rendezvous can fail due to promise validation failure or RST on
    // promised stream.  |url| will have been removed from the index
    // before |OnRendezvousResult()| is invoked, so a recursive call to
    // |Try()| will return |QUIC_FAILURE|, which may be convenient for
    // retry purposes.
    virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
  };

  class QUIC_EXPORT_PRIVATE TryHandle {
   public:
    // Cancel the request.
    virtual void Cancel() = 0;

   protected:
    TryHandle() {}
    TryHandle(const TryHandle&) = delete;
    TryHandle& operator=(const TryHandle&) = delete;
    ~TryHandle();
  };

  QuicClientPushPromiseIndex();
  QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
  QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
      delete;
  virtual ~QuicClientPushPromiseIndex();

  // Called by client code, used to enforce affinity between requests
  // for promised streams and the session the promise came from.
  QuicClientPromisedInfo* GetPromised(const std::string& url);

  // Called by client code, to initiate rendezvous between a request
  // and a server push stream.  If |request|'s url is in the index,
  // rendezvous will be attempted and may complete immediately or
  // asynchronously.  If the matching promise and response headers
  // have already arrived, the delegate's methods will fire
  // recursively from within |Try()|.  Returns |QUIC_SUCCESS| if the
  // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
  // matching promise, or if there was but the rendezvous has failed.
  // Returns QUIC_PENDING if a matching promise was found, but the
  // rendezvous needs to complete asynchronously because the promised
  // response headers are not yet available.  If result is
  // QUIC_PENDING, then |*handle| will set so that the caller may
  // cancel the request if need be.  The caller does not inherit
  // ownership of |*handle|, and it ceases to be valid if the caller
  // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
  QuicAsyncStatus Try(const spdy::Http2HeaderBlock& request, Delegate* delegate,
                      TryHandle** handle);

  QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }

 private:
  QuicPromisedByUrlMap promised_by_url_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_