Skip to content

Commit

Permalink
cupsGetPPD got stuck sometime for an infinite time due to network con…
Browse files Browse the repository at this point in the history
…figuration/issues.

Make http connection for cupsGetPPD non-blocking to prevent that.

BUG=none
TEST=Make sure GettPPD does not get stuck.

Review URL: http://codereview.chromium.org/5609004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68356 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gene@google.com committed Dec 6, 2010
1 parent 73c4793 commit 5a49cdc
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
4 changes: 4 additions & 0 deletions printing/backend/cups_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ HttpConnectionCUPS::~HttpConnectionCUPS() {
httpClose(http_);
}

void HttpConnectionCUPS::SetBlocking(bool blocking) {
httpBlocking(http_, blocking ? 1 : 0);
}

http_t* HttpConnectionCUPS::http() {
return http_;
}
Expand Down
2 changes: 2 additions & 0 deletions printing/backend/cups_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class HttpConnectionCUPS {
explicit HttpConnectionCUPS(const GURL& print_server_url);
~HttpConnectionCUPS();

void SetBlocking(bool blocking);

http_t* http();

private:
Expand Down
33 changes: 31 additions & 2 deletions printing/backend/print_backend_cups.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit 5a49cdc

Please sign in to comment.