New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcups and CUPS 1.1.x servers #1528

Closed
michaelrsweet opened this Issue Mar 31, 2006 · 6 comments

Comments

Projects
None yet
1 participant
@michaelrsweet
Collaborator

michaelrsweet commented Mar 31, 2006

Version: 1.2rc1
CUPS.org User: twaugh.redhat

It seems that libcups from cups-1.2rc1 is having problems communicating with CUPS-1.1.23 servers. Example, on a machine running CUPS-1.1.23 but with an application using CUPS-1.2rc1's libcups via LD_LIBRARY_PATH:

[pid 13917] connect(17, {sa_family=AF_INET, sin_port=htons(631), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
[pid 13917] send(17, "POST / HTTP/1.1\r\n", 17, 0) = 17
[pid 13917] send(17, "Content-Length: 75\r\n", 20, 0) = 20
[pid 13917] send(17, "Content-Type: application/ipp\r\n", 31, 0) = 31
[pid 13917] send(17, "Host: localhost\r\n", 17, 0) = 17
[pid 13917] send(17, "User-Agent: CUPS/1.2rc1\r\n", 25, 0) = 25
[pid 13917] send(17, "Expect: 100-continue\r\n", 22, 0) = 22
[pid 13917] send(17, "\r\n", 2, 0) = 2
[pid 13917] getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0
[pid 13917] select(18, [17], NULL, NULL, {1, 0}) = 1 (in [17], left {0, 0})
[pid 13917] recv(17, "HTTP/1.1 400 Bad Request\r\nDate: Fri, 31 Mar 2006 13:13:36 GMT\r\nServer: CUPS/1.1\r\nContent-Language: en_US\r\nUpgrade: TLS/1.0,HTTP/1.1\r\nConnection: close\r\nContent-Type: text/html\r\nContent-Length: 156\r\n\r\n<TITLE>400 Bad Request</TITLE>

Bad Request

Your
browser sent a request that this server could not understand.\n",
2048, 0) = 356

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Mar 31, 2006

CUPS.org User: mike

I haven't see this show up with testing in our lab, but will do some more testing to see if I can duplicate it here...

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Mar 31, 2006

CUPS.org User: mike

OK, I was able to duplicate on my development system. The 1.1.x server is getting an IPP read error for some reason...

Ethereal shows a perfect IPP request, but unlike 1.1.x the whole request comes in a single TCP packet - perhaps it doesn't like that?

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Mar 31, 2006

CUPS.org User: mike

OK, looks like the timeout over the loopback interface is the problem - if I bump the httpWait() timeout in ipp_read_http() to 10000 msec, everything works OK.

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Mar 31, 2006

CUPS.org User: mike

Ha, found the problem!

It was the Expect: stuff - basically, the code would wait up to 1 second to read the 100-continue response, but 1.1.x doesn't return the response...

Working on a patch now...

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Mar 31, 2006

CUPS.org User: mike

Fixed in Subversion repository.

OK, the problem was caused by the use of the Expect: header.

CUPS 1.1.x did not support Expect: 100-continue

CUPS 1.2 does, and uses it so that we can get early notification of authentication/authorization/upgrade errors - basically so you don't send a print file without the necessary limits.

The cupsDoFileRequest() code would send the POST, wait up to 1 second for a response, and then send the IPP request followed by the data.

The CUPS 1.1.x scheduler would get the POST, wait up to 1 second for the IPP request header, and then error out.

The solution I've committed (patch attached) basically sends the POST and IPP request, and then checks (if necessary) for the server response.

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Apr 14, 2006

"str1528.patch":

Index: request.c

--- request.c (revision 5361)
+++ request.c (working copy)
@@ -64,6 +64,7 @@
ipp_t response; / IPP response data /
size_t length; /
Content-Length value /
http_status_t status; /
Status of HTTP request */

  • int got_status; /* Did we get the status? /
    ipp_state_t state; /
    State of IPP processing /
    FILE *file; /
    File to send /
    struct stat fileinfo; /
    File information */
    @@ -184,54 +185,58 @@
    }

/*

  • * Wait up to 1 second for a 100-continue response...
    • Send the IPP data...
      */
  • if (httpWait(http, 1000))
  • DEBUG_puts("cupsDoFileRequest: ipp write...");
  • request->state = IPP_IDLE;
  • status = HTTP_CONTINUE;
  • got_status = 0;
  • while ((state = ippWrite(http, request)) != IPP_DATA)

  •  if (state == IPP_ERROR)
    
  • break;

  •  else if (httpCheck(http))
    
  •  {
    
  •    got_status = 1;
    
  • if ((status = httpUpdate(http)) != HTTP_CONTINUE)

  • break;
    
  •  }
    
  • if (!got_status)

  • {

  • /*
    
  •  \* Wait up to 1 second to get the 100-continue response...
    
  •  */
    
  •  if (httpWait(http, 1000))
    
  •    status = httpUpdate(http);
    
  • }

  • else if (httpCheck(http))
    status = httpUpdate(http);

  • else

  •  status = HTTP_CONTINUE;
    
  • if (status == HTTP_CONTINUE)

  • if (status == HTTP_CONTINUE && state == IPP_DATA && filename)
    {

  •  DEBUG_puts("cupsDoFileRequest: file write...");
    
    • /*
  •  \* Send the IPP data...
    
  •  * Send the file...
    

    */

  •  DEBUG_puts("cupsDoFileRequest: ipp write...");
    
  •  rewind(file);
    

- request->state = IPP_IDLE;

  •  while ((state = ippWrite(http, request)) != IPP_DATA)
    
  •    if (state == IPP_ERROR)
    
  • break;
    
  • else if (httpCheck(http))
  •  while ((bytes = (int)fread(buffer, 1, sizeof(buffer), file)) > 0)
    
  •  {
    
  • if (httpCheck(http))
    {
    if ((status = httpUpdate(http)) != HTTP_CONTINUE)
    break;
    }
  •  if (state == IPP_DATA && filename)
    
  •  {
    

- DEBUG_puts("cupsDoFileRequest: file write...");

  •   /*
    
  •    \* Send the file...
    

- */

- rewind(file);

  •    while ((bytes = (int)fread(buffer, 1, sizeof(buffer), file)) > 0)
    
  • {
  • if (httpCheck(http))
    
  • {
    
  •   if ((status = httpUpdate(http)) != HTTP_CONTINUE)
    
  •     break;
    

- }

  • if (httpWrite2(http, buffer, bytes) < bytes)
    
  •        break;
    
  •    }
    
  • if (httpWrite2(http, buffer, bytes) < bytes)
  •      break;
    
    }
    }

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment