summaryrefslogtreecommitdiffstats
path: root/printing
diff options
context:
space:
mode:
Diffstat (limited to 'printing')
-rw-r--r--printing/backend/cups_helper.cc4
-rw-r--r--printing/backend/cups_helper.h2
-rw-r--r--printing/backend/print_backend_cups.cc33
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;
}