OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "nacl_io/googledrivefs/googledrivefs.h" | |
6 | |
7 #include <map> | |
8 | |
9 #include "nacl_io/filesystem.h" | |
10 #include "nacl_io/statuscode.h" | |
11 #include "nacl_io/googledrivefs/googledrivefs_node.h" | |
12 #include "nacl_io/googledrivefs/googledrivefs_util.h" | |
13 | |
14 namespace nacl_io { | |
15 | |
16 GoogleDriveFs::GoogleDriveFs() {} | |
17 | |
18 GoogleDriveFs::~GoogleDriveFs() {} | |
19 | |
20 Error GoogleDriveFs::Init(const FsInitArgs& args) { | |
21 Error error = Filesystem::Init(args); | |
22 if (error) { | |
23 return error; | |
24 } | |
25 | |
26 std::map<std::string, std::string>::const_iterator instance_it = | |
27 args.string_map.find("instance"); | |
28 | |
29 if (instance_it == args.string_map.end()) { | |
30 return EINVAL; | |
31 } | |
32 | |
33 instance_ = atoi(instance_it->second.c_str()); | |
binji
2016/08/22 19:21:52
you don't need to get this instance from the user,
chanpatorikku
2016/08/29 17:14:03
Done.
| |
34 | |
35 std::map<std::string, std::string>::const_iterator token_it = | |
binji
2016/08/22 19:21:52
nit: Use StringMap_t instead of std::map<std::stri
chanpatorikku
2016/08/29 17:14:03
Done.
StringMap_t is defined the same in http_fs_
binji
2016/08/30 01:39:34
It's fine to redefine it.
| |
36 args.string_map.find("token"); | |
37 | |
38 if (token_it == args.string_map.end()) { | |
39 return EINVAL; | |
40 } | |
41 | |
42 token_ = token_it->second; | |
43 | |
44 return 0; | |
45 } | |
46 | |
47 void GoogleDriveFs::Destroy() {} | |
48 | |
49 Error GoogleDriveFs::OpenWithMode(const Path& path, | |
50 int open_flags, | |
51 mode_t mode, | |
52 ScopedNode* out_node) { | |
53 ScopedNode node(new GoogleDriveFsNode(this, path)); | |
54 | |
55 Error error = node->Init(open_flags); | |
56 if (error) { | |
57 return error; | |
58 } | |
59 | |
60 *out_node = node; | |
61 | |
62 return 0; | |
63 } | |
64 | |
65 Error GoogleDriveFs::Mkdir(const Path& path, int permissions) { | |
66 URLLoaderInterface* url_loader_iface = ppapi()->GetURLLoaderInterface(); | |
binji
2016/08/22 19:21:52
you could cache these interface pointers as member
chanpatorikku
2016/08/29 17:14:02
The interface pointers in googledrivefs are not ca
| |
67 PP_Resource url_loader_object = url_loader_iface->Create(instance()); | |
68 URLRequestInfoInterface* url_request_info_iface = | |
69 ppapi()->GetURLRequestInfoInterface(); | |
70 PP_Resource url_request_info_object = | |
71 url_request_info_iface->Create(instance()); | |
72 PP_Resource url_response_info_object = 0; | |
73 Error error(0); | |
74 std::string parent_dir_id = ""; | |
binji
2016/08/22 19:21:52
nit: it's not necessary to initialize to "", that
chanpatorikku
2016/08/29 17:14:02
Done.
| |
75 std::string item_id = ""; | |
76 static const char base_url[] = "https://www.googleapis.com/drive/v3/files"; | |
77 RequestUrlParams p; | |
78 | |
79 // Error on making the root directory | |
80 if (path.Size() < 2) { | |
81 error = EEXIST; | |
82 goto done; | |
83 } | |
84 | |
85 error = RequestParentDirId(path, this, &parent_dir_id); | |
86 if (error) { | |
87 goto done; | |
88 } | |
89 | |
90 error = RequestItemId(parent_dir_id, path.Basename(), this, &item_id); | |
91 | |
92 if (!error) { | |
93 error = EEXIST; | |
94 goto done; | |
95 } else if (error == ENOENT) { | |
96 // mkdir does not create a directory when a file with path.Basename() | |
97 // already exists. | |
98 | |
99 p.url = base_url; | |
chanpatorikku
2016/08/07 02:41:02
Lines 99-113 are samples of how codes imitate the
| |
100 p.method = "POST"; | |
101 | |
102 p.headers = ""; | |
103 AddHeaders("Content-type", "application/json", &p.headers); | |
104 AddHeaders("Authorization", "Bearer " + token_, &p.headers); | |
105 | |
106 p.body = ""; | |
107 AddBody("{", &p.body); | |
108 AddBody(" \"name\": \"" + path.Basename() + "\",", &p.body); | |
109 AddBody(" \"mimeType\": \"application/vnd.google-apps.folder\",", &p.body); | |
110 AddBody(" \"parents\": [", &p.body); | |
111 AddBody(" \"" + parent_dir_id + "\"", &p.body); | |
112 AddBody(" ]", &p.body); | |
113 AddBody("}", &p.body); | |
114 | |
115 error = MakeRequest(ppapi(), url_loader_object, url_request_info_object, p); | |
116 | |
117 if (error) { | |
118 goto done; | |
119 } | |
120 | |
121 error = FinishPreparingResponse(ppapi(), url_loader_object, | |
122 &url_response_info_object); | |
123 | |
124 if (error) { | |
125 goto done; | |
126 } | |
127 | |
128 if (ReadStatusCode(ppapi(), url_response_info_object) != STATUSCODE_OK) { | |
129 error = EPERM; | |
130 goto done; | |
131 } | |
132 | |
133 error = 0; | |
134 } | |
135 | |
136 done: | |
137 if (url_loader_object) { | |
binji
2016/08/22 19:21:52
Use the ScopedResource instead (see pepper_interfa
chanpatorikku
2016/08/29 17:14:03
Done.
| |
138 ppapi()->ReleaseResource(url_loader_object); | |
139 } | |
140 if (url_request_info_object) { | |
141 ppapi()->ReleaseResource(url_request_info_object); | |
142 } | |
143 if (url_response_info_object) { | |
144 ppapi()->ReleaseResource(url_response_info_object); | |
145 } | |
146 | |
147 return error; | |
148 } | |
149 | |
150 Error GoogleDriveFs::Rmdir(const Path& path) { | |
151 URLLoaderInterface* url_loader_iface = ppapi()->GetURLLoaderInterface(); | |
152 PP_Resource url_loader_object = url_loader_iface->Create(instance()); | |
153 URLRequestInfoInterface* url_request_info_iface = | |
154 ppapi()->GetURLRequestInfoInterface(); | |
155 PP_Resource url_request_info_object = | |
156 url_request_info_iface->Create(instance()); | |
157 PP_Resource url_response_info_object = 0; | |
158 Error error(0); | |
159 std::string parent_dir_id = ""; | |
160 std::string dir_id = ""; | |
161 std::string item_id = ""; | |
162 bool is_empty_dir = true; | |
163 static const char base_url[] = "https://www.googleapis.com/drive/v3/files"; | |
binji
2016/08/22 19:21:52
This seems to be repeated quite a bit, can you mov
chanpatorikku
2016/08/29 17:14:02
Yes. Done.
| |
164 RequestUrlParams p; | |
165 | |
166 // Error on removing the root directory | |
167 if (path.Size() < 2) { | |
168 error = EEXIST; | |
169 goto done; | |
170 } | |
171 | |
172 error = RequestParentDirId(path, this, &parent_dir_id); | |
173 if (error) { | |
174 goto done; | |
175 } | |
176 | |
177 error = RequestDirId(parent_dir_id, path.Basename(), this, &dir_id); | |
178 if (error == ENOENT) { | |
179 error = RequestItemId(parent_dir_id, path.Basename(), this, &item_id); | |
180 | |
181 if (error) { | |
182 goto done; | |
183 } | |
184 | |
185 error = ENOTDIR; | |
186 goto done; | |
187 } else if (error) { | |
188 goto done; | |
189 } | |
190 | |
191 error = IsEmpty(dir_id, &is_empty_dir); | |
192 if (error) { | |
193 goto done; | |
194 } | |
195 | |
196 if (!is_empty_dir) { | |
197 error = ENOTEMPTY; | |
198 goto done; | |
199 } | |
200 | |
201 p.url = base_url; | |
202 AddUrlPath(dir_id, &p.url); | |
203 | |
204 p.method = "DELETE"; | |
205 | |
206 p.headers = ""; | |
207 AddHeaders("Content-type", "application/json", &p.headers); | |
208 AddHeaders("Authorization", "Bearer " + token_, &p.headers); | |
209 | |
210 error = MakeRequest(ppapi(), url_loader_object, url_request_info_object, p); | |
211 | |
212 if (error) { | |
213 goto done; | |
214 } | |
215 | |
216 error = FinishPreparingResponse(ppapi(), url_loader_object, | |
217 &url_response_info_object); | |
218 | |
219 if (error) { | |
220 goto done; | |
221 } | |
222 | |
223 if (ReadStatusCode(ppapi(), url_response_info_object) != | |
224 STATUSCODE_NO_CONTENT) { | |
225 error = EPERM; | |
226 goto done; | |
227 } | |
228 | |
229 done: | |
230 if (url_loader_object) { | |
231 ppapi()->ReleaseResource(url_loader_object); | |
232 } | |
233 if (url_request_info_object) { | |
234 ppapi()->ReleaseResource(url_request_info_object); | |
235 } | |
236 if (url_response_info_object) { | |
237 ppapi()->ReleaseResource(url_response_info_object); | |
238 } | |
239 | |
240 return error; | |
241 } | |
242 | |
243 Error GoogleDriveFs::Rename(const Path& path, const Path& newPath) { | |
244 // TODO: support rename | |
245 LOG_ERROR("rename not supported."); | |
246 return EPERM; | |
247 } | |
248 | |
249 Error GoogleDriveFs::Unlink(const Path& path) { | |
250 // TODO: support unlink | |
251 LOG_ERROR("unlink not supported."); | |
252 return EPERM; | |
253 } | |
254 | |
255 Error GoogleDriveFs::Remove(const Path& path) { | |
256 // TODO: support remove | |
257 LOG_ERROR("remove not supported."); | |
258 return EPERM; | |
259 } | |
260 | |
261 Error GoogleDriveFs::IsEmpty(const std::string& dir_id, | |
262 bool* out_is_empty_dir) { | |
263 static const char base_url[] = "https://www.googleapis.com/drive/v3/files"; | |
264 | |
265 std::string url = base_url; | |
266 AddUrlFirstQueryParameter("q", "%27" + dir_id + "%27+in+parents", &url); | |
267 | |
268 std::string response_body; | |
269 Error error = GetListFileResponseBody(url, this, &response_body); | |
270 if (error) { | |
271 return error; | |
272 } | |
273 | |
274 std::string name_value = ""; | |
275 int name_index = 0; | |
276 | |
277 GetValue(response_body, "name", name_index, &name_value, &name_index); | |
278 | |
279 *out_is_empty_dir = (name_index == -1); | |
280 | |
281 return 0; | |
282 } | |
283 | |
284 std::string GoogleDriveFs::token() { | |
285 return token_; | |
286 } | |
287 | |
288 PP_Instance GoogleDriveFs::instance() { | |
289 return instance_; | |
290 } | |
291 | |
292 } // namespace nacl_io | |
OLD | NEW |