diff options
Diffstat (limited to 'printing')
-rw-r--r-- | printing/backend/cups_helper.cc | 4 | ||||
-rw-r--r-- | printing/backend/cups_helper.h | 2 | ||||
-rw-r--r-- | printing/backend/print_backend_cups.cc | 33 |
3 files changed, 37 insertions, 2 deletions
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc index 2c3b853..7df5302 100644 --- a/printing/backend/cups_helper.cc +++ b/printing/backend/cups_helper.cc @@ -37,6 +37,10 @@ HttpConnectionCUPS::~HttpConnectionCUPS() { httpClose(http_); } +void HttpConnectionCUPS::SetBlocking(bool blocking) { + httpBlocking(http_, blocking ? 1 : 0); +} + http_t* HttpConnectionCUPS::http() { return http_; } diff --git a/printing/backend/cups_helper.h b/printing/backend/cups_helper.h index 16841bc..1237468 100644 --- a/printing/backend/cups_helper.h +++ b/printing/backend/cups_helper.h @@ -20,6 +20,8 @@ class HttpConnectionCUPS { explicit HttpConnectionCUPS(const GURL& print_server_url); ~HttpConnectionCUPS(); + void SetBlocking(bool blocking); + http_t* http(); private: diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc index 5419358..9fbf2ab 100644 --- a/printing/backend/print_backend_cups.cc +++ b/printing/backend/print_backend_cups.cc @@ -218,12 +218,41 @@ FilePath PrintBackendCUPS::GetPPD(const char* name) { const char* ppd_file_path = NULL; if (print_server_url_.is_empty()) { // Use default (local) print server. ppd_file_path = cupsGetPPD(name); + if (ppd_file_path) + ppd_path = FilePath(ppd_file_path); } else { + // cupsGetPPD2 gets stuck sometimes in an infinite time due to network + // configuration/issues. To prevent that, use non-blocking http connection + // here. + // Note: After looking at CUPS sources, it looks like non-blocking + // connection will timeout after 10 seconds of no data period. And it will + // return the same way as if data was completely and sucessfully downloaded. + // To distinguish error case from the normal return, will check result file + // size agains content length. HttpConnectionCUPS http(print_server_url_); + http.SetBlocking(false); ppd_file_path = cupsGetPPD2(http.http(), name); + // Check if the get full PPD, since non-blocking call may simply return + // normally after timeout expired. + if (ppd_file_path) { + ppd_path = FilePath(ppd_file_path); + off_t content_len = httpGetLength2(http.http()); + int64 ppd_size = 0; + // This is a heuristic to detect if we reached timeout. If we see content + // length is larger that the actual file we downloaded it means timeout + // reached. Sometimes http can be compressed, and in that case the + // the content length will be smaller than the actual payload (not sure + // if CUPS support such responses). + if (!file_util::GetFileSize(ppd_path, &ppd_size) || + content_len > ppd_size) { + LOG(ERROR) << "Error downloading PPD file for: " << name + << ", file size: " << ppd_size + << ", content length: " << content_len; + file_util::Delete(ppd_path, false); + ppd_path.clear(); + } + } } - if (ppd_file_path) - ppd_path = FilePath(ppd_file_path); return ppd_path; } |