123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // Copyright 2018 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 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/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 RequestType { SUBSCRIBE, UNSUBSCRIBE };
- // 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/1054759): 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_
|