summaryrefslogtreecommitdiffstats
path: root/chrome/browser/local_discovery/privet_url_fetcher.h
blob: f3b7405378d0cc73385b7162db9ac81ef0ef5479 (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
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
// Copyright 2013 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 CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_

#include <string>

#include "base/file_util.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"

namespace base {
class FilePath;
}

namespace local_discovery {

const int kPrivetHTTPCodeInternalFailure = -1;

// Privet-specific URLFetcher adapter. Currently supports only the subset
// of HTTP features required by Privet for GCP 1.5
// (/privet/info and /privet/register).
class PrivetURLFetcher : public net::URLFetcherDelegate {
 public:
  enum ErrorType {
    JSON_PARSE_ERROR,
    URL_FETCH_ERROR,
    RESPONSE_CODE_ERROR,
    RETRY_ERROR,
    TOKEN_ERROR
  };

  typedef base::Callback<void(const std::string& /*token*/)> TokenCallback;

  class Delegate {
   public:
    virtual ~Delegate() {}

    // If you do not implement this method, you will always get a
    // TOKEN_ERROR error when your token is invalid.
    virtual void OnNeedPrivetToken(
        PrivetURLFetcher* fetcher,
        const TokenCallback& callback);
    virtual void OnError(PrivetURLFetcher* fetcher, ErrorType error) = 0;
    virtual void OnParsedJson(PrivetURLFetcher* fetcher,
                              const base::DictionaryValue* value,
                              bool has_error) = 0;
  };

  PrivetURLFetcher(
      const std::string& token,
      const GURL& url,
      net::URLFetcher::RequestType request_type,
      net::URLRequestContextGetter* request_context,
      Delegate* delegate);
  virtual ~PrivetURLFetcher();

  void DoNotRetryOnTransientError();

  void AllowEmptyPrivetToken();

  void Start();

  void SetUploadData(const std::string& upload_content_type,
                     const std::string& upload_data);

  void SetUploadFilePath(const std::string& upload_content_type,
                         const base::FilePath& upload_file_path);

  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;

  const GURL& url() const { return url_fetcher_->GetOriginalURL(); }
  int response_code() const { return url_fetcher_->GetResponseCode(); }

 private:
  void Try();
  void ScheduleRetry(int timeout_seconds);
  bool PrivetErrorTransient(const std::string& error);
  void RequestTokenRefresh();
  void RefreshToken(const std::string& token);

  std::string privet_access_token_;
  GURL url_;
  net::URLFetcher::RequestType request_type_;
  scoped_refptr<net::URLRequestContextGetter> request_context_;
  Delegate* delegate_;

  bool do_not_retry_on_transient_error_;
  bool allow_empty_privet_token_;

  int tries_;
  std::string upload_data_;
  std::string upload_content_type_;
  base::FilePath upload_file_path_;
  scoped_ptr<net::URLFetcher> url_fetcher_;

  base::WeakPtrFactory<PrivetURLFetcher> weak_factory_;
  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcher);
};

class PrivetURLFetcherFactory {
 public:
  explicit PrivetURLFetcherFactory(
      net::URLRequestContextGetter* request_context);
  ~PrivetURLFetcherFactory();

  scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
      const GURL& url,
      net::URLFetcher::RequestType request_type,
      PrivetURLFetcher::Delegate* delegate) const;

  void set_token(const std::string& token) { token_ = token; }
  const std::string& get_token() const { return token_; }

 private:
  scoped_refptr<net::URLRequestContextGetter> request_context_;
  std::string token_;

  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcherFactory);
};

}  // namespace local_discovery

#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_