File: per_user_topic_subscription_request.h

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (131 lines) | stat: -rw-r--r-- 5,188 bytes parent folder | download | duplicates (6)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_INVALIDATION_IMPL_PER_USER_TOPIC_SUBSCRIPTION_REQUEST_H_
#define COMPONENTS_INVALIDATION_IMPL_PER_USER_TOPIC_SUBSCRIPTION_REQUEST_H_

#include <memory>
#include <string>
#include <utility>

#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "components/invalidation/impl/status.h"
#include "components/invalidation/public/invalidation_util.h"
#include "net/http/http_request_headers.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"

namespace invalidation {

// A single request to subscribe to a topic on the per-user-topic service.
class PerUserTopicSubscriptionRequest {
 public:
  // The request result consists of the request status and name of the private
  // topic. The |topic_name| will be empty in the case of error.
  using CompletedCallback =
      base::OnceCallback<void(const Status& status,
                              const std::string& topic_name)>;
  enum class RequestType { kSubscribe, kUnsubscribe };

  // Builds authenticated PerUserTopicSubscriptionRequests.
  class Builder {
   public:
    Builder();
    Builder(const Builder& other) = delete;
    Builder& operator=(const Builder& other) = delete;
    ~Builder();

    // Builds a Request object in order to perform the subscription.
    std::unique_ptr<PerUserTopicSubscriptionRequest> Build() const;

    Builder& SetInstanceIdToken(const std::string& token);
    Builder& SetScope(const std::string& scope);
    Builder& SetAuthenticationHeader(const std::string& auth_header);

    Builder& SetPublicTopicName(const Topic& topic);
    Builder& SetProjectId(const std::string& project_id);

    Builder& SetType(RequestType type);

    Builder& SetTopicIsPublic(bool topic_is_public);

   private:
    net::HttpRequestHeaders BuildHeaders() const;
    std::string BuildBody() const;
    std::unique_ptr<network::SimpleURLLoader> BuildURLFetcher(
        const net::HttpRequestHeaders& headers,
        const std::string& body,
        const GURL& url) const;

    // GCM subscription token obtained from GCM driver (instanceID::getToken()).
    std::string instance_id_token_;
    Topic topic_;
    std::string project_id_;

    std::string scope_;
    std::string auth_header_;
    RequestType type_;
    bool topic_is_public_ = false;
  };

  PerUserTopicSubscriptionRequest(
      const PerUserTopicSubscriptionRequest& other) = delete;
  PerUserTopicSubscriptionRequest& operator=(
      const PerUserTopicSubscriptionRequest& other) = delete;
  ~PerUserTopicSubscriptionRequest();

  // Starts an async request. The callback is invoked when the request succeeds
  // or fails. The callback is not called if the request is destroyed.
  void Start(CompletedCallback callback,
             network::mojom::URLLoaderFactory* loader_factory);

  GURL GetUrlForTesting() const { return url_; }

 private:
  PerUserTopicSubscriptionRequest();

  // The methods below may end up calling RunCompletedCallbackAndMaybeDie(),
  // which potentially lead to destroying |this|. Hence, |this| object must
  // assume that it is dead after invoking any of these methods and must not
  // run any more code.
  void OnURLFetchComplete(std::unique_ptr<std::string> response_body);
  void OnURLFetchCompleteInternal(int net_error,
                                  int response_code,
                                  std::unique_ptr<std::string> response_body);
  void OnJsonParse(data_decoder::DataDecoder::ValueOrError result);

  // Invokes |request_completed_callback_| with (|status|, |topic_name|). Per
  // the contract of this class, it is allowed for clients to delete this
  // object as part of the invocation of |request_completed_callback_|. Hence,
  // this object must assume that it is dead after invoking this method and
  // must not run any more code. See crbug.com/1054590 as sample issue for
  // violation of this rule.
  // |status| and |topic_name| are intentionally taken by value to avoid
  // references to members.
  void RunCompletedCallbackAndMaybeDie(Status status, std::string topic_name);
  // The fetcher for subscribing.
  std::unique_ptr<network::SimpleURLLoader> simple_loader_;

  // The callback to notify when URLFetcher finished and results are available.
  // When the request is finished/aborted/destroyed, it's called in the dtor!
  // Note: This callback should only be invoked from
  // RunCompletedCallbackAndMaybeDie(), as invoking it has the potential to
  // destroy this object per this class's contract.
  // TODO(crbug.com/40675891): find a way to avoid this fragile logic.
  CompletedCallback request_completed_callback_;

  // Full URL. Used in tests only.
  GURL url_;
  RequestType type_;
  std::string topic_;

  base::WeakPtrFactory<PerUserTopicSubscriptionRequest> weak_ptr_factory_{this};
};

}  // namespace invalidation

#endif  // COMPONENTS_INVALIDATION_IMPL_PER_USER_TOPIC_SUBSCRIPTION_REQUEST_H_