OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #if !defined(OS_MACOSX) | 9 #if !defined(OS_MACOSX) |
10 #include <gcrypt.h> | 10 #include <gcrypt.h> |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 | 211 |
212 FilePath PrintBackendCUPS::GetPPD(const char* name) { | 212 FilePath PrintBackendCUPS::GetPPD(const char* name) { |
213 // cupsGetPPD returns a filename stored in a static buffer in CUPS. | 213 // cupsGetPPD returns a filename stored in a static buffer in CUPS. |
214 // Protect this code with lock. | 214 // Protect this code with lock. |
215 static Lock ppd_lock; | 215 static Lock ppd_lock; |
216 AutoLock ppd_autolock(ppd_lock); | 216 AutoLock ppd_autolock(ppd_lock); |
217 FilePath ppd_path; | 217 FilePath ppd_path; |
218 const char* ppd_file_path = NULL; | 218 const char* ppd_file_path = NULL; |
219 if (print_server_url_.is_empty()) { // Use default (local) print server. | 219 if (print_server_url_.is_empty()) { // Use default (local) print server. |
220 ppd_file_path = cupsGetPPD(name); | 220 ppd_file_path = cupsGetPPD(name); |
| 221 if (ppd_file_path) |
| 222 ppd_path = FilePath(ppd_file_path); |
221 } else { | 223 } else { |
| 224 // cupsGetPPD2 gets stuck sometimes in an infinite time due to network |
| 225 // configuration/issues. To prevent that, use non-blocking http connection |
| 226 // here. |
| 227 // Note: After looking at CUPS sources, it looks like non-blocking |
| 228 // connection will timeout after 10 seconds of no data period. And it will |
| 229 // return the same way as if data was completely and sucessfully downloaded. |
| 230 // To distinguish error case from the normal return, will check result file |
| 231 // size agains content length. |
222 HttpConnectionCUPS http(print_server_url_); | 232 HttpConnectionCUPS http(print_server_url_); |
| 233 http.SetBlocking(false); |
223 ppd_file_path = cupsGetPPD2(http.http(), name); | 234 ppd_file_path = cupsGetPPD2(http.http(), name); |
| 235 // Check if the get full PPD, since non-blocking call may simply return |
| 236 // normally after timeout expired. |
| 237 if (ppd_file_path) { |
| 238 ppd_path = FilePath(ppd_file_path); |
| 239 off_t content_len = httpGetLength2(http.http()); |
| 240 int64 ppd_size = 0; |
| 241 // This is a heuristic to detect if we reached timeout. If we see content |
| 242 // length is larger that the actual file we downloaded it means timeout |
| 243 // reached. Sometimes http can be compressed, and in that case the |
| 244 // the content length will be smaller than the actual payload (not sure |
| 245 // if CUPS support such responses). |
| 246 if (!file_util::GetFileSize(ppd_path, &ppd_size) || |
| 247 content_len > ppd_size) { |
| 248 LOG(ERROR) << "Error downloading PPD file for: " << name |
| 249 << ", file size: " << ppd_size |
| 250 << ", content length: " << content_len; |
| 251 file_util::Delete(ppd_path, false); |
| 252 ppd_path.clear(); |
| 253 } |
| 254 } |
224 } | 255 } |
225 if (ppd_file_path) | |
226 ppd_path = FilePath(ppd_file_path); | |
227 return ppd_path; | 256 return ppd_path; |
228 } | 257 } |
229 | 258 |
230 } // namespace printing | 259 } // namespace printing |
OLD | NEW |