Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: chrome/common/cloud_print/cloud_print_helpers.cc

Issue 11038063: Support chrome_to_mobile job receiving Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix format Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/cloud_print/cloud_print_helpers.h" 5 #include "chrome/common/cloud_print/cloud_print_helpers.h"
6 6
7 #include "base/json/json_reader.h" 7 #include "base/json/json_reader.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/md5.h"
9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
10 #include "base/rand_util.h" 11 #include "base/rand_util.h"
11 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
13 #include "base/sys_info.h"
12 #include "base/values.h" 14 #include "base/values.h"
13 #include "googleurl/src/gurl.h" 15 #include "googleurl/src/gurl.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/common/cloud_print/cloud_print_consts.h"
18
19 namespace {
20
21 // Returns printer tags generated from |printer_tags| and the default tags
22 // required by cloud print server.
23 cloud_print::PrinterTags PreparePrinterTags(
24 const cloud_print::PrinterTags& printer_tags) {
25 cloud_print::PrinterTags printer_tags_out = printer_tags;
26 chrome::VersionInfo version_info;
27 DCHECK(version_info.is_valid());
28 printer_tags_out[cloud_print::kChromeVersionTagName] =
29 version_info.CreateVersionString();
30 using base::SysInfo;
31 printer_tags_out[cloud_print::kSystemNameTagName] =
32 SysInfo::OperatingSystemName();
33 printer_tags_out[cloud_print::kSystemVersionTagName] =
34 SysInfo::OperatingSystemVersion();
35 return printer_tags_out;
36 }
37
38 std::string HashPrinterTags(const cloud_print::PrinterTags& strings) {
39 std::string values_list;
40 cloud_print::PrinterTags::const_iterator it;
41 for (it = strings.begin(); it != strings.end(); ++it) {
42 values_list.append(it->first);
43 values_list.append(it->second);
44 }
45 return base::MD5String(values_list);
46 }
47
48 } // namespace
14 49
15 namespace cloud_print { 50 namespace cloud_print {
16 51
17 const char kPrinterListValue[] = "printers";
18 const char kSuccessValue[] = "success";
19
20 // Certain cloud print requests require Chrome's X-CloudPrint-Proxy header.
21 const char kChromeCloudPrintProxyHeader[] = "X-CloudPrint-Proxy: Chrome";
22
23 std::string AppendPathToUrl(const GURL& url, const std::string& path) { 52 std::string AppendPathToUrl(const GURL& url, const std::string& path) {
24 DCHECK_NE(path[0], '/'); 53 DCHECK_NE(path[0], '/');
25 std::string ret = url.path(); 54 std::string ret = url.path();
26 if (url.has_path() && (ret[ret.length() - 1] != '/')) 55 if (url.has_path() && (ret[ret.length() - 1] != '/'))
27 ret += '/'; 56 ret += '/';
28 ret += path; 57 ret += path;
29 return ret; 58 return ret;
30 } 59 }
31 60
32 GURL GetUrlForSearch(const GURL& cloud_print_server_url) { 61 GURL GetUrlForSearch(const GURL& cloud_print_server_url) {
33 std::string path(AppendPathToUrl(cloud_print_server_url, "search")); 62 std::string path(AppendPathToUrl(cloud_print_server_url, "search"));
34 GURL::Replacements replacements; 63 GURL::Replacements replacements;
35 replacements.SetPathStr(path); 64 replacements.SetPathStr(path);
36 return cloud_print_server_url.ReplaceComponents(replacements); 65 return cloud_print_server_url.ReplaceComponents(replacements);
37 } 66 }
38 67
39 GURL GetUrlForSubmit(const GURL& cloud_print_server_url) { 68 GURL GetUrlForSubmit(const GURL& cloud_print_server_url) {
40 std::string path(AppendPathToUrl(cloud_print_server_url, "submit")); 69 std::string path(AppendPathToUrl(cloud_print_server_url, "submit"));
41 GURL::Replacements replacements; 70 GURL::Replacements replacements;
42 replacements.SetPathStr(path); 71 replacements.SetPathStr(path);
43 return cloud_print_server_url.ReplaceComponents(replacements); 72 return cloud_print_server_url.ReplaceComponents(replacements);
44 } 73 }
45 74
75 GURL GetUrlForPrinterList(const GURL& cloud_print_server_url,
76 const std::string& proxy_id) {
77 std::string path(cloud_print::AppendPathToUrl(
78 cloud_print_server_url, "list"));
79 GURL::Replacements replacements;
80 replacements.SetPathStr(path);
81 std::string query = StringPrintf("proxy=%s", proxy_id.c_str());
82 replacements.SetQueryStr(query);
83 return cloud_print_server_url.ReplaceComponents(replacements);
84 }
85
86 GURL GetUrlForPrinterRegistration(const GURL& cloud_print_server_url) {
87 std::string path(cloud_print::AppendPathToUrl(
88 cloud_print_server_url, "register"));
89 GURL::Replacements replacements;
90 replacements.SetPathStr(path);
91 return cloud_print_server_url.ReplaceComponents(replacements);
92 }
93
94 GURL GetUrlForPrinterUpdate(const GURL& cloud_print_server_url,
95 const std::string& printer_id) {
96 std::string path(cloud_print::AppendPathToUrl(
97 cloud_print_server_url, "update"));
98 GURL::Replacements replacements;
99 replacements.SetPathStr(path);
100 std::string query = StringPrintf("printerid=%s", printer_id.c_str());
101 replacements.SetQueryStr(query);
102 return cloud_print_server_url.ReplaceComponents(replacements);
103 }
104
105 GURL GetUrlForPrinterDelete(const GURL& cloud_print_server_url,
106 const std::string& printer_id,
107 const std::string& reason) {
108 std::string path(cloud_print::AppendPathToUrl(
109 cloud_print_server_url, "delete"));
110 GURL::Replacements replacements;
111 replacements.SetPathStr(path);
112 std::string query = StringPrintf(
113 "printerid=%s&reason=%s", printer_id.c_str(), reason.c_str());
114 replacements.SetQueryStr(query);
115 return cloud_print_server_url.ReplaceComponents(replacements);
116 }
117
118 GURL GetUrlForJobFetch(const GURL& cloud_print_server_url,
119 const std::string& printer_id,
120 const std::string& reason) {
121 std::string path(cloud_print::AppendPathToUrl(
122 cloud_print_server_url, "fetch"));
123 GURL::Replacements replacements;
124 replacements.SetPathStr(path);
125 std::string query = StringPrintf(
126 "printerid=%s&deb=%s", printer_id.c_str(), reason.c_str());
127 replacements.SetQueryStr(query);
128 return cloud_print_server_url.ReplaceComponents(replacements);
129 }
130
131
132 GURL GetUrlForJobDelete(const GURL& cloud_print_server_url,
133 const std::string& job_id) {
134 std::string path(cloud_print::AppendPathToUrl(
135 cloud_print_server_url, "deletejob"));
136 GURL::Replacements replacements;
137 replacements.SetPathStr(path);
138 std::string query = StringPrintf("jobid=%s", job_id.c_str());
139 replacements.SetQueryStr(query);
140 return cloud_print_server_url.ReplaceComponents(replacements);
141 }
142
143 GURL GetUrlForJobStatusUpdate(const GURL& cloud_print_server_url,
144 const std::string& job_id,
145 const std::string& status_string) {
146 std::string path(cloud_print::AppendPathToUrl(
147 cloud_print_server_url, "control"));
148 GURL::Replacements replacements;
149 replacements.SetPathStr(path);
150 std::string query = StringPrintf(
151 "jobid=%s&status=%s", job_id.c_str(), status_string.c_str());
152 replacements.SetQueryStr(query);
153 return cloud_print_server_url.ReplaceComponents(replacements);
154 }
155
156 GURL GetUrlForUserMessage(const GURL& cloud_print_server_url,
157 const std::string& message_id) {
158 std::string path(
159 cloud_print::AppendPathToUrl(cloud_print_server_url, "message"));
160 GURL::Replacements replacements;
161 replacements.SetPathStr(path);
162 std::string query = StringPrintf("code=%s", message_id.c_str());
163 replacements.SetQueryStr(query);
164 return cloud_print_server_url.ReplaceComponents(replacements);
165 }
166
167 GURL GetUrlForGetAuthCode(const GURL& cloud_print_server_url,
168 const std::string& oauth_client_id,
169 const std::string& proxy_id) {
170 // We use the internal API "createrobot" instead of "getauthcode". This API
171 // will add the robot as owner to all the existing printers for this user.
172 std::string path(
173 cloud_print::AppendPathToUrl(cloud_print_server_url, "createrobot"));
174 GURL::Replacements replacements;
175 replacements.SetPathStr(path);
176 std::string query = StringPrintf("oauth_client_id=%s&proxy=%s",
177 oauth_client_id.c_str(),
178 proxy_id.c_str());
179 replacements.SetQueryStr(query);
180 return cloud_print_server_url.ReplaceComponents(replacements);
181 }
182
46 bool ParseResponseJSON(const std::string& response_data, 183 bool ParseResponseJSON(const std::string& response_data,
47 bool* succeeded, 184 bool* succeeded,
48 DictionaryValue** response_dict) { 185 DictionaryValue** response_dict) {
49 scoped_ptr<Value> message_value(base::JSONReader::Read(response_data)); 186 scoped_ptr<Value> message_value(base::JSONReader::Read(response_data));
50 if (!message_value.get()) 187 if (!message_value.get())
51 return false; 188 return false;
52 189
53 if (!message_value->IsType(Value::TYPE_DICTIONARY)) 190 if (!message_value->IsType(Value::TYPE_DICTIONARY))
54 return false; 191 return false;
55 192
56 scoped_ptr<DictionaryValue> response_dict_local( 193 scoped_ptr<DictionaryValue> response_dict_local(
57 static_cast<DictionaryValue*>(message_value.release())); 194 static_cast<DictionaryValue*>(message_value.release()));
58 if (succeeded && 195 if (succeeded &&
59 !response_dict_local->GetBoolean(cloud_print::kSuccessValue, succeeded)) 196 !response_dict_local->GetBoolean(cloud_print::kSuccessValue, succeeded))
60 *succeeded = false; 197 *succeeded = false;
61 if (response_dict) 198 if (response_dict)
62 *response_dict = response_dict_local.release(); 199 *response_dict = response_dict_local.release();
63 return true; 200 return true;
64 } 201 }
65 202
203 void ParsePrinterIdsFromListResponse(const std::string& response_data,
204 bool* succeeded,
205 std::set<std::string>* printer_ids) {
206 DCHECK(succeeded);
207 DCHECK(printer_ids);
208
209 DictionaryValue* response_dict = NULL;
210 ParseResponseJSON(response_data, succeeded, &response_dict);
211 scoped_ptr<DictionaryValue> response_dict_to_be_released(response_dict);
212
213 if (!(*succeeded) || !response_dict) {
214 printer_ids->clear();
215 return;
216 }
217
218 const ListValue* printer_list = NULL;
219 if (!response_dict->GetList(kPrinterListValue, &printer_list) ||
220 !printer_list) {
221 printer_ids->clear();
222 return;
223 }
224
225 for (size_t index = 0; index < printer_list->GetSize(); ++index) {
226 // Parse the printer id from the printer data.
227 const DictionaryValue* printer_data = NULL;
228 if (!printer_list->GetDictionary(index, &printer_data) || !printer_data)
229 continue;
230 std::string printer_id;
231 if (printer_data->GetString(kIdValue, &printer_id) && !printer_id.empty())
232 printer_ids->insert(printer_id);
233 }
234 }
235
236 void ParsePrinterIdFromRegisterResponse(const std::string& response_data,
237 bool* succeeded,
238 std::string* printer_id) {
239 DCHECK(succeeded);
240 DCHECK(printer_id);
241
242 DictionaryValue* response_dict = NULL;
243 ParseResponseJSON(response_data, succeeded, &response_dict);
244 scoped_ptr<DictionaryValue> response_dict_to_be_released(response_dict);
245
246 if (!(*succeeded) || !response_dict) {
247 printer_id->clear();
248 return;
249 }
250
251 const base::ListValue* printer_list = NULL;
252 if (!response_dict->GetList(cloud_print::kPrinterListValue, &printer_list) ||
253 !printer_list ||
254 printer_list->GetSize() != 1) {
255 printer_id->clear();
256 return;
257 }
258
259 const DictionaryValue* printer_data = NULL;
260 if (!printer_list->GetDictionary(0, &printer_data) || !printer_data) {
261 printer_id->clear();
262 return;
263 }
264
265 if (!printer_data->GetString(kIdValue, printer_id))
266 printer_id->clear();
267 }
268
66 void AddMultipartValueForUpload(const std::string& value_name, 269 void AddMultipartValueForUpload(const std::string& value_name,
67 const std::string& value, 270 const std::string& value,
68 const std::string& mime_boundary, 271 const std::string& mime_boundary,
69 const std::string& content_type, 272 const std::string& content_type,
70 std::string* post_data) { 273 std::string* post_data) {
71 DCHECK(post_data); 274 DCHECK(post_data);
72 // First line is the boundary 275 // First line is the boundary
73 post_data->append("--" + mime_boundary + "\r\n"); 276 post_data->append("--" + mime_boundary + "\r\n");
74 // Next line is the Content-disposition 277 // Next line is the Content-disposition
75 post_data->append(StringPrintf("Content-Disposition: form-data; " 278 post_data->append(StringPrintf("Content-Disposition: form-data; "
76 "name=\"%s\"\r\n", value_name.c_str())); 279 "name=\"%s\"\r\n", value_name.c_str()));
77 if (!content_type.empty()) { 280 if (!content_type.empty()) {
78 // If Content-type is specified, the next line is that 281 // If Content-type is specified, the next line is that
79 post_data->append(StringPrintf("Content-Type: %s\r\n", 282 post_data->append(StringPrintf("Content-Type: %s\r\n",
80 content_type.c_str())); 283 content_type.c_str()));
81 } 284 }
82 // Leave an empty line and append the value. 285 // Leave an empty line and append the value.
83 post_data->append(StringPrintf("\r\n%s\r\n", value.c_str())); 286 post_data->append(StringPrintf("\r\n%s\r\n", value.c_str()));
84 } 287 }
85 288
289 std::string GetMultipartMimeType(const std::string& mime_boundary) {
290 return std::string("multipart/form-data; boundary=") += mime_boundary;
291 }
292
86 // Create a MIME boundary marker (27 '-' characters followed by 16 hex digits). 293 // Create a MIME boundary marker (27 '-' characters followed by 16 hex digits).
87 void CreateMimeBoundaryForUpload(std::string* out) { 294 void CreateMimeBoundaryForUpload(std::string* out) {
88 int r1 = base::RandInt(0, kint32max); 295 int r1 = base::RandInt(0, kint32max);
89 int r2 = base::RandInt(0, kint32max); 296 int r2 = base::RandInt(0, kint32max);
90 base::SStringPrintf(out, "---------------------------%08X%08X", r1, r2); 297 base::SStringPrintf(out, "---------------------------%08X%08X", r1, r2);
91 } 298 }
92 299
300 std::string GetHashOfPrinterTags(const PrinterTags& printer_tags) {
301 PrinterTags printer_tags_prepared = PreparePrinterTags(printer_tags);
302 std::string values_list;
303 for (PrinterTags::const_iterator it = printer_tags_prepared.begin();
304 it != printer_tags_prepared.end(); ++it) {
305 values_list.append(it->first);
306 values_list.append(it->second);
307 }
308 return base::MD5String(values_list);
309 }
310
311 std::string GetPostDataForPrinterTags(
312 const PrinterTags& printer_tags,
313 const std::string& mime_boundary,
314 const std::string& proxy_tag_prefix,
315 const std::string& tags_hash_tag_name) {
316 PrinterTags printer_tags_prepared = PreparePrinterTags(printer_tags);
317 std::string post_data;
318 for (PrinterTags::const_iterator it = printer_tags.begin();
319 it != printer_tags.end(); ++it) {
320 // TODO(gene) Escape '=' char from name. Warning for now.
321 if (it->first.find('=') != std::string::npos) {
322 LOG(WARNING) <<
323 "CP_PROXY: Printer option name contains '=' character";
324 NOTREACHED();
325 }
326 // All our tags have a special prefix to identify them as such.
327 std::string msg(proxy_tag_prefix);
328 msg += it->first;
329 msg += "=";
330 msg += it->second;
331 cloud_print::AddMultipartValueForUpload(cloud_print::kPrinterTagValue, msg,
332 mime_boundary, std::string(), &post_data);
333 }
334 std::string tags_hash_msg(tags_hash_tag_name);
335 tags_hash_msg += "=";
336 tags_hash_msg += HashPrinterTags(printer_tags);
337 cloud_print::AddMultipartValueForUpload(cloud_print::kPrinterTagValue,
338 tags_hash_msg,
339 mime_boundary, std::string(),
340 &post_data);
341 return post_data;
342 }
343
93 } // namespace cloud_print 344 } // namespace cloud_print
OLDNEW
« no previous file with comments | « chrome/common/cloud_print/cloud_print_helpers.h ('k') | chrome/common/cloud_print/cloud_print_helpers_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698