OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "printing/backend/print_backend.h" | 5 #include "printing/backend/print_backend.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 121 |
122 protected: | 122 protected: |
123 virtual ~PrintBackendCUPS() {} | 123 virtual ~PrintBackendCUPS() {} |
124 | 124 |
125 private: | 125 private: |
126 // Following functions are wrappers around corresponding CUPS functions. | 126 // Following functions are wrappers around corresponding CUPS functions. |
127 // <functions>2() are called when print server is specified, and plain | 127 // <functions>2() are called when print server is specified, and plain |
128 // version in another case. There is an issue specifing CUPS_HTTP_DEFAULT | 128 // version in another case. There is an issue specifing CUPS_HTTP_DEFAULT |
129 // in the <functions>2(), it does not work in CUPS prior to 1.4. | 129 // in the <functions>2(), it does not work in CUPS prior to 1.4. |
130 int GetDests(cups_dest_t** dests); | 130 int GetDests(cups_dest_t** dests); |
131 FilePath GetPPD(const char* name); | 131 base::FilePath GetPPD(const char* name); |
132 | 132 |
133 GURL print_server_url_; | 133 GURL print_server_url_; |
134 http_encryption_t cups_encryption_; | 134 http_encryption_t cups_encryption_; |
135 bool blocking_; | 135 bool blocking_; |
136 }; | 136 }; |
137 | 137 |
138 PrintBackendCUPS::PrintBackendCUPS(const GURL& print_server_url, | 138 PrintBackendCUPS::PrintBackendCUPS(const GURL& print_server_url, |
139 http_encryption_t encryption, | 139 http_encryption_t encryption, |
140 bool blocking) | 140 bool blocking) |
141 : print_server_url_(print_server_url), | 141 : print_server_url_(print_server_url), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } | 228 } |
229 | 229 |
230 bool PrintBackendCUPS::GetPrinterCapsAndDefaults( | 230 bool PrintBackendCUPS::GetPrinterCapsAndDefaults( |
231 const std::string& printer_name, | 231 const std::string& printer_name, |
232 PrinterCapsAndDefaults* printer_info) { | 232 PrinterCapsAndDefaults* printer_info) { |
233 DCHECK(printer_info); | 233 DCHECK(printer_info); |
234 | 234 |
235 VLOG(1) << "CUPS: Getting caps and defaults" | 235 VLOG(1) << "CUPS: Getting caps and defaults" |
236 << ", printer name: " << printer_name; | 236 << ", printer name: " << printer_name; |
237 | 237 |
238 FilePath ppd_path(GetPPD(printer_name.c_str())); | 238 base::FilePath ppd_path(GetPPD(printer_name.c_str())); |
239 // In some cases CUPS failed to get ppd file. | 239 // In some cases CUPS failed to get ppd file. |
240 if (ppd_path.empty()) { | 240 if (ppd_path.empty()) { |
241 LOG(ERROR) << "CUPS: Failed to get PPD" | 241 LOG(ERROR) << "CUPS: Failed to get PPD" |
242 << ", printer name: " << printer_name; | 242 << ", printer name: " << printer_name; |
243 return false; | 243 return false; |
244 } | 244 } |
245 | 245 |
246 std::string content; | 246 std::string content; |
247 bool res = file_util::ReadFileToString(ppd_path, &content); | 247 bool res = file_util::ReadFileToString(ppd_path, &content); |
248 | 248 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 http.SetBlocking(blocking_); | 325 http.SetBlocking(blocking_); |
326 return cupsGetDests2(http.http(), dests); | 326 return cupsGetDests2(http.http(), dests); |
327 } | 327 } |
328 } | 328 } |
329 | 329 |
330 FilePath PrintBackendCUPS::GetPPD(const char* name) { | 330 FilePath PrintBackendCUPS::GetPPD(const char* name) { |
331 // cupsGetPPD returns a filename stored in a static buffer in CUPS. | 331 // cupsGetPPD returns a filename stored in a static buffer in CUPS. |
332 // Protect this code with lock. | 332 // Protect this code with lock. |
333 CR_DEFINE_STATIC_LOCAL(base::Lock, ppd_lock, ()); | 333 CR_DEFINE_STATIC_LOCAL(base::Lock, ppd_lock, ()); |
334 base::AutoLock ppd_autolock(ppd_lock); | 334 base::AutoLock ppd_autolock(ppd_lock); |
335 FilePath ppd_path; | 335 base::FilePath ppd_path; |
336 const char* ppd_file_path = NULL; | 336 const char* ppd_file_path = NULL; |
337 if (print_server_url_.is_empty()) { // Use default (local) print server. | 337 if (print_server_url_.is_empty()) { // Use default (local) print server. |
338 ppd_file_path = cupsGetPPD(name); | 338 ppd_file_path = cupsGetPPD(name); |
339 if (ppd_file_path) | 339 if (ppd_file_path) |
340 ppd_path = FilePath(ppd_file_path); | 340 ppd_path = base::FilePath(ppd_file_path); |
341 } else { | 341 } else { |
342 // cupsGetPPD2 gets stuck sometimes in an infinite time due to network | 342 // cupsGetPPD2 gets stuck sometimes in an infinite time due to network |
343 // configuration/issues. To prevent that, use non-blocking http connection | 343 // configuration/issues. To prevent that, use non-blocking http connection |
344 // here. | 344 // here. |
345 // Note: After looking at CUPS sources, it looks like non-blocking | 345 // Note: After looking at CUPS sources, it looks like non-blocking |
346 // connection will timeout after 10 seconds of no data period. And it will | 346 // connection will timeout after 10 seconds of no data period. And it will |
347 // return the same way as if data was completely and sucessfully downloaded. | 347 // return the same way as if data was completely and sucessfully downloaded. |
348 HttpConnectionCUPS http(print_server_url_, cups_encryption_); | 348 HttpConnectionCUPS http(print_server_url_, cups_encryption_); |
349 http.SetBlocking(blocking_); | 349 http.SetBlocking(blocking_); |
350 ppd_file_path = cupsGetPPD2(http.http(), name); | 350 ppd_file_path = cupsGetPPD2(http.http(), name); |
351 // Check if the get full PPD, since non-blocking call may simply return | 351 // Check if the get full PPD, since non-blocking call may simply return |
352 // normally after timeout expired. | 352 // normally after timeout expired. |
353 if (ppd_file_path) { | 353 if (ppd_file_path) { |
354 // There is no reliable way right now to detect full and complete PPD | 354 // There is no reliable way right now to detect full and complete PPD |
355 // get downloaded. If we reach http timeout, it may simply return | 355 // get downloaded. If we reach http timeout, it may simply return |
356 // downloaded part as a full response. It might be good enough to check | 356 // downloaded part as a full response. It might be good enough to check |
357 // http->data_remaining or http->_data_remaining, unfortunately http_t | 357 // http->data_remaining or http->_data_remaining, unfortunately http_t |
358 // is an internal structure and fields are not exposed in CUPS headers. | 358 // is an internal structure and fields are not exposed in CUPS headers. |
359 // httpGetLength or httpGetLength2 returning the full content size. | 359 // httpGetLength or httpGetLength2 returning the full content size. |
360 // Comparing file size against that content length might be unreliable | 360 // Comparing file size against that content length might be unreliable |
361 // since some http reponses are encoded and content_length > file size. | 361 // since some http reponses are encoded and content_length > file size. |
362 // Let's just check for the obvious CUPS and http errors here. | 362 // Let's just check for the obvious CUPS and http errors here. |
363 ppd_path = FilePath(ppd_file_path); | 363 ppd_path = base::FilePath(ppd_file_path); |
364 ipp_status_t error_code = cupsLastError(); | 364 ipp_status_t error_code = cupsLastError(); |
365 int http_error = httpError(http.http()); | 365 int http_error = httpError(http.http()); |
366 if (error_code > IPP_OK_EVENTS_COMPLETE || http_error != 0) { | 366 if (error_code > IPP_OK_EVENTS_COMPLETE || http_error != 0) { |
367 LOG(ERROR) << "Error downloading PPD file" | 367 LOG(ERROR) << "Error downloading PPD file" |
368 << ", name: " << name | 368 << ", name: " << name |
369 << ", CUPS error: " << static_cast<int>(error_code) | 369 << ", CUPS error: " << static_cast<int>(error_code) |
370 << ", HTTP error: " << http_error; | 370 << ", HTTP error: " << http_error; |
371 file_util::Delete(ppd_path, false); | 371 file_util::Delete(ppd_path, false); |
372 ppd_path.clear(); | 372 ppd_path.clear(); |
373 } | 373 } |
374 } | 374 } |
375 } | 375 } |
376 return ppd_path; | 376 return ppd_path; |
377 } | 377 } |
378 | 378 |
379 } // namespace printing | 379 } // namespace printing |
OLD | NEW |