]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/http.c
Load cups into easysw/current.
[thirdparty/cups.git] / cups / http.c
index dc0da38927b7446afd60b5d40e6f7c30308c6557..504be39cfeff245e80d194413c48a7cd4bb50af9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http.c 5222 2006-03-03 18:57:56Z mike $"
+ * "$Id: http.c 5889 2006-08-24 21:44:35Z mike $"
  *
  *   HTTP routines for the Common UNIX Printing System (CUPS).
  *
@@ -539,6 +539,8 @@ httpGetBlocking(http_t *http)               /* I - HTTP connection */
 
 /*
  * 'httpGetCookie()' - Get any cookie data from the response.
+ *
+ * @since CUPS 1.1.19@
  */
 
 const char *                           /* O - Cookie data or NULL */
@@ -864,8 +866,12 @@ httpGets(char   *line,                     /* I - Line to read into */
       * No newline; see if there is more data to be read...
       */
 
-      if (!http->blocking && !http_wait(http, 1000))
+      if (!http->blocking && !http_wait(http, 10000))
+      {
+        DEBUG_puts("httpGets: Timed out!");
+        http->error = ETIMEDOUT;
         return (NULL);
+      }
 
 #ifdef HAVE_SSL
       if (http->tls)
@@ -1094,15 +1100,20 @@ httpPrintf(http_t     *http,            /* I - HTTP connection */
 
   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));
+  }
 }
 
 
@@ -1216,7 +1227,7 @@ httpRead2(http_t *http,                   /* I - HTTP connection */
     * Buffer small reads for better performance...
     */
 
-    if (!http->blocking && !httpWait(http, 1000))
+    if (!http->blocking && !httpWait(http, 10000))
       return (0);
 
     if (http->data_remaining > sizeof(http->buffer))
@@ -1279,7 +1290,7 @@ httpRead2(http_t *http,                   /* I - HTTP connection */
 #ifdef HAVE_SSL
   else if (http->tls)
   {
-    if (!http->blocking && !httpWait(http, 1000))
+    if (!http->blocking && !httpWait(http, 10000))
       return (0);
 
     bytes = http_read_ssl(http, buffer, length);
@@ -1287,7 +1298,7 @@ httpRead2(http_t *http,                   /* I - HTTP connection */
 #endif /* HAVE_SSL */
   else
   {
-    if (!http->blocking && !httpWait(http, 1000))
+    if (!http->blocking && !httpWait(http, 10000))
       return (0);
 
     DEBUG_printf(("httpRead2: reading %d bytes from socket...\n", length));
@@ -1386,11 +1397,15 @@ _httpReadCDSA(
     void             *data,            /* I  - Data buffer */
     size_t           *dataLength)      /* IO - Number of bytes */
 {
-  OSStatus     result;                 /* Return value */
-  ssize_t      bytes;                  /* Number of bytes read */
+  OSStatus       result;               /* Return value */
+  ssize_t        bytes;                /* Number of bytes read */
+  cdsa_conn_ref_t u;                   /* Connection reference union */
+
+
+  u.connection = connection;
 
   do
-    bytes = recv((int)connection, data, *dataLength, 0);
+    bytes = recv(u.sock, data, *dataLength, 0);
   while (bytes == -1 && errno == EINTR);
 
   if (bytes == *dataLength)
@@ -1405,13 +1420,11 @@ _httpReadCDSA(
     *dataLength = 0;
 
     if (bytes == 0)
-      result = errSSLClosedAbort;
+      result = errSSLClosedGraceful;
     else if (errno == EAGAIN)
       result = errSSLWouldBlock;
-    else if (errno == EPIPE)
-      result = errSSLClosedAbort;
     else
-      result = errSSLInternal;
+      result = errSSLClosedAbort;
   }
 
   return result;
@@ -1690,6 +1703,7 @@ httpUpdate(http_t *http)          /* I - HTTP connection */
        case HTTP_PUT :
            http->state ++;
        case HTTP_POST_SEND :
+       case HTTP_HEAD :
            break;
 
        default :
@@ -1799,6 +1813,16 @@ httpWait(http_t *http,                   /* I - HTTP connection */
   if (http->used)
     return (1);
 
+ /*
+  * Flush pending data, if any...
+  */
+
+  if (http->wused)
+  {
+    if (httpFlushWrite(http) < 0)
+      return (0);
+  }
+
  /*
   * If not, check the SSL/TLS buffers and do a select() on the connection...
   */
@@ -1869,7 +1893,7 @@ httpWrite2(http_t     *http,              /* I - HTTP connection */
       httpFlushWrite(http);
     }
 
-    if ((length + http->wused) <= sizeof(http->wbuffer))
+    if ((length + http->wused) < sizeof(http->wbuffer))
     {
      /*
       * Write to buffer...
@@ -1959,11 +1983,15 @@ _httpWriteCDSA(
     const void       *data,            /* I  - Data buffer */
     size_t           *dataLength)      /* IO - Number of bytes */
 {
-  OSStatus     result;                 /* Return value */
-  ssize_t      bytes;                  /* Number of bytes read */
+  OSStatus       result;               /* Return value */
+  ssize_t        bytes;                /* Number of bytes read */
+  cdsa_conn_ref_t u;                   /* Connection reference union */
+
+
+  u.connection = connection;
 
   do
-    bytes = write((int)connection, data, *dataLength);
+    bytes = write(u.sock, data, *dataLength);
   while (bytes == -1 && errno == EINTR);
 
   if (bytes == *dataLength)
@@ -1979,10 +2007,8 @@ _httpWriteCDSA(
   
     if (errno == EAGAIN)
       result = errSSLWouldBlock;
-    else if (errno == EPIPE)
-      result = errSSLClosedAbort;
     else
-      result = errSSLInternal;
+      result = errSSLClosedAbort;
   }
 
   return result;
@@ -2030,7 +2056,7 @@ http_read_ssl(http_t *http,               /* I - HTTP connection */
   size_t       processed;              /* Number of bytes processed */
 
 
-  error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);
+  error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed);
 
   switch (error)
   {
@@ -2133,11 +2159,20 @@ http_send(http_t       *http,   /* I - HTTP connection */
     if (httpReconnect(http))
       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 ++;
 
@@ -2190,6 +2225,7 @@ http_send(http_t       *http,     /* I - HTTP connection */
     return (-1);
   }
 
+  httpFlushWrite(http);
   httpGetLength2(http);
   httpClearFields(http);
 
@@ -2206,15 +2242,16 @@ static int                              /* O - Status of connection */
 http_setup_ssl(http_t *http)           /* I - HTTP connection */
 {
 #  ifdef HAVE_LIBSSL
-  SSL_CTX      *context;       /* Context for encryption */
-  SSL          *conn;          /* Connection for encryption */
+  SSL_CTX      *context;               /* Context for encryption */
+  SSL          *conn;                  /* Connection for encryption */
 #  elif defined(HAVE_GNUTLS)
-  http_tls_t   *conn;          /* TLS session object */
+  http_tls_t   *conn;                  /* TLS session object */
   gnutls_certificate_client_credentials *credentials;
-                               /* TLS credentials */
+                                       /* TLS credentials */
 #  elif defined(HAVE_CDSASSL)
-  SSLContextRef        conn;           /* Context for encryption */
-  OSStatus     error;          /* Error info */
+  OSStatus     error;                  /* Error code */
+  http_tls_t   *conn;                  /* CDSA connection information */
+  cdsa_conn_ref_t u;                   /* Connection reference union */
 #  endif /* HAVE_LIBSSL */
 
 
@@ -2251,9 +2288,7 @@ http_setup_ssl(http_t *http)              /* I - HTTP connection */
   }
 
 #  elif defined(HAVE_GNUTLS)
-  conn = (http_tls_t *)malloc(sizeof(http_tls_t));
-
-  if (conn == NULL)
+  if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
   {
     http->error  = errno;
     http->status = HTTP_ERROR;
@@ -2278,7 +2313,8 @@ http_setup_ssl(http_t *http)              /* I - HTTP connection */
   gnutls_init(&(conn->session), GNUTLS_CLIENT);
   gnutls_set_default_priority(conn->session);
   gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
-  gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http->fd);
+  gnutls_transport_set_ptr(conn->session,
+                           (gnutls_transport_ptr)((long)http->fd));
 
   if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
   {
@@ -2291,34 +2327,54 @@ http_setup_ssl(http_t *http)            /* I - HTTP connection */
   conn->credentials = credentials;
 
 #  elif defined(HAVE_CDSASSL)
-  error = SSLNewContext(false, &conn);
+  conn = (http_tls_t *)calloc(1, sizeof(http_tls_t));
+
+  if (conn == NULL)
+    return (-1);
+
+  if ((error = SSLNewContext(false, &conn->session)))
+  {
+    http->error  = error;
+    http->status = HTTP_ERROR;
+
+    free(conn);
+    return (-1);
+  }
+
+ /*
+  * Use a union to resolve warnings about int/pointer size mismatches...
+  */
+
+  u.connection = NULL;
+  u.sock       = http->fd;
+  error        = SSLSetConnection(conn->session, u.connection);
 
   if (!error)
-    error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
+    error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
 
   if (!error)
-    error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);
+    error = SSLSetAllowsExpiredCerts(conn->session, true);
 
   if (!error)
-    error = SSLSetAllowsExpiredCerts(conn, true);
+    error = SSLSetAllowsAnyRoot(conn->session, true);
 
   if (!error)
-    error = SSLSetAllowsAnyRoot(conn, true);
+    error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);
 
   if (!error)
   {
-    while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+    while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
       usleep(1000);
   }
 
-  if (error != 0)
+  if (error)
   {
     http->error  = error;
     http->status = HTTP_ERROR;
 
-    SSLDisposeContext(conn);
+    SSLDisposeContext(conn->session);
 
-    close(http->fd);
+    free(conn);
 
     return (-1);
   }
@@ -2336,11 +2392,11 @@ http_setup_ssl(http_t *http)            /* I - HTTP connection */
  */
 
 static void
-http_shutdown_ssl(http_t *http)        /* I - HTTP connection */
+http_shutdown_ssl(http_t *http)                /* I - HTTP connection */
 {
 #  ifdef HAVE_LIBSSL
-  SSL_CTX      *context;       /* Context for encryption */
-  SSL          *conn;          /* Connection for encryption */
+  SSL_CTX      *context;               /* Context for encryption */
+  SSL          *conn;                  /* Connection for encryption */
 
 
   conn    = (SSL *)(http->tls);
@@ -2351,9 +2407,9 @@ http_shutdown_ssl(http_t *http)   /* I - HTTP connection */
   SSL_free(conn);
 
 #  elif defined(HAVE_GNUTLS)
-  http_tls_t      *conn;       /* Encryption session */
+  http_tls_t      *conn;               /* Encryption session */
   gnutls_certificate_client_credentials *credentials;
-                               /* TLS credentials */
+                                       /* TLS credentials */
 
 
   conn = (http_tls_t *)(http->tls);
@@ -2366,10 +2422,20 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */
   free(conn);
 
 #  elif defined(HAVE_CDSASSL)
-  while (SSLClose((SSLContextRef)http->tls) == errSSLWouldBlock)
+  http_tls_t      *conn;               /* CDSA connection information */
+
+
+  conn = (http_tls_t *)(http->tls);
+
+  while (SSLClose(conn->session) == errSSLWouldBlock)
     usleep(1000);
 
-  SSLDisposeContext((SSLContextRef)http->tls);
+  SSLDisposeContext(conn->session);
+
+  if (conn->certsArray)
+    CFRelease(conn->certsArray);
+
+  free(conn);
 #  endif /* HAVE_LIBSSL */
 
   http->tls = NULL;
@@ -2382,11 +2448,11 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */
  * 'http_upgrade()' - Force upgrade to TLS encryption.
  */
 
-static int                     /* O - Status of connection */
-http_upgrade(http_t *http)     /* I - HTTP connection */
+static int                             /* O - Status of connection */
+http_upgrade(http_t *http)             /* I - HTTP connection */
 {
-  int          ret;            /* Return value */
-  http_t       myhttp;         /* Local copy of HTTP data */
+  int          ret;                    /* Return value */
+  http_t       myhttp;                 /* Local copy of HTTP data */
 
 
   DEBUG_printf(("http_upgrade(%p)\n", http));
@@ -2506,7 +2572,7 @@ http_wait(http_t *http,                   /* I - HTTP connection */
 #  elif defined(HAVE_CDSASSL)
     size_t bytes;                      /* Bytes that are available */
 
-    if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
+    if (!SSLGetBufferedReadSize(((http_tls_t *)http->tls)->session, &bytes) && bytes > 0)
       return (1);
 #  endif /* HAVE_LIBSSL */
   }
@@ -2549,6 +2615,8 @@ http_wait(http_t *http,                   /* I - HTTP connection */
   {
     FD_SET(http->fd, http->input_set);
 
+    DEBUG_printf(("http_wait: msec=%d, http->fd=%d\n", msec, http->fd));
+
     if (msec >= 0)
     {
       timeout.tv_sec  = msec / 1000;
@@ -2558,6 +2626,8 @@ http_wait(http_t *http,                   /* I - HTTP connection */
     }
     else
       nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
+
+    DEBUG_printf(("http_wait: select() returned %d...\n", nfds));
   }
 #ifdef WIN32
   while (nfds < 0 && WSAGetLastError() == WSAEINTR);
@@ -2567,6 +2637,8 @@ http_wait(http_t *http,                   /* I - HTTP connection */
 
   FD_CLR(http->fd, http->input_set);
 
+  DEBUG_printf(("http_wait: returning with nfds=%d...\n", nfds));
+
   return (nfds > 0);
 }
 
@@ -2722,7 +2794,7 @@ http_write_ssl(http_t     *http,  /* I - HTTP connection */
   size_t       processed;              /* Number of bytes processed */
 
 
-  error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
+  error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed);
 
   switch (error)
   {
@@ -2754,5 +2826,5 @@ http_write_ssl(http_t     *http,  /* I - HTTP connection */
 
 
 /*
- * End of "$Id: http.c 5222 2006-03-03 18:57:56Z mike $".
+ * End of "$Id: http.c 5889 2006-08-24 21:44:35Z mike $".
  */