/*
- * "$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).
*
/*
* 'httpGetCookie()' - Get any cookie data from the response.
+ *
+ * @since CUPS 1.1.19@
*/
const char * /* O - Cookie data or NULL */
* 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)
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));
+ }
}
* 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))
#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);
#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));
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)
*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;
case HTTP_PUT :
http->state ++;
case HTTP_POST_SEND :
+ case HTTP_HEAD :
break;
default :
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...
*/
httpFlushWrite(http);
}
- if ((length + http->wused) <= sizeof(http->wbuffer))
+ if ((length + http->wused) < sizeof(http->wbuffer))
{
/*
* Write to buffer...
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)
if (errno == EAGAIN)
result = errSSLWouldBlock;
- else if (errno == EPIPE)
- result = errSSLClosedAbort;
else
- result = errSSLInternal;
+ result = errSSLClosedAbort;
}
return result;
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)
{
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 ++;
return (-1);
}
+ httpFlushWrite(http);
httpGetLength2(http);
httpClearFields(http);
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 */
}
# 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;
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)
{
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);
}
*/
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);
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);
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;
* '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));
# 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 */
}
{
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;
}
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);
FD_CLR(http->fd, http->input_set);
+ DEBUG_printf(("http_wait: returning with nfds=%d...\n", nfds));
+
return (nfds > 0);
}
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)
{
/*
- * 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 $".
*/