privet_url_fetcher.h revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
6#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
7
8#include <string>
9
10#include "base/memory/weak_ptr.h"
11#include "base/values.h"
12#include "net/url_request/url_fetcher.h"
13#include "net/url_request/url_fetcher_delegate.h"
14#include "net/url_request/url_request_context_getter.h"
15#include "url/gurl.h"
16
17namespace local_discovery {
18
19const int kPrivetHTTPCodeInternalFailure = -1;
20
21// Privet-specific URLFetcher adapter. Currently supports only the subset
22// of HTTP features required by Privet for GCP 1.5
23// (/privet/info and /privet/register).
24class PrivetURLFetcher : public net::URLFetcherDelegate {
25 public:
26  enum ErrorType {
27    JSON_PARSE_ERROR,
28    URL_FETCH_ERROR,
29    RESPONSE_CODE_ERROR,
30    RETRY_ERROR,
31    TOKEN_ERROR
32  };
33
34  typedef base::Callback<void(const std::string& /*token*/)> TokenCallback;
35
36  class Delegate {
37   public:
38    virtual ~Delegate() {}
39
40    // If you do not implement this method, you will always get a
41    // TOKEN_ERROR error when your token is invalid.
42    virtual void OnNeedPrivetToken(
43        PrivetURLFetcher* fetcher,
44        const TokenCallback& callback);
45    virtual void OnError(PrivetURLFetcher* fetcher, ErrorType error) = 0;
46    virtual void OnParsedJson(PrivetURLFetcher* fetcher,
47                              const base::DictionaryValue* value,
48                              bool has_error) = 0;
49  };
50
51  PrivetURLFetcher(
52      const std::string& token,
53      const GURL& url,
54      net::URLFetcher::RequestType request_type,
55      net::URLRequestContextGetter* request_context,
56      Delegate* delegate);
57  virtual ~PrivetURLFetcher();
58
59  void DoNotRetryOnTransientError();
60
61  void AllowEmptyPrivetToken();
62
63  void Start();
64
65  void SetUploadData(const std::string& upload_content_type,
66                     const std::string& upload_data);
67
68  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
69
70  const GURL& url() const { return url_fetcher_->GetOriginalURL(); }
71  int response_code() const { return url_fetcher_->GetResponseCode(); }
72
73 private:
74  void Try();
75  void ScheduleRetry(int timeout_seconds);
76  bool PrivetErrorTransient(const std::string& error);
77  void RequestTokenRefresh();
78  void RefreshToken(const std::string& token);
79
80  std::string privet_access_token_;
81  GURL url_;
82  net::URLFetcher::RequestType request_type_;
83  scoped_refptr<net::URLRequestContextGetter> request_context_;
84  Delegate* delegate_;
85
86  bool do_not_retry_on_transient_error_;
87  bool allow_empty_privet_token_;
88
89  int tries_;
90  std::string upload_data_;
91  std::string upload_content_type_;
92  scoped_ptr<net::URLFetcher> url_fetcher_;
93
94  base::WeakPtrFactory<PrivetURLFetcher> weak_factory_;
95  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcher);
96};
97
98class PrivetURLFetcherFactory {
99 public:
100  explicit PrivetURLFetcherFactory(
101      net::URLRequestContextGetter* request_context);
102  ~PrivetURLFetcherFactory();
103
104  scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
105      const GURL& url,
106      net::URLFetcher::RequestType request_type,
107      PrivetURLFetcher::Delegate* delegate) const;
108
109  void set_token(const std::string& token) { token_ = token; }
110  const std::string& get_token() const { return token_; }
111
112 private:
113  scoped_refptr<net::URLRequestContextGetter> request_context_;
114  std::string token_;
115
116  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcherFactory);
117};
118
119}  // namespace local_discovery
120
121#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
122