Index: cups/http.c =================================================================== --- cups/http.c (revision 5871) +++ cups/http.c (working copy) @@ -1100,15 +1100,20 @@ DEBUG_printf(("httpPrintf: %s", buf)); - if (http->wused) + if (http->data_encoding == HTTP_ENCODE_FIELDS) + return (httpWrite2(http, buf, bytes)); + else { - DEBUG_puts(" flushing existing data..."); + if (http->wused) + { + DEBUG_puts(" flushing existing data..."); - if (httpFlushWrite(http) < 0) - return (-1); + if (httpFlushWrite(http) < 0) + return (-1); + } + + return (http_write(http, buf, bytes)); } - - return (http_write(http, buf, bytes)); } @@ -1888,7 +1893,7 @@ httpFlushWrite(http); } - if ((length + http->wused) <= sizeof(http->wbuffer)) + if ((length + http->wused) < sizeof(http->wbuffer)) { /* * Write to buffer... @@ -2155,10 +2160,19 @@ return (-1); /* + * Flush any written data that is pending... + */ + + if (http->wused) + httpFlushWrite(http); + + /* * Send the request header... */ - http->state = request; + http->state = request; + http->data_encoding = HTTP_ENCODE_FIELDS; + if (request == HTTP_POST || request == HTTP_PUT) http->state ++; @@ -2211,6 +2225,7 @@ return (-1); } + httpFlushWrite(http); httpGetLength2(http); httpClearFields(http); Index: cups/http.h =================================================================== --- cups/http.h (revision 5871) +++ cups/http.h (working copy) @@ -142,7 +142,8 @@ typedef enum http_encoding_e /**** HTTP transfer encoding values ****/ { HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ - HTTP_ENCODE_CHUNKED /* Data is chunked */ + HTTP_ENCODE_CHUNKED, /* Data is chunked */ + HTTP_ENCODE_FIELDS /* Sending HTTP fields */ } http_encoding_t; typedef enum http_encryption_e /**** HTTP encryption values ****/ Index: scheduler/client.c =================================================================== --- scheduler/client.c (revision 5882) +++ scheduler/client.c (working copy) @@ -26,6 +26,7 @@ * cupsdAcceptClient() - Accept a new client. * cupsdCloseAllClients() - Close all remote clients immediately. * cupsdCloseClient() - Close a remote client. + * cupsdFlushHeader() - Flush the header fields to the client. * cupsdReadClient() - Read data from a client. * cupsdSendCommand() - Send output from a command via HTTP. * cupsdSendError() - Send an error message via HTTP. @@ -674,6 +675,19 @@ /* + * 'cupsdFlushHeader()' - Flush the header fields to the client. + */ + +void +cupsdFlushHeader(cupsd_client_t *con) /* I - Client to flush to */ +{ + httpFlushWrite(HTTP(con)); + + con->http.data_encoding = HTTP_ENCODE_LENGTH; +} + + +/* * 'cupsdReadClient()' - Read data from a client. */ @@ -1024,6 +1038,7 @@ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n"); httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); + cupsdFlushHeader(con); encrypt_client(con); #else @@ -1038,6 +1053,7 @@ httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n"); httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); + cupsdFlushHeader(con); } else if (!is_path_absolute(con->uri)) { @@ -1065,6 +1081,7 @@ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n"); httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); + cupsdFlushHeader(con); encrypt_client(con); #else @@ -1105,6 +1122,7 @@ httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); + cupsdFlushHeader(con); } } @@ -1538,6 +1556,8 @@ if (httpPrintf(HTTP(con), "\r\n") < 0) return (cupsdCloseClient(con)); + cupsdFlushHeader(con); + cupsdLogRequest(con, HTTP_OK); } else if ((!strncmp(con->uri, "/admin/conf/", 12) && @@ -1601,6 +1621,8 @@ if (httpPrintf(HTTP(con), "\r\n") < 0) return (cupsdCloseClient(con)); + cupsdFlushHeader(con); + con->http.state = HTTP_WAITING; break; @@ -2074,6 +2096,8 @@ else if (httpPrintf(HTTP(con), "\r\n") < 0) return (0); + cupsdFlushHeader(con); + con->http.state = HTTP_WAITING; return (1); @@ -2093,6 +2117,10 @@ * Send the HTTP status header... */ + httpFlushWrite(HTTP(con)); + + con->http.data_encoding = HTTP_ENCODE_FIELDS; + if (httpPrintf(HTTP(con), "HTTP/%d.%d %d %s\r\n", con->http.version / 100, con->http.version % 100, code, httpStatus(code)) < 0) return (0); @@ -2106,7 +2134,10 @@ if (httpPrintf(HTTP(con), "\r\n") < 0) return (0); else + { + cupsdFlushHeader(con); return (1); + } } if (httpPrintf(HTTP(con), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0) @@ -2191,7 +2222,7 @@ if (!strchr(CGIStatusBuffer->buffer, '\n')) break; - if (ptr == NULL && errno) + if (ptr == NULL && !CGIStatusBuffer->bufused) { /* * Fatal error on pipe - should never happen! @@ -2281,8 +2312,6 @@ if (con->http.version == HTTP_1_1) { - con->http.data_encoding = HTTP_ENCODE_CHUNKED; - if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n") < 0) return (0); } @@ -2310,7 +2339,14 @@ */ if (con->field_col == 0) + { con->got_fields = 1; + + cupsdFlushHeader(con); + + if (con->http.version == HTTP_1_1) + con->http.data_encoding = HTTP_ENCODE_CHUNKED; + } else con->field_col = 0; } @@ -4086,6 +4122,8 @@ if (httpPrintf(HTTP(con), "\r\n") < 0) return (0); + cupsdFlushHeader(con); + con->http.data_encoding = HTTP_ENCODE_LENGTH; con->http.data_remaining = filestats->st_size; Index: scheduler/client.h =================================================================== --- scheduler/client.h (revision 5871) +++ scheduler/client.h (working copy) @@ -104,6 +104,7 @@ extern void cupsdCloseAllClients(void); extern int cupsdCloseClient(cupsd_client_t *con); extern void cupsdDeleteAllListeners(void); +extern void cupsdFlushHeader(cupsd_client_t *con); extern void cupsdPauseListening(void); extern int cupsdProcessIPPRequest(cupsd_client_t *con); extern int cupsdReadClient(cupsd_client_t *con); Index: scheduler/ipp.c =================================================================== --- scheduler/ipp.c (revision 5874) +++ scheduler/ipp.c (working copy) @@ -629,7 +629,7 @@ #ifdef CUPSD_USE_CHUNKING /* * Because older versions of CUPS (1.1.17 and older) and some IPP - * clients do not implement chunking properly, we should not use + * clients do not implement chunking properly, we cannot use * chunking by default. This may become the default in future * CUPS releases, or we might add a configuration directive for * it. @@ -637,23 +637,25 @@ if (con->http.version == HTTP_1_1) { + httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n"); + cupsdFlushHeader(con); + con->http.data_encoding = HTTP_ENCODE_CHUNKED; - - httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n"); } else #endif /* CUPSD_USE_CHUNKING */ { - con->http.data_encoding = HTTP_ENCODE_LENGTH; - con->http.data_remaining = ippLength(con->response); + size_t length; /* Length of response */ - if (con->http.data_remaining < INT_MAX) - con->http._data_remaining = con->http.data_remaining; - else - con->http._data_remaining = INT_MAX; + length = ippLength(con->response); + httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n", - CUPS_LLCAST con->http.data_remaining); + CUPS_LLCAST length); + cupsdFlushHeader(con); + + con->http.data_encoding = HTTP_ENCODE_LENGTH; + con->http.data_remaining = length; } cupsdLogMessage(CUPSD_LOG_DEBUG2, Index: scheduler/dirsvc.c =================================================================== --- scheduler/dirsvc.c (revision 5871) +++ scheduler/dirsvc.c (working copy) @@ -1626,7 +1626,7 @@ if (!strchr(PollStatusBuffer->buffer, '\n')) break; - if (ptr == NULL && errno) + if (ptr == NULL && !PollStatusBuffer->bufused) { /* * All polling processes have died; stop polling... Index: scheduler/statbuf.c =================================================================== --- scheduler/statbuf.c (revision 5871) +++ scheduler/statbuf.c (working copy) @@ -141,13 +141,6 @@ /* - * Clear the errno variable since not all systems clear it after a - * successful read... - */ - - errno = 0; - - /* * Check if the buffer already contains a full line... */ @@ -179,7 +172,6 @@ *loglevel = CUPSD_LOG_NONE; line[0] = '\0'; - errno = 0; return (line); } @@ -201,7 +193,7 @@ lineptr = NULL; } - if (lineptr == NULL) + if (!lineptr) { /* * End of file... Index: scheduler/job.c =================================================================== --- scheduler/job.c (revision 5875) +++ scheduler/job.c (working copy) @@ -1717,7 +1717,7 @@ break; } - if (ptr == NULL && errno) + if (ptr == NULL && !job->status_buffer->bufused) { /* * See if all of the filters and the backend have returned their