[cups-devel] Using CUPS_HTTP_DEFAULT with cupsStartDestDocument/cupsWriteRequestData/cupsFinishDestDocument API (fwd)

Sam Varshavchik mrsam at courier-mta.com
Wed Jan 24 16:59:22 PST 2018


I'm following the sample code from  
https://www.cups.org/doc/cupspm.html#submitting-a-print-job with cups 2.2.4,  
and my results are that cupsFinishDestDocument() returns  
IPP_STATUS_ERROR_INTERNAL.

Digging into the code with gdb, the problem appears to be as follows. This  
is what happens at the very beginning of cupsFinishTestDocument() when it  
calls _cupsConnect(), because I'm passing CUPS_HTTP_DEFAULT, like the sample  
code does:

998         if (strcmp(cg->http->hostname, cg->server) ||
(gdb)
999             cg->ipp_port != httpAddrPort(cg->http->hostaddr) ||
(gdb)
998         if (strcmp(cg->http->hostname, cg->server) ||
(gdb)
1031            httpClose(cg->http);
(gdb) p cg->http->hostaddr
$1 = (http_addr_t *) 0x9c2dd8
(gdb) p *cg->http->hostaddr
$2 = {addr = {sa_family = 1, sa_data = "/var/run/cups/"}, ipv4 = {
    sin_family = 1, sin_port = 30255, sin_addr = {s_addr = 1915712097},
    sin_zero = "un/cups/"}, ipv6 = {sin6_family = 1, sin6_port = 30255,
    sin6_flowinfo = 1915712097, sin6_addr = {__in6_u = {
        __u6_addr8 = "un/cups/cups.soc", __u6_addr16 = {28277, 25391, 28789,
          12147, 30051, 29552, 29486, 25455}, __u6_addr32 = {1664052853,
          796094581, 1936749923, 1668248366}}}, sin6_scope_id = 107}, un = {
    sun_family = 1,
    sun_path = "/var/run/cups/cups.sock", '\000' <repeats 84 times>},
  pad = "\001\000/var/run/cups/cups.sock", '\000' <repeats 230 times>}
(gdb) p htons(30255)
$3 = 12150
(gdb) p cg->ipp_port
$4 = 631
(gdb) where
#0  _cupsConnect () at request.c:1031
#1  0x00007ffff6cec0d6 in cupsFinishDestDocument (http=<optimized out>,
    dest=0x965070, info=0x99c230) at dest-job.c:273


_cupsConnect() appears to decide to close the current http connection and  
open a new one, because of the mismatch between the current connection's  
port, and the IPP port:

cg->ipp_port != httpAddrPort(cg->http->hostaddr) ||

cg->http->hostaddr appears to be the port of my current connection to the  
scheduler, which is in the middle of submitting the print job; and not port  
631. So _cupsConnect() appears to be taking down my active connection, and  
creates a new one; and this ends up making cupsFinishDestDocument() very  
unhappy.

Rooting through the CUPS source, I see that cups/testdest.c also uses the  
cupsStartDestDocument(), cupsWriteRequestData(), and  
cupsFinishDestDocument() API; except that testdest.c does not use  
CUPS_HTTP_DEFAULT but, rather, appears to use additional API calls to  
establish a separate http connection for the purpose of submitting a print  
job.

Should I expect cupsStartDestDocument(), cupsWriteRequestData(), and  
cupsFinishDestDocument() to work with CUPS_HTTP_DEFAULT, like the sample  
code shows? Or is this a bug in cupsFinishDestDocument(). Looking at how  
cupsWriteRequestData() deals with CUPS_HTTP_DEFAULT: it does not call  
_cupsConnect(), but it calls _cupsGlobal() and manually fetches the global  
connection handle out of there. That seems to be what  
cupsFinishDestDocument() should be doing also.



More information about the cups-devel mailing list