1// Copyright (c) 2012 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#include "google_apis/drive/drive_api_url_generator.h"
6
7#include "base/logging.h"
8#include "base/strings/string_number_conversions.h"
9#include "base/strings/stringprintf.h"
10#include "google_apis/google_api_keys.h"
11#include "net/base/escape.h"
12#include "net/base/url_util.h"
13
14namespace google_apis {
15
16namespace {
17
18// Hard coded URLs for communication with a google drive server.
19const char kDriveV2AboutUrl[] = "/drive/v2/about";
20const char kDriveV2AppsUrl[] = "/drive/v2/apps";
21const char kDriveV2ChangelistUrl[] = "/drive/v2/changes";
22const char kDriveV2FilesUrl[] = "/drive/v2/files";
23const char kDriveV2FileUrlPrefix[] = "/drive/v2/files/";
24const char kDriveV2ChildrenUrlFormat[] = "/drive/v2/files/%s/children";
25const char kDriveV2ChildrenUrlForRemovalFormat[] =
26    "/drive/v2/files/%s/children/%s";
27const char kDriveV2FileCopyUrlFormat[] = "/drive/v2/files/%s/copy";
28const char kDriveV2FileDeleteUrlFormat[] = "/drive/v2/files/%s";
29const char kDriveV2FileTrashUrlFormat[] = "/drive/v2/files/%s/trash";
30const char kDriveV2InitiateUploadNewFileUrl[] = "/upload/drive/v2/files";
31const char kDriveV2InitiateUploadExistingFileUrlPrefix[] =
32    "/upload/drive/v2/files/";
33const char kDriveV2PermissionsUrlFormat[] = "/drive/v2/files/%s/permissions";
34
35// apps.delete and file.authorize API is exposed through a special endpoint
36// v2internal that is accessible only by the official API key for Chrome.
37const char kDriveV2InternalAppsUrl[] = "/drive/v2internal/apps";
38const char kDriveV2AppsDeleteUrlFormat[] = "/drive/v2internal/apps/%s";
39const char kDriveV2FilesAuthorizeUrlFormat[] =
40    "/drive/v2internal/files/%s/authorize?appId=%s";
41
42GURL AddResumableUploadParam(const GURL& url) {
43  return net::AppendOrReplaceQueryParameter(url, "uploadType", "resumable");
44}
45
46}  // namespace
47
48DriveApiUrlGenerator::DriveApiUrlGenerator(const GURL& base_url,
49                                           const GURL& base_download_url)
50    : base_url_(base_url),
51      base_download_url_(base_download_url) {
52  // Do nothing.
53}
54
55DriveApiUrlGenerator::~DriveApiUrlGenerator() {
56  // Do nothing.
57}
58
59const char DriveApiUrlGenerator::kBaseUrlForProduction[] =
60    "https://www.googleapis.com";
61const char DriveApiUrlGenerator::kBaseDownloadUrlForProduction[] =
62    "https://www.googledrive.com/host/";
63
64GURL DriveApiUrlGenerator::GetAboutGetUrl() const {
65  return base_url_.Resolve(kDriveV2AboutUrl);
66}
67
68GURL DriveApiUrlGenerator::GetAppsListUrl(bool use_internal_endpoint) const {
69  return base_url_.Resolve(use_internal_endpoint ?
70      kDriveV2InternalAppsUrl : kDriveV2AppsUrl);
71}
72
73GURL DriveApiUrlGenerator::GetAppsDeleteUrl(const std::string& app_id) const {
74  return base_url_.Resolve(base::StringPrintf(
75      kDriveV2AppsDeleteUrlFormat, net::EscapePath(app_id).c_str()));
76}
77
78GURL DriveApiUrlGenerator::GetFilesGetUrl(const std::string& file_id) const {
79  return base_url_.Resolve(kDriveV2FileUrlPrefix + net::EscapePath(file_id));
80}
81
82GURL DriveApiUrlGenerator::GetFilesAuthorizeUrl(
83    const std::string& file_id,
84    const std::string& app_id) const {
85  return base_url_.Resolve(base::StringPrintf(kDriveV2FilesAuthorizeUrlFormat,
86                                              net::EscapePath(file_id).c_str(),
87                                              net::EscapePath(app_id).c_str()));
88}
89
90GURL DriveApiUrlGenerator::GetFilesInsertUrl() const {
91  return base_url_.Resolve(kDriveV2FilesUrl);
92}
93
94GURL DriveApiUrlGenerator::GetFilesPatchUrl(const std::string& file_id,
95                                            bool set_modified_date,
96                                            bool update_viewed_date) const {
97  GURL url =
98      base_url_.Resolve(kDriveV2FileUrlPrefix + net::EscapePath(file_id));
99
100  // setModifiedDate is "false" by default.
101  if (set_modified_date)
102    url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true");
103
104  // updateViewedDate is "true" by default.
105  if (!update_viewed_date)
106    url = net::AppendOrReplaceQueryParameter(url, "updateViewedDate", "false");
107
108  return url;
109}
110
111GURL DriveApiUrlGenerator::GetFilesCopyUrl(const std::string& file_id) const {
112  return base_url_.Resolve(base::StringPrintf(
113      kDriveV2FileCopyUrlFormat, net::EscapePath(file_id).c_str()));
114}
115
116GURL DriveApiUrlGenerator::GetFilesListUrl(int max_results,
117                                           const std::string& page_token,
118                                           const std::string& q) const {
119  GURL url = base_url_.Resolve(kDriveV2FilesUrl);
120
121  // maxResults is 100 by default.
122  if (max_results != 100) {
123    url = net::AppendOrReplaceQueryParameter(
124        url, "maxResults", base::IntToString(max_results));
125  }
126
127  if (!page_token.empty())
128    url = net::AppendOrReplaceQueryParameter(url, "pageToken", page_token);
129
130  if (!q.empty())
131    url = net::AppendOrReplaceQueryParameter(url, "q", q);
132
133  return url;
134}
135
136GURL DriveApiUrlGenerator::GetFilesDeleteUrl(const std::string& file_id) const {
137  return base_url_.Resolve(base::StringPrintf(
138      kDriveV2FileDeleteUrlFormat, net::EscapePath(file_id).c_str()));
139}
140
141GURL DriveApiUrlGenerator::GetFilesTrashUrl(const std::string& file_id) const {
142  return base_url_.Resolve(base::StringPrintf(
143      kDriveV2FileTrashUrlFormat, net::EscapePath(file_id).c_str()));
144}
145
146GURL DriveApiUrlGenerator::GetChangesListUrl(bool include_deleted,
147                                             int max_results,
148                                             const std::string& page_token,
149                                             int64 start_change_id) const {
150  DCHECK_GE(start_change_id, 0);
151
152  GURL url = base_url_.Resolve(kDriveV2ChangelistUrl);
153
154  // includeDeleted is "true" by default.
155  if (!include_deleted)
156    url = net::AppendOrReplaceQueryParameter(url, "includeDeleted", "false");
157
158  // maxResults is "100" by default.
159  if (max_results != 100) {
160    url = net::AppendOrReplaceQueryParameter(
161        url, "maxResults", base::IntToString(max_results));
162  }
163
164  if (!page_token.empty())
165    url = net::AppendOrReplaceQueryParameter(url, "pageToken", page_token);
166
167  if (start_change_id > 0)
168    url = net::AppendOrReplaceQueryParameter(
169        url, "startChangeId", base::Int64ToString(start_change_id));
170
171  return url;
172}
173
174GURL DriveApiUrlGenerator::GetChildrenInsertUrl(
175    const std::string& file_id) const {
176  return base_url_.Resolve(base::StringPrintf(
177      kDriveV2ChildrenUrlFormat, net::EscapePath(file_id).c_str()));
178}
179
180GURL DriveApiUrlGenerator::GetChildrenDeleteUrl(
181    const std::string& child_id, const std::string& folder_id) const {
182  return base_url_.Resolve(
183      base::StringPrintf(kDriveV2ChildrenUrlForRemovalFormat,
184                         net::EscapePath(folder_id).c_str(),
185                         net::EscapePath(child_id).c_str()));
186}
187
188GURL DriveApiUrlGenerator::GetInitiateUploadNewFileUrl(
189    bool set_modified_date) const {
190  GURL url = AddResumableUploadParam(
191      base_url_.Resolve(kDriveV2InitiateUploadNewFileUrl));
192
193  // setModifiedDate is "false" by default.
194  if (set_modified_date)
195    url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true");
196
197  return url;
198}
199
200GURL DriveApiUrlGenerator::GetInitiateUploadExistingFileUrl(
201    const std::string& resource_id,
202    bool set_modified_date) const {
203  GURL url = base_url_.Resolve(
204      kDriveV2InitiateUploadExistingFileUrlPrefix +
205      net::EscapePath(resource_id));
206  url = AddResumableUploadParam(url);
207
208  // setModifiedDate is "false" by default.
209  if (set_modified_date)
210    url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true");
211
212  return url;
213}
214
215GURL DriveApiUrlGenerator::GenerateDownloadFileUrl(
216    const std::string& resource_id) const {
217  return base_download_url_.Resolve(net::EscapePath(resource_id));
218}
219
220GURL DriveApiUrlGenerator::GetPermissionsInsertUrl(
221    const std::string& resource_id) const {
222  return base_url_.Resolve(
223      base::StringPrintf(kDriveV2PermissionsUrlFormat,
224                         net::EscapePath(resource_id).c_str()));
225}
226
227}  // namespace google_apis
228