cupsPrintFile() has no streaming equivalent?

mike dizaemon at hotmail.com
Fri Feb 23 10:55:59 PST 2007


> mike wrote:
> > from what i can tell from both the API documentation as well as the
> > source of cups/util.c and cups/request.c, cups provides no method of
> > streaming a file to the print server.  i hope that i am merely
> > overlooking something and the cups API is not crippled in this way.
>
> CUPS is not "crippled" this way, but does not provide a convenience
> API to handle streamed printing.  File a feature request with the
> kind of API you'd like to see...
>
> If you look at the cupsDoFileRequest code in cups/request.c, you'll
> see how to use the lower-level HTTP and IPP APIs to stream your
> content to the CUPS server.

well, i've got a completely working implementation that is completely broken.

i don't know the length beforehand, so i don't call httpSetLength; this completely breaks everything.  if i call httpSetLength and set it to the actual length of the input, everything works great.  however, this is suboptimal.

cupsd sits in scheduler/client.c:1839 calling httpRead2 from cupsdReadClient, which times out after a few seconds.  HTTP state is HTTP_POST_RECV, which, at line 1869, causes cupsdReadClient to return 1 without closing the connection.

basically, it appears that the client and server deadlock as the client waits for the server to send it a response and the server waits for the client to send it more data.

i don't think there's a way around it without explicitly setting the Content-Length header.  i don't know enough about the internals (and i've learned a lot over the past 24 hours) to be able to say.  if there was some type of chunked/segmented file transfer method where set blocks of the file are transferred at a time, then perhaps the streaming method would work.  is there such support in cups?  transferring 4K blocks of the file at a time through multiple HTTP requests in a single connection?  Content-Length: 4096, Content-Length: 4096, Content-Length: 4096, etc...

otherwise, i can modify my cupsPrintStream to expect a length argument.  while this might be fine for small input, it sucks for large files.  take lpr, for instance...

since lpr's STDIN printing mode simply writes all the data back out to disk and then stats() the resulting file, it saves memory usage.  if it were to use the streaming mode, it would have to buffer everything in memory in order to determine the Content-Length, which, for large inputs on stdin, could be bad.

what i can do is change lpr back to the temporary file method, add the length argument to cupsPrintStream and then put the onus on the user to find out what the length is.

i'll have a working patch today if anyone would like to help test it.

-mike





More information about the cups mailing list