Skip to content
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

httpPrintf not buffered #1899

Closed
michaelrsweet opened this issue Aug 9, 2006 · 2 comments
Closed

httpPrintf not buffered #1899

michaelrsweet opened this issue Aug 9, 2006 · 2 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.2-current
CUPS.org User: mike

httpPrintf is not buffering its output. Need to add code to handle output buffering prior to starting the request body.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Patch for this is attached (also includes unrelated fix for STR #1892)

@michaelrsweet
Copy link
Collaborator Author

"str1899.patch":

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

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

No branches or pull requests

1 participant