/*
- * "$Id: http.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: http.c 5200 2006-02-28 00:10:32Z mike $"
*
* HTTP routines for the Common UNIX Printing System (CUPS).
*
* _httpReadCDSA() - Read function for CDSA decryption code.
* httpReconnect() - Reconnect to a HTTP server...
* httpSetCookie() - Set the cookie value(s)...
+ * httpSetExpect() - Set the Expect: header in a request.
* httpSetField() - Set the value of an HTTP header.
* httpSetLength() - Set the content-length and transfer-encoding.
* httpTrace() - Send an TRACE request to the server.
{
memset(http->fields, 0, sizeof(http->fields));
httpSetField(http, HTTP_FIELD_HOST, http->hostname);
+
+ http->expect = (http_status_t)0;
}
}
OSStatus result; /* Return value */
ssize_t bytes; /* Number of bytes read */
-
- for (;;)
- {
+ do
bytes = recv((int)connection, data, *dataLength, 0);
+ while (bytes == -1 && errno == EINTR);
- if (bytes > 0)
- {
- result = (bytes == *dataLength);
- *dataLength = bytes;
-
- return (result);
- }
+ if (bytes == *dataLength)
+ result = 0;
+ else if (bytes > 0)
+ {
+ *dataLength = bytes;
+ result = errSSLWouldBlock;
+ }
+ else
+ {
+ *dataLength = 0;
if (bytes == 0)
- return (errSSLClosedAbort);
-
- if (errno == EAGAIN)
- return (errSSLWouldBlock);
-
- if (errno == EPIPE)
- return (errSSLClosedAbort);
-
- if (errno != EINTR)
- return (errSSLInternal);
+ result = errSSLClosedAbort;
+ else if (errno == EAGAIN)
+ result = errSSLWouldBlock;
+ else if (errno == EPIPE)
+ result = errSSLClosedAbort;
+ else
+ result = errSSLInternal;
}
+
+ return result;
}
#endif /* HAVE_SSL && HAVE_CDSASSL */
}
+/*
+ * 'httpSetExpect()' - Set the Expect: header in a request.
+ *
+ * Currently only HTTP_CONTINUE is supported for the "expect" argument.
+ *
+ * @since CUPS 1.2@
+ */
+
+void
+httpSetExpect(http_t *http, /* I - HTTP connection */
+ http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */
+{
+ if (http)
+ http->expect = expect;
+}
+
+
/*
* 'httpSetField()' - Set the value of an HTTP header.
*/
OSStatus result; /* Return value */
ssize_t bytes; /* Number of bytes read */
-
- for (;;)
- {
+ do
bytes = write((int)connection, data, *dataLength);
+ while (bytes == -1 && errno == EINTR);
- if (bytes >= 0)
- {
- result = (bytes == *dataLength) ? 0 : errSSLWouldBlock;
- *dataLength = bytes;
-
- return (result);
- }
-
+ if (bytes == *dataLength)
+ result = 0;
+ else if (bytes >= 0)
+ {
+ *dataLength = bytes;
+ result = errSSLWouldBlock;
+ }
+ else
+ {
+ *dataLength = 0;
+
if (errno == EAGAIN)
- return (errSSLWouldBlock);
-
- if (errno == EPIPE)
- return (errSSLClosedAbort);
-
- if (errno != EINTR)
- return (errSSLInternal);
+ result = errSSLWouldBlock;
+ else if (errno == EPIPE)
+ result = errSSLClosedAbort;
+ else
+ result = errSSLInternal;
}
+
+ return result;
}
#endif /* HAVE_SSL && HAVE_CDSASSL */
result = 0;
break;
case errSSLWouldBlock :
- errno = EAGAIN;
- result = -1;
+ if (processed)
+ result = (int)processed;
+ else
+ {
+ result = -1;
+ errno = EINTR;
+ }
break;
default :
errno = EPIPE;
return (-1);
}
+ if (http->expect == HTTP_CONTINUE &&
+ (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
+ if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
if (httpPrintf(http, "\r\n") < 1)
{
http->status = HTTP_ERROR;
error = SSLSetAllowsAnyRoot(conn, true);
if (!error)
- error = SSLHandshake(conn);
+ {
+ while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+ usleep(1000);
+ }
if (error != 0)
{
free(conn);
# elif defined(HAVE_CDSASSL)
- SSLClose((SSLContextRef)http->tls);
+ while (SSLClose((SSLContextRef)http->tls) == errSSLWouldBlock)
+ usleep(1000);
+
SSLDisposeContext((SSLContextRef)http->tls);
# endif /* HAVE_LIBSSL */
result = 0;
break;
case errSSLWouldBlock :
- errno = EAGAIN;
- result = -1;
+ if (processed)
+ result = (int)processed;
+ else
+ {
+ result = -1;
+ errno = EINTR;
+ }
break;
default :
errno = EPIPE;
/*
- * End of "$Id: http.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: http.c 5200 2006-02-28 00:10:32Z mike $".
*/