Lines Matching +full:data +full:- +full:uri +full:- +full:to +full:- +full:buffer
4 * Copyright © 2007-2021 by Apple Inc.
5 * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
18 #include "cups-private.h"
19 #include "debug-internal.h"
52 static void http_debug_hex(const char *prefix, const char *buffer,
55 static ssize_t http_read(http_t *http, char *buffer, size_t length);
56 static ssize_t http_read_buffered(http_t *http, char *buffer, size_t length);
57 static ssize_t http_read_chunk(http_t *http, char *buffer, size_t length);
59 const char *uri);
60 static ssize_t http_write(http_t *http, const char *buffer,
62 static ssize_t http_write_chunk(http_t *http, const char *buffer,
79 "Accept-Language",
80 "Accept-Ranges",
83 "Content-Encoding",
84 "Content-Language",
85 "Content-Length",
86 "Content-Location",
87 "Content-MD5",
88 "Content-Range",
89 "Content-Type",
90 "Content-Version",
93 "If-Modified-Since",
94 "If-Unmodified-since",
95 "Keep-Alive",
96 "Last-Modified",
101 "Retry-After",
102 "Transfer-Encoding",
104 "User-Agent",
105 "WWW-Authenticate",
106 "Accept-Encoding",
109 "Authentication-Info"
114 * 'httpAcceptConnection()' - Accept a new HTTP client connection from the
120 http_t * /* O - HTTP connection or @code NULL@ */
121 httpAcceptConnection(int fd, /* I - Listen socket file descriptor */ in httpAcceptConnection()
122 int blocking) /* I - 1 if the connection should be in httpAcceptConnection()
155 if ((http->fd = accept(fd, (struct sockaddr *)&(http->addrlist->addr), in httpAcceptConnection()
164 http->hostaddr = &(http->addrlist->addr); in httpAcceptConnection()
166 if (httpAddrLocalhost(http->hostaddr)) in httpAcceptConnection()
167 strlcpy(http->hostname, "localhost", sizeof(http->hostname)); in httpAcceptConnection()
169 httpAddrString(http->hostaddr, http->hostname, sizeof(http->hostname)); in httpAcceptConnection()
177 setsockopt(http->fd, SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val)); in httpAcceptConnection()
188 setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, CUPS_SOCAST &val, sizeof(val)); in httpAcceptConnection()
195 fcntl(http->fd, F_SETFD, FD_CLOEXEC); in httpAcceptConnection()
203 * 'httpAddCredential()' - Allocates and adds a single credential to an array.
205 * Use @code cupsArrayNew(NULL, NULL)@ to create a credentials array.
210 int /* O - 0 on success, -1 on error */
212 cups_array_t *credentials, /* I - Credentials array */ in httpAddCredential()
213 const void *data, /* I - PEM-encoded X.509 data */ in httpAddCredential() argument
214 size_t datalen) /* I - Length of data */ in httpAddCredential()
216 http_credential_t *credential; /* Credential data */ in httpAddCredential()
221 credential->datalen = datalen; in httpAddCredential()
223 if ((credential->data = malloc(datalen)) != NULL) in httpAddCredential()
225 memcpy(credential->data, data, datalen); in httpAddCredential()
233 return (-1); in httpAddCredential()
238 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
242 httpBlocking(http_t *http, /* I - HTTP connection */ in httpBlocking()
243 int b) /* I - 1 = blocking, 0 = non-blocking */ in httpBlocking()
247 http->blocking = b; in httpBlocking()
254 * 'httpCheck()' - Check to see if there is a pending response from the server.
257 int /* O - 0 = no data, 1 = data available */
258 httpCheck(http_t *http) /* I - HTTP connection */ in httpCheck()
265 * 'httpClearCookie()' - Clear the cookie value(s).
271 httpClearCookie(http_t *http) /* I - HTTP connection */ in httpClearCookie()
276 if (http->cookie) in httpClearCookie()
278 free(http->cookie); in httpClearCookie()
279 http->cookie = NULL; in httpClearCookie()
285 * 'httpClearFields()' - Clear HTTP request fields.
289 httpClearFields(http_t *http) /* I - HTTP connection */ in httpClearFields()
298 memset(http->_fields, 0, sizeof(http->fields)); in httpClearFields()
302 if (http->fields[field] && http->fields[field] != http->_fields[field]) in httpClearFields()
303 free(http->fields[field]); in httpClearFields()
305 http->fields[field] = NULL; in httpClearFields()
308 if (http->mode == _HTTP_MODE_CLIENT) in httpClearFields()
310 if (http->hostname[0] == '/') in httpClearFields()
313 httpSetField(http, HTTP_FIELD_HOST, http->hostname); in httpClearFields()
316 http->expect = (http_status_t)0; in httpClearFields()
322 * 'httpClose()' - Close an HTTP connection.
326 httpClose(http_t *http) /* I - HTTP connection */ in httpClose()
352 httpAddrFreeList(http->addrlist); in httpClose()
354 if (http->cookie) in httpClose()
355 free(http->cookie); in httpClose()
358 if (http->gssctx != GSS_C_NO_CONTEXT) in httpClose()
359 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER); in httpClose()
361 if (http->gssname != GSS_C_NO_NAME) in httpClose()
362 gss_release_name(&minor_status, &http->gssname); in httpClose()
366 if (http->auth_ref) in httpClose()
367 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); in httpClose()
372 if (http->authstring && http->authstring != http->_authstring) in httpClose()
373 free(http->authstring); in httpClose()
380 * 'httpCompareCredentials()' - Compare two sets of X.509 credentials.
385 int /* O - 1 if they match, 0 if they do not */
387 cups_array_t *cred1, /* I - First set of X.509 credentials */ in httpCompareCredentials()
388 cups_array_t *cred2) /* I - Second set of X.509 credentials */ in httpCompareCredentials()
394 if (temp1->datalen != temp2->datalen) in httpCompareCredentials()
396 else if (memcmp(temp1->data, temp2->data, temp1->datalen)) in httpCompareCredentials()
404 * 'httpConnect()' - Connect to a HTTP server.
406 * This function is deprecated - use @link httpConnect2@ instead.
411 http_t * /* O - New HTTP connection */
412 httpConnect(const char *host, /* I - Host to connect to */ in httpConnect()
413 int port) /* I - Port number */ in httpConnect()
421 * 'httpConnect2()' - Connect to a HTTP server.
426 http_t * /* O - New HTTP connection */
428 const char *host, /* I - Host to connect to */ in httpConnect2()
429 int port, /* I - Port number */ in httpConnect2()
430 http_addrlist_t *addrlist, /* I - List of addresses or @code NULL@ to lookup */ in httpConnect2()
431 int family, /* I - Address family to use or @code AF_UNSPEC@ for any */ in httpConnect2()
432 http_encryption_t encryption, /* I - Type of encryption to use */ in httpConnect2()
433 int blocking, /* I - 1 for blocking connection, 0 for non-blocking */ in httpConnect2()
434 int msec, /* I - Connection timeout in milliseconds, 0 means don't connect */ in httpConnect2()
435 int *cancel) /* I - Pointer to "cancel" variable */ in httpConnect2()
451 * Optionally connect to the remote system... in httpConnect2()
458 * Could not connect to any known address - bail out! in httpConnect2()
468 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
476 http_t * /* O - New HTTP connection */
478 const char *host, /* I - Host to connect to */ in httpConnectEncrypt()
479 int port, /* I - Port number */ in httpConnectEncrypt()
480 http_encryption_t encryption) /* I - Type of encryption to use */ in httpConnectEncrypt()
491 * 'httpDelete()' - Send a DELETE request to the server.
494 int /* O - Status of call (0 = success) */
495 httpDelete(http_t *http, /* I - HTTP connection */ in httpDelete()
496 const char *uri) /* I - URI to delete */ in httpDelete() argument
498 return (http_send(http, HTTP_STATE_DELETE, uri)); in httpDelete()
503 * '_httpDisconnect()' - Disconnect a HTTP connection.
507 _httpDisconnect(http_t *http) /* I - HTTP connection */ in _httpDisconnect()
510 if (http->tls) in _httpDisconnect()
514 httpAddrClose(NULL, http->fd); in _httpDisconnect()
516 http->fd = -1; in _httpDisconnect()
521 * 'httpEncryption()' - Set the required encryption on the link.
524 int /* O - -1 on error, 0 on success */
525 httpEncryption(http_t *http, /* I - HTTP connection */ in httpEncryption()
526 http_encryption_t e) /* I - New encryption preference */ in httpEncryption()
534 if (http->mode == _HTTP_MODE_CLIENT) in httpEncryption()
536 http->encryption = e; in httpEncryption()
538 if ((http->encryption == HTTP_ENCRYPTION_ALWAYS && !http->tls) || in httpEncryption()
539 (http->encryption == HTTP_ENCRYPTION_NEVER && http->tls)) in httpEncryption()
541 else if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls) in httpEncryption()
548 if (e == HTTP_ENCRYPTION_NEVER && http->tls) in httpEncryption()
549 return (-1); in httpEncryption()
551 http->encryption = e; in httpEncryption()
552 if (e != HTTP_ENCRYPTION_IF_REQUESTED && !http->tls) in httpEncryption()
559 return (-1); in httpEncryption()
567 * 'httpError()' - Get the last error on a connection.
570 int /* O - Error code (errno) value */
571 httpError(http_t *http) /* I - HTTP connection */ in httpError()
574 return (http->error); in httpError()
581 * 'httpFieldValue()' - Return the HTTP field enumeration value for a field
585 http_field_t /* O - Field index */
586 httpFieldValue(const char *name) /* I - String name */ in httpFieldValue()
600 * 'httpFlush()' - Flush data read from a HTTP connection.
604 httpFlush(http_t *http) /* I - HTTP connection */ in httpFlush()
606 char buffer[8192]; /* Junk buffer */ in httpFlush() local
607 int blocking; /* To block or not to block */ in httpFlush()
611 DEBUG_printf(("httpFlush(http=%p), state=%s", (void *)http, httpStateString(http->state))); in httpFlush()
614 * Nothing to do if we are in the "waiting" state... in httpFlush()
617 if (http->state == HTTP_STATE_WAITING) in httpFlush()
621 * Temporarily set non-blocking mode so we don't get stuck in httpRead()... in httpFlush()
624 blocking = http->blocking; in httpFlush()
625 http->blocking = 0; in httpFlush()
628 * Read any data we can... in httpFlush()
631 oldstate = http->state; in httpFlush()
632 while (httpRead2(http, buffer, sizeof(buffer)) > 0); in httpFlush()
636 * the remaining data... in httpFlush()
639 http->blocking = blocking; in httpFlush()
641 if (http->state == oldstate && http->state != HTTP_STATE_WAITING && in httpFlush()
642 http->fd >= 0) in httpFlush()
645 * Didn't get the data back, so close the current connection. in httpFlush()
649 if (http->coding) in httpFlush()
653 DEBUG_puts("1httpFlush: Setting state to HTTP_STATE_WAITING and closing."); in httpFlush()
655 http->state = HTTP_STATE_WAITING; in httpFlush()
658 if (http->tls) in httpFlush()
662 httpAddrClose(NULL, http->fd); in httpFlush()
664 http->fd = -1; in httpFlush()
670 * 'httpFlushWrite()' - Flush data written to a HTTP connection.
675 int /* O - Bytes written or -1 on error */
676 httpFlushWrite(http_t *http) /* I - HTTP connection */ in httpFlushWrite()
681 …DEBUG_printf(("httpFlushWrite(http=%p) data_encoding=%d", (void *)http, http ? http->data_encoding… in httpFlushWrite()
683 if (!http || !http->wused) in httpFlushWrite()
685 DEBUG_puts(http ? "1httpFlushWrite: Write buffer is empty." : in httpFlushWrite()
690 if (http->data_encoding == HTTP_ENCODING_CHUNKED) in httpFlushWrite()
691 bytes = http_write_chunk(http, http->wbuffer, (size_t)http->wused); in httpFlushWrite()
693 bytes = http_write(http, http->wbuffer, (size_t)http->wused); in httpFlushWrite()
695 http->wused = 0; in httpFlushWrite()
704 * 'httpFreeCredentials()' - Free an array of credentials.
709 cups_array_t *credentials) /* I - Array of credentials */ in httpFreeCredentials()
719 free((void *)credential->data); in httpFreeCredentials()
728 * 'httpGet()' - Send a GET request to the server.
731 int /* O - Status of call (0 = success) */
732 httpGet(http_t *http, /* I - HTTP connection */ in httpGet()
733 const char *uri) /* I - URI to get */ in httpGet() argument
735 return (http_send(http, HTTP_STATE_GET, uri)); in httpGet()
740 * 'httpGetActivity()' - Get the most recent activity for a connection.
747 time_t /* O - Time of last read or write */
748 httpGetActivity(http_t *http) /* I - HTTP connection */ in httpGetActivity()
750 return (http ? http->activity : 0); in httpGetActivity()
755 * 'httpGetAuthString()' - Get the current authorization string.
758 * @link httpSetAuthString@. Use @link httpGetAuthString@ to retrieve the
759 * string to use with @link httpSetField@ for the
765 char * /* O - Authorization string */
766 httpGetAuthString(http_t *http) /* I - HTTP connection */ in httpGetAuthString()
769 return (http->authstring); in httpGetAuthString()
776 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection.
781 int /* O - 1 if blocking, 0 if non-blocking */
782 httpGetBlocking(http_t *http) /* I - HTTP connection */ in httpGetBlocking()
784 return (http ? http->blocking : 0); in httpGetBlocking()
789 * 'httpGetContentEncoding()' - Get a common content encoding, if any, between
792 * This function uses the value of the Accepts-Encoding HTTP header and must be
795 * or in the response (for servers) in order to compress the content stream.
800 const char * /* O - Content-Coding value or
803 httpGetContentEncoding(http_t *http) /* I - HTTP connection */ in httpGetContentEncoding()
806 if (http && http->fields[HTTP_FIELD_ACCEPT_ENCODING]) in httpGetContentEncoding()
809 char temp[HTTP_MAX_VALUE], /* Copy of Accepts-Encoding value */ in httpGetContentEncoding()
813 struct lconv *loc = localeconv(); /* Locale data */ in httpGetContentEncoding()
818 "x-deflate", in httpGetContentEncoding()
819 "x-gzip" in httpGetContentEncoding()
822 strlcpy(temp, http->fields[HTTP_FIELD_ACCEPT_ENCODING], sizeof(temp)); in httpGetContentEncoding()
877 * 'httpGetCookie()' - Get any cookie data from the response.
882 const char * /* O - Cookie data or @code NULL@ */
883 httpGetCookie(http_t *http) /* I - HTTP connection */ in httpGetCookie()
885 return (http ? http->cookie : NULL); in httpGetCookie()
890 * 'httpGetEncryption()' - Get the current encryption mode of a connection.
893 * @link httpIsEncrypted@ function to determine whether a TLS session has
899 http_encryption_t /* O - Current encryption mode */
900 httpGetEncryption(http_t *http) /* I - HTTP connection */ in httpGetEncryption()
902 return (http ? http->encryption : HTTP_ENCRYPTION_IF_REQUESTED); in httpGetEncryption()
907 * 'httpGetExpect()' - Get the value of the Expect header, if any.
915 http_status_t /* O - Expect: status, if any */
916 httpGetExpect(http_t *http) /* I - HTTP connection */ in httpGetExpect()
921 return (http->expect); in httpGetExpect()
926 * 'httpGetFd()' - Get the file descriptor associated with a connection.
931 int /* O - File descriptor or -1 if none */
932 httpGetFd(http_t *http) /* I - HTTP connection */ in httpGetFd()
934 return (http ? http->fd : -1); in httpGetFd()
939 * 'httpGetField()' - Get a field value from a request/response.
942 const char * /* O - Field value */
943 httpGetField(http_t *http, /* I - HTTP connection */ in httpGetField()
944 http_field_t field) /* I - Field to get */ in httpGetField()
948 else if (http->fields[field]) in httpGetField()
949 return (http->fields[field]); in httpGetField()
956 * 'httpGetKeepAlive()' - Get the current Keep-Alive state of the connection.
961 http_keepalive_t /* O - Keep-Alive state */
962 httpGetKeepAlive(http_t *http) /* I - HTTP connection */ in httpGetKeepAlive()
964 return (http ? http->keep_alive : HTTP_KEEPALIVE_OFF); in httpGetKeepAlive()
969 * 'httpGetLength()' - Get the amount of data remaining from the
970 * content-length or transfer-encoding fields.
973 * 2^31 - 1; use httpGetLength2() instead.
978 int /* O - Content length */
979 httpGetLength(http_t *http) /* I - HTTP connection */ in httpGetLength()
982 * Get the read content length and return the 32-bit value. in httpGetLength()
989 return (http->_data_remaining); in httpGetLength()
992 return (-1); in httpGetLength()
997 * 'httpGetLength2()' - Get the amount of data remaining from the
998 * content-length or transfer-encoding fields.
1001 * content larger than 2^31 - 1.
1006 off_t /* O - Content length */
1007 httpGetLength2(http_t *http) /* I - HTTP connection */ in httpGetLength2()
1012 DEBUG_printf(("2httpGetLength2(http=%p), state=%s", (void *)http, httpStateString(http->state))); in httpGetLength2()
1015 return (-1); in httpGetLength2()
1017 …if (http->fields[HTTP_FIELD_TRANSFER_ENCODING] && !_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSF… in httpGetLength2()
1026 * Content-Length or Transfer-Encoding field... in httpGetLength2()
1028 * If there is no Content-Length then the connection must close in httpGetLength2()
1032 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH] || !http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) in httpGetLength2()
1036 * and 2^31-1 for other successful requests... in httpGetLength2()
1039 if (http->status >= HTTP_STATUS_MULTIPLE_CHOICES || in httpGetLength2()
1040 http->state == HTTP_STATE_OPTIONS || in httpGetLength2()
1041 (http->state == HTTP_STATE_GET && http->mode == _HTTP_MODE_SERVER) || in httpGetLength2()
1042 http->state == HTTP_STATE_HEAD || in httpGetLength2()
1043 (http->state == HTTP_STATE_PUT && http->mode == _HTTP_MODE_CLIENT) || in httpGetLength2()
1044 http->state == HTTP_STATE_DELETE || in httpGetLength2()
1045 http->state == HTTP_STATE_TRACE || in httpGetLength2()
1046 http->state == HTTP_STATE_CONNECT) in httpGetLength2()
1051 else if ((remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH], in httpGetLength2()
1053 remaining = -1; in httpGetLength2()
1064 * 'httpGetPending()' - Get the number of bytes that are buffered for writing.
1069 size_t /* O - Number of bytes buffered */
1070 httpGetPending(http_t *http) /* I - HTTP connection */ in httpGetPending()
1072 return (http ? (size_t)http->wused : 0); in httpGetPending()
1077 * 'httpGetReady()' - Get the number of bytes that can be read without blocking.
1082 size_t /* O - Number of bytes available */
1083 httpGetReady(http_t *http) /* I - HTTP connection */ in httpGetReady()
1087 else if (http->used > 0) in httpGetReady()
1088 return ((size_t)http->used); in httpGetReady()
1090 else if (http->tls) in httpGetReady()
1099 * 'httpGetRemaining()' - Get the number of remaining bytes in the message
1102 * The @link httpIsChunked@ function can be used to determine whether the
1103 * message body is chunked or fixed-length.
1108 size_t /* O - Remaining bytes */
1109 httpGetRemaining(http_t *http) /* I - HTTP connection */ in httpGetRemaining()
1111 return (http ? (size_t)http->data_remaining : 0); in httpGetRemaining()
1116 * 'httpGets()' - Get a line of text from a HTTP connection.
1119 char * /* O - Line or @code NULL@ */
1120 httpGets(char *line, /* I - Line to read into */ in httpGets()
1121 int length, /* I - Max length of buffer */ in httpGets()
1122 http_t *http) /* I - HTTP connection */ in httpGets()
1126 *bufptr, /* Pointer into input buffer */ in httpGets()
1127 *bufend; /* Pointer to end of buffer */ in httpGets()
1129 int eol; /* End-of-line? */ in httpGets()
1138 * Read a line from the buffer... in httpGets()
1141 http->error = 0; in httpGets()
1143 lineend = line + length - 1; in httpGets()
1149 * Pre-load the buffer as needed... in httpGets()
1158 while (http->used == 0) in httpGets()
1161 * No newline; see if there is more data to be read... in httpGets()
1164 while (!_httpWait(http, http->wait_value, 1)) in httpGets()
1166 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in httpGets()
1171 http->error = WSAETIMEDOUT; in httpGets()
1173 http->error = ETIMEDOUT; in httpGets()
1178 bytes = http_read(http, http->buffer + http->used, (size_t)(HTTP_MAX_BUFFER - http->used)); in httpGets()
1195 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in httpGets()
1198 http->error = WSAGetLastError(); in httpGets()
1200 else if (WSAGetLastError() != http->error) in httpGets()
1202 http->error = WSAGetLastError(); in httpGets()
1213 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in httpGets()
1215 else if (!http->timeout_cb && errno == EAGAIN) in httpGets()
1218 http->error = errno; in httpGets()
1220 else if (errno != http->error) in httpGets()
1222 http->error = errno; in httpGets()
1231 http->error = EPIPE; in httpGets()
1240 http->used += (int)bytes; in httpGets()
1247 for (bufptr = http->buffer, bufend = http->buffer + http->used; in httpGets()
1262 http->used -= (int)(bufptr - http->buffer); in httpGets()
1263 if (http->used > 0) in httpGets()
1264 memmove(http->buffer, bufptr, (size_t)http->used); in httpGets()
1272 http->activity = time(NULL); in httpGets()
1289 * 'httpGetState()' - Get the current state of the HTTP request.
1292 http_state_t /* O - HTTP state */
1293 httpGetState(http_t *http) /* I - HTTP connection */ in httpGetState()
1295 return (http ? http->state : HTTP_STATE_ERROR); in httpGetState()
1300 * 'httpGetStatus()' - Get the status of the last HTTP request.
1305 http_status_t /* O - HTTP status */
1306 httpGetStatus(http_t *http) /* I - HTTP connection */ in httpGetStatus()
1308 return (http ? http->status : HTTP_STATUS_ERROR); in httpGetStatus()
1313 * 'httpGetSubField()' - Get a sub-field value.
1318 char * /* O - Value or @code NULL@ */
1319 httpGetSubField(http_t *http, /* I - HTTP connection */ in httpGetSubField()
1320 http_field_t field, /* I - Field index */ in httpGetSubField()
1321 const char *name, /* I - Name of sub-field */ in httpGetSubField()
1322 char *value) /* O - Value string */ in httpGetSubField()
1329 * 'httpGetSubField2()' - Get a sub-field value.
1334 char * /* O - Value or @code NULL@ */
1335 httpGetSubField2(http_t *http, /* I - HTTP connection */ in httpGetSubField2()
1336 http_field_t field, /* I - Field index */ in httpGetSubField2()
1337 const char *name, /* I - Name of sub-field */ in httpGetSubField2()
1338 char *value, /* O - Value string */ in httpGetSubField2()
1339 int valuelen) /* I - Size of value buffer */ in httpGetSubField2()
1342 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ in httpGetSubField2()
1343 *ptr, /* Pointer into string buffer */ in httpGetSubField2()
1344 *end; /* End of value buffer */ in httpGetSubField2()
1352 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX || !http->fields[field]) in httpGetSubField2()
1355 end = value + valuelen - 1; in httpGetSubField2()
1357 for (fptr = http->fields[field]; *fptr;) in httpGetSubField2()
1373 * Get the sub-field name... in httpGetSubField2()
1378 ptr < (temp + sizeof(temp) - 1); in httpGetSubField2()
1386 * Skip trailing chars up to the '='... in httpGetSubField2()
1463 * 'httpGetVersion()' - Get the HTTP version at the other end.
1466 http_version_t /* O - Version number */
1467 httpGetVersion(http_t *http) /* I - HTTP connection */ in httpGetVersion()
1469 return (http ? http->version : HTTP_VERSION_1_0); in httpGetVersion()
1474 * 'httpHead()' - Send a HEAD request to the server.
1477 int /* O - Status of call (0 = success) */
1478 httpHead(http_t *http, /* I - HTTP connection */ in httpHead()
1479 const char *uri) /* I - URI for head */ in httpHead() argument
1481 DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", (void *)http, uri)); in httpHead()
1482 return (http_send(http, HTTP_STATE_HEAD, uri)); in httpHead()
1487 * 'httpInitialize()' - Initialize the HTTP interface library and set the
1496 WSADATA winsockdata; /* WinSock data */ in httpInitialize()
1519 struct sigaction action; /* POSIX sigaction data */ in httpInitialize()
1541 * 'httpIsChunked()' - Report whether a message body is chunked.
1543 * This function returns non-zero if the message body is composed of
1544 * variable-length chunks.
1549 int /* O - 1 if chunked, 0 if not */
1550 httpIsChunked(http_t *http) /* I - HTTP connection */ in httpIsChunked()
1552 return (http ? http->data_encoding == HTTP_ENCODING_CHUNKED : 0); in httpIsChunked()
1557 * 'httpIsEncrypted()' - Report whether a connection is encrypted.
1559 * This function returns non-zero if the connection is currently encrypted.
1564 int /* O - 1 if encrypted, 0 if not */
1565 httpIsEncrypted(http_t *http) /* I - HTTP connection */ in httpIsEncrypted()
1567 return (http ? http->tls != NULL : 0); in httpIsEncrypted()
1572 * 'httpOptions()' - Send an OPTIONS request to the server.
1575 int /* O - Status of call (0 = success) */
1576 httpOptions(http_t *http, /* I - HTTP connection */ in httpOptions()
1577 const char *uri) /* I - URI for options */ in httpOptions() argument
1579 return (http_send(http, HTTP_STATE_OPTIONS, uri)); in httpOptions()
1584 * 'httpPeek()' - Peek at data from a HTTP connection.
1586 * This function copies available data from the given HTTP connection, reading
1587 * a buffer as needed. The data is still available for reading using
1590 * For non-blocking connections the usual timeouts apply.
1595 ssize_t /* O - Number of bytes copied */
1596 httpPeek(http_t *http, /* I - HTTP connection */ in httpPeek()
1597 char *buffer, /* I - Buffer for data */ in httpPeek() argument
1598 size_t length) /* I - Maximum number of bytes */ in httpPeek()
1604 …DEBUG_printf(("httpPeek(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffer,… in httpPeek()
1606 if (http == NULL || buffer == NULL) in httpPeek()
1607 return (-1); in httpPeek()
1609 http->activity = time(NULL); in httpPeek()
1610 http->error = 0; in httpPeek()
1615 if (http->data_encoding == HTTP_ENCODING_CHUNKED && in httpPeek()
1616 http->data_remaining <= 0) in httpPeek()
1636 http->data_remaining = strtoll(len, NULL, 16); in httpPeek()
1638 if (http->data_remaining < 0) in httpPeek()
1646 CUPS_LLCAST http->data_remaining)); in httpPeek()
1648 if (http->data_remaining <= 0 && http->data_encoding != HTTP_ENCODING_FIELDS) in httpPeek()
1651 * A zero-length chunk ends a transfer; unless we are reading POST in httpPeek()
1652 * data, go idle... in httpPeek()
1656 if (http->coding >= _HTTP_CODING_GUNZIP) in httpPeek()
1660 if (http->data_encoding == HTTP_ENCODING_CHUNKED) in httpPeek()
1663 if (http->state == HTTP_STATE_POST_RECV) in httpPeek()
1664 http->state ++; in httpPeek()
1666 http->state = HTTP_STATE_STATUS; in httpPeek()
1668 DEBUG_printf(("1httpPeek: 0-length chunk, set state to %s.", in httpPeek()
1669 httpStateString(http->state))); in httpPeek()
1675 http->data_encoding = HTTP_ENCODING_FIELDS; in httpPeek()
1679 else if (length > (size_t)http->data_remaining) in httpPeek()
1680 length = (size_t)http->data_remaining; in httpPeek()
1683 if (http->used == 0 && in httpPeek()
1684 (http->coding == _HTTP_CODING_IDENTITY || in httpPeek()
1685 (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0))) in httpPeek()
1687 if (http->used == 0) in httpPeek()
1691 * Buffer small reads for better performance... in httpPeek()
1694 ssize_t buflen; /* Length of read for buffer */ in httpPeek()
1696 if (!http->blocking) in httpPeek()
1698 while (!httpWait(http, http->wait_value)) in httpPeek()
1700 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in httpPeek()
1707 if ((size_t)http->data_remaining > sizeof(http->buffer)) in httpPeek()
1708 buflen = sizeof(http->buffer); in httpPeek()
1710 buflen = (ssize_t)http->data_remaining; in httpPeek()
1712 DEBUG_printf(("2httpPeek: Reading %d bytes into buffer.", (int)buflen)); in httpPeek()
1713 bytes = http_read(http, http->buffer, (size_t)buflen); in httpPeek()
1715 DEBUG_printf(("2httpPeek: Read " CUPS_LLFMT " bytes into buffer.", in httpPeek()
1720 http_debug_hex("httpPeek", http->buffer, (int)bytes); in httpPeek()
1723 http->used = (int)bytes; in httpPeek()
1728 if (http->coding >= _HTTP_CODING_GUNZIP) in httpPeek()
1734 if (http->used > 0 && ((z_stream *)http->stream)->avail_in < HTTP_MAX_BUFFER) in httpPeek()
1736 size_t buflen = HTTP_MAX_BUFFER - ((z_stream *)http->stream)->avail_in; in httpPeek()
1737 /* Number of bytes to copy */ in httpPeek()
1739 if (((z_stream *)http->stream)->avail_in > 0 && in httpPeek()
1740 ((z_stream *)http->stream)->next_in > http->sbuffer) in httpPeek()
1741 … memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in); in httpPeek()
1743 ((z_stream *)http->stream)->next_in = http->sbuffer; in httpPeek()
1745 if (buflen > (size_t)http->data_remaining) in httpPeek()
1746 buflen = (size_t)http->data_remaining; in httpPeek()
1748 if (buflen > (size_t)http->used) in httpPeek()
1749 buflen = (size_t)http->used; in httpPeek()
1751 DEBUG_printf(("1httpPeek: Copying %d more bytes of data into " in httpPeek()
1752 "decompression buffer.", (int)buflen)); in httpPeek()
1754 memcpy(http->sbuffer + ((z_stream *)http->stream)->avail_in, http->buffer, buflen); in httpPeek()
1755 ((z_stream *)http->stream)->avail_in += buflen; in httpPeek()
1756 http->used -= (int)buflen; in httpPeek()
1757 http->data_remaining -= (off_t)buflen; in httpPeek()
1759 if (http->used > 0) in httpPeek()
1760 memmove(http->buffer, http->buffer + buflen, (size_t)http->used); in httpPeek()
1764 (int)((z_stream *)http->stream)->avail_in)); in httpPeek()
1766 if (inflateCopy(&stream, (z_stream *)http->stream) != Z_OK) in httpPeek()
1768 DEBUG_puts("2httpPeek: Unable to copy decompressor stream."); in httpPeek()
1769 http->error = ENOMEM; in httpPeek()
1770 return (-1); in httpPeek()
1773 stream.next_out = (Bytef *)buffer; in httpPeek()
1783 http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in); in httpPeek()
1786 http->error = EIO; in httpPeek()
1787 return (-1); in httpPeek()
1790 bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out); in httpPeek()
1795 return (-1); in httpPeek()
1800 if (http->used > 0) in httpPeek()
1802 if (length > (size_t)http->used) in httpPeek()
1803 length = (size_t)http->used; in httpPeek()
1807 DEBUG_printf(("2httpPeek: grabbing %d bytes from input buffer...", in httpPeek()
1810 memcpy(buffer, http->buffer, length); in httpPeek()
1821 http->error = WSAGetLastError(); in httpPeek()
1826 http->error = errno; in httpPeek()
1831 http->error = EPIPE; in httpPeek()
1840 * 'httpPost()' - Send a POST request to the server.
1843 int /* O - Status of call (0 = success) */
1844 httpPost(http_t *http, /* I - HTTP connection */ in httpPost()
1845 const char *uri) /* I - URI for post */ in httpPost() argument
1847 return (http_send(http, HTTP_STATE_POST, uri)); in httpPost()
1852 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
1857 int /* O - Number of bytes written */
1858 httpPrintf(http_t *http, /* I - HTTP connection */ in httpPrintf()
1859 const char *format, /* I - printf-style format string */ in httpPrintf()
1860 ...) /* I - Additional args as needed */ in httpPrintf()
1862 ssize_t bytes; /* Number of bytes to write */ in httpPrintf()
1863 char buf[65536]; /* Buffer for formatted string */ in httpPrintf()
1875 if (bytes > (ssize_t)(sizeof(buf) - 1)) in httpPrintf()
1877 http->error = ENOMEM; in httpPrintf()
1878 return (-1); in httpPrintf()
1880 else if (http->data_encoding == HTTP_ENCODING_FIELDS) in httpPrintf()
1884 if (http->wused) in httpPrintf()
1886 DEBUG_puts("4httpPrintf: flushing existing data..."); in httpPrintf()
1889 return (-1); in httpPrintf()
1898 * 'httpPut()' - Send a PUT request to the server.
1901 int /* O - Status of call (0 = success) */
1902 httpPut(http_t *http, /* I - HTTP connection */ in httpPut()
1903 const char *uri) /* I - URI to put */ in httpPut() argument
1905 DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", (void *)http, uri)); in httpPut()
1906 return (http_send(http, HTTP_STATE_PUT, uri)); in httpPut()
1911 * 'httpRead()' - Read data from a HTTP connection.
1914 * read more than 2GB of data.
1919 int /* O - Number of bytes read */
1920 httpRead(http_t *http, /* I - HTTP connection */ in httpRead()
1921 char *buffer, /* I - Buffer for data */ in httpRead() argument
1922 int length) /* I - Maximum number of bytes */ in httpRead()
1924 return ((int)httpRead2(http, buffer, (size_t)length)); in httpRead()
1929 * 'httpRead2()' - Read data from a HTTP connection.
1934 ssize_t /* O - Number of bytes read */
1935 httpRead2(http_t *http, /* I - HTTP connection */ in httpRead2()
1936 char *buffer, /* I - Buffer for data */ in httpRead2() argument
1937 size_t length) /* I - Maximum number of bytes */ in httpRead2()
1943 …buffer=%p, length=" CUPS_LLFMT ") coding=%d data_encoding=%d data_remaining=" CUPS_LLFMT, (void *)… in httpRead2()
1945 …buffer=%p, length=" CUPS_LLFMT ") data_encoding=%d data_remaining=" CUPS_LLFMT, (void *)http, (voi… in httpRead2()
1948 if (http == NULL || buffer == NULL) in httpRead2()
1949 return (-1); in httpRead2()
1951 http->activity = time(NULL); in httpRead2()
1952 http->error = 0; in httpRead2()
1958 if (http->coding >= _HTTP_CODING_GUNZIP) in httpRead2()
1962 if (((z_stream *)http->stream)->avail_in > 0) in httpRead2()
1967 (int)((z_stream *)http->stream)->avail_in, (int)length)); in httpRead2()
1969 ((z_stream *)http->stream)->next_out = (Bytef *)buffer; in httpRead2()
1970 ((z_stream *)http->stream)->avail_out = (uInt)length; in httpRead2()
1972 if ((zerr = inflate((z_stream *)http->stream, Z_SYNC_FLUSH)) < Z_OK) in httpRead2()
1976 … http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in); in httpRead2()
1979 http->error = EIO; in httpRead2()
1980 return (-1); in httpRead2()
1983 bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out); in httpRead2()
1986 ((z_stream *)http->stream)->avail_in, ((z_stream *)http->stream)->avail_out, in httpRead2()
1994 ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)((z_stream *)http->stream)->avail_in; in httpRead2()
1995 /* Additional bytes for buffer */ in httpRead2()
1999 if (((z_stream *)http->stream)->avail_in > 0 && in httpRead2()
2000 ((z_stream *)http->stream)->next_in > http->sbuffer) in httpRead2()
2001 … memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in); in httpRead2()
2003 ((z_stream *)http->stream)->next_in = http->sbuffer; in httpRead2()
2005 DEBUG_printf(("1httpRead2: Reading up to %d more bytes of data into " in httpRead2()
2006 "decompression buffer.", (int)buflen)); in httpRead2()
2008 if (http->data_remaining > 0) in httpRead2()
2010 if (buflen > http->data_remaining) in httpRead2()
2011 buflen = (ssize_t)http->data_remaining; in httpRead2()
2013 …bytes = http_read_buffered(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (si… in httpRead2()
2015 else if (http->data_encoding == HTTP_ENCODING_CHUNKED) in httpRead2()
2016 …bytes = http_read_chunk(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (size_… in httpRead2()
2025 DEBUG_printf(("1httpRead2: Adding " CUPS_LLFMT " bytes to " in httpRead2()
2026 "decompression buffer.", CUPS_LLCAST bytes)); in httpRead2()
2028 http->data_remaining -= bytes; in httpRead2()
2029 ((z_stream *)http->stream)->avail_in += (uInt)bytes; in httpRead2()
2031 if (http->data_remaining <= 0 && in httpRead2()
2032 http->data_encoding == HTTP_ENCODING_CHUNKED) in httpRead2()
2053 if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) in httpRead2()
2055 if ((bytes = http_read_chunk(http, buffer, length)) > 0) in httpRead2()
2057 http->data_remaining -= bytes; in httpRead2()
2059 if (http->data_remaining <= 0) in httpRead2()
2071 else if (http->data_remaining <= 0) in httpRead2()
2074 * No more data to read... in httpRead2()
2081 DEBUG_printf(("1httpRead2: Reading up to %d bytes into buffer.", in httpRead2()
2084 if (length > (size_t)http->data_remaining) in httpRead2()
2085 length = (size_t)http->data_remaining; in httpRead2()
2087 if ((bytes = http_read_buffered(http, buffer, length)) > 0) in httpRead2()
2089 http->data_remaining -= bytes; in httpRead2()
2091 if (http->data_remaining <= 0 && in httpRead2()
2092 http->data_encoding == HTTP_ENCODING_CHUNKED) in httpRead2()
2107 (http->coding == _HTTP_CODING_IDENTITY || in httpRead2()
2108 (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0)) && in httpRead2()
2110 ((http->data_remaining <= 0 && in httpRead2()
2111 http->data_encoding == HTTP_ENCODING_LENGTH) || in httpRead2()
2112 (http->data_encoding == HTTP_ENCODING_CHUNKED && bytes == 0))) in httpRead2()
2115 if (http->coding >= _HTTP_CODING_GUNZIP) in httpRead2()
2119 if (http->state == HTTP_STATE_POST_RECV) in httpRead2()
2120 http->state ++; in httpRead2()
2121 else if (http->state == HTTP_STATE_GET_SEND || in httpRead2()
2122 http->state == HTTP_STATE_POST_SEND) in httpRead2()
2123 http->state = HTTP_STATE_WAITING; in httpRead2()
2125 http->state = HTTP_STATE_STATUS; in httpRead2()
2127 DEBUG_printf(("1httpRead2: End of content, set state to %s.", in httpRead2()
2128 httpStateString(http->state))); in httpRead2()
2136 * 'httpReadRequest()' - Read a HTTP request from a connection.
2141 http_state_t /* O - New state of connection */
2142 httpReadRequest(http_t *http, /* I - HTTP connection */ in httpReadRequest()
2143 char *uri, /* I - URI buffer */ in httpReadRequest() argument
2144 size_t urilen) /* I - Size of URI buffer */ in httpReadRequest()
2148 *req_uri, /* HTTP request URI */ in httpReadRequest()
2156 …DEBUG_printf(("httpReadRequest(http=%p, uri=%p, urilen=" CUPS_LLFMT ")", (void *)http, (void *)uri… in httpReadRequest()
2158 if (uri) in httpReadRequest()
2159 *uri = '\0'; in httpReadRequest()
2161 if (!http || !uri || urilen < 1) in httpReadRequest()
2166 else if (http->state != HTTP_STATE_WAITING) in httpReadRequest()
2169 httpStateString(http->state))); in httpReadRequest()
2179 http->activity = time(NULL); in httpReadRequest()
2180 http->data_encoding = HTTP_ENCODING_FIELDS; in httpReadRequest()
2181 http->data_remaining = 0; in httpReadRequest()
2182 http->keep_alive = HTTP_KEEPALIVE_OFF; in httpReadRequest()
2183 http->status = HTTP_STATUS_OK; in httpReadRequest()
2184 http->version = HTTP_VERSION_1_1; in httpReadRequest()
2192 DEBUG_puts("1httpReadRequest: Unable to read, returning HTTP_STATE_ERROR"); in httpReadRequest()
2216 DEBUG_puts("1httpReadRequest: No request URI."); in httpReadRequest()
2217 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No request URI."), 1); in httpReadRequest()
2248 http->state = HTTP_STATE_OPTIONS; in httpReadRequest()
2250 http->state = HTTP_STATE_GET; in httpReadRequest()
2252 http->state = HTTP_STATE_HEAD; in httpReadRequest()
2254 http->state = HTTP_STATE_POST; in httpReadRequest()
2256 http->state = HTTP_STATE_PUT; in httpReadRequest()
2258 http->state = HTTP_STATE_DELETE; in httpReadRequest()
2260 http->state = HTTP_STATE_TRACE; in httpReadRequest()
2262 http->state = HTTP_STATE_CONNECT; in httpReadRequest()
2270 DEBUG_printf(("1httpReadRequest: Set state to %s.", in httpReadRequest()
2271 httpStateString(http->state))); in httpReadRequest()
2275 http->version = HTTP_VERSION_1_0; in httpReadRequest()
2276 http->keep_alive = HTTP_KEEPALIVE_OFF; in httpReadRequest()
2280 http->version = HTTP_VERSION_1_1; in httpReadRequest()
2281 http->keep_alive = HTTP_KEEPALIVE_ON; in httpReadRequest()
2290 DEBUG_printf(("1httpReadRequest: URI is \"%s\".", req_uri)); in httpReadRequest()
2291 strlcpy(uri, req_uri, urilen); in httpReadRequest()
2293 return (http->state); in httpReadRequest()
2298 * 'httpReconnect()' - Reconnect to a HTTP server.
2306 int /* O - 0 on success, non-zero on failure */
2307 httpReconnect(http_t *http) /* I - HTTP connection */ in httpReconnect()
2316 * 'httpReconnect2()' - Reconnect to a HTTP server with timeout and optional
2320 int /* O - 0 on success, non-zero on failure */
2321 httpReconnect2(http_t *http, /* I - HTTP connection */ in httpReconnect2()
2322 int msec, /* I - Timeout in milliseconds */ in httpReconnect2()
2323 int *cancel) /* I - Pointer to "cancel" variable */ in httpReconnect2()
2337 return (-1); in httpReconnect2()
2341 if (http->tls) in httpReconnect2()
2352 if (http->fd >= 0) in httpReconnect2()
2354 DEBUG_printf(("2httpReconnect2: Closing socket %d...", http->fd)); in httpReconnect2()
2356 httpAddrClose(NULL, http->fd); in httpReconnect2()
2358 http->fd = -1; in httpReconnect2()
2365 http->state = HTTP_STATE_WAITING; in httpReconnect2()
2366 http->version = HTTP_VERSION_1_1; in httpReconnect2()
2367 http->keep_alive = HTTP_KEEPALIVE_OFF; in httpReconnect2()
2368 memset(&http->_hostaddr, 0, sizeof(http->_hostaddr)); in httpReconnect2()
2369 http->data_encoding = HTTP_ENCODING_FIELDS; in httpReconnect2()
2370 http->_data_remaining = 0; in httpReconnect2()
2371 http->used = 0; in httpReconnect2()
2372 http->data_remaining = 0; in httpReconnect2()
2373 http->hostaddr = NULL; in httpReconnect2()
2374 http->wused = 0; in httpReconnect2()
2377 * Connect to the server... in httpReconnect2()
2381 for (current = http->addrlist; current; current = current->next) in httpReconnect2()
2383 httpAddrString(&(current->addr), temp, sizeof(temp)), in httpReconnect2()
2384 httpAddrPort(&(current->addr)))); in httpReconnect2()
2387 if ((addr = httpAddrConnect2(http->addrlist, &(http->fd), msec, cancel)) == NULL) in httpReconnect2()
2390 * Unable to connect... in httpReconnect2()
2394 http->error = WSAGetLastError(); in httpReconnect2()
2396 http->error = errno; in httpReconnect2()
2398 http->status = HTTP_STATUS_ERROR; in httpReconnect2()
2401 strerror(http->error))); in httpReconnect2()
2403 return (-1); in httpReconnect2()
2406 DEBUG_printf(("2httpReconnect2: New socket=%d", http->fd)); in httpReconnect2()
2408 if (http->timeout_value > 0) in httpReconnect2()
2409 http_set_timeout(http->fd, http->timeout_value); in httpReconnect2()
2411 http->hostaddr = &(addr->addr); in httpReconnect2()
2412 http->error = 0; in httpReconnect2()
2415 if (http->encryption == HTTP_ENCRYPTION_ALWAYS) in httpReconnect2()
2423 httpAddrClose(NULL, http->fd); in httpReconnect2()
2424 http->fd = -1; in httpReconnect2()
2426 return (-1); in httpReconnect2()
2429 else if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls_upgrade) in httpReconnect2()
2433 DEBUG_printf(("1httpReconnect2: Connected to %s:%d...", in httpReconnect2()
2434 httpAddrString(http->hostaddr, temp, sizeof(temp)), in httpReconnect2()
2435 httpAddrPort(http->hostaddr))); in httpReconnect2()
2442 * 'httpSetAuthString()' - Set the current authorization string.
2445 * the HTTP connection object. You must still call @link httpSetField@ to set
2446 * @code HTTP_FIELD_AUTHORIZATION@ prior to issuing a HTTP request using
2454 httpSetAuthString(http_t *http, /* I - HTTP connection */ in httpSetAuthString()
2455 const char *scheme, /* I - Auth scheme (NULL to clear it) */ in httpSetAuthString()
2456 const char *data) /* I - Auth data (NULL for none) */ in httpSetAuthString() argument
2465 if (http->authstring && http->authstring != http->_authstring) in httpSetAuthString()
2466 free(http->authstring); in httpSetAuthString()
2468 http->authstring = http->_authstring; in httpSetAuthString()
2476 size_t len = strlen(scheme) + (data ? strlen(data) + 1 : 0) + 1; in httpSetAuthString()
2479 if (len > sizeof(http->_authstring)) in httpSetAuthString()
2482 len = sizeof(http->_authstring); in httpSetAuthString()
2484 http->authstring = temp; in httpSetAuthString()
2487 if (data) in httpSetAuthString()
2488 snprintf(http->authstring, len, "%s %s", scheme, data); in httpSetAuthString()
2490 strlcpy(http->authstring, scheme, len); in httpSetAuthString()
2498 http->_authstring[0] = '\0'; in httpSetAuthString()
2504 * 'httpSetCredentials()' - Set the credentials associated with an encrypted
2510 int /* O - Status of call (0 = success) */
2511 httpSetCredentials(http_t *http, /* I - HTTP connection */ in httpSetCredentials()
2512 cups_array_t *credentials) /* I - Array of credentials */ in httpSetCredentials()
2515 return (-1); in httpSetCredentials()
2518 _httpFreeCredentials(http->tls_credentials); in httpSetCredentials()
2520 http->tls_credentials = _httpCreateCredentials(credentials); in httpSetCredentials()
2523 return (http->tls_credentials ? 0 : -1); in httpSetCredentials()
2528 * 'httpSetCookie()' - Set the cookie value(s).
2534 httpSetCookie(http_t *http, /* I - Connection */ in httpSetCookie()
2535 const char *cookie) /* I - Cookie string */ in httpSetCookie()
2540 if (http->cookie) in httpSetCookie()
2541 free(http->cookie); in httpSetCookie()
2544 http->cookie = strdup(cookie); in httpSetCookie()
2546 http->cookie = NULL; in httpSetCookie()
2551 * 'httpSetDefaultField()' - Set the default value of an HTTP header.
2560 httpSetDefaultField(http_t *http, /* I - HTTP connection */ in httpSetDefaultField()
2561 http_field_t field, /* I - Field index */ in httpSetDefaultField()
2562 const char *value)/* I - Value */ in httpSetDefaultField()
2569 if (http->default_fields[field]) in httpSetDefaultField()
2570 free(http->default_fields[field]); in httpSetDefaultField()
2572 http->default_fields[field] = value ? strdup(value) : NULL; in httpSetDefaultField()
2577 * 'httpSetExpect()' - Set the Expect: header in a request.
2586 httpSetExpect(http_t *http, /* I - HTTP connection */ in httpSetExpect()
2587 http_status_t expect) /* I - HTTP status to expect in httpSetExpect()
2593 http->expect = expect; in httpSetExpect()
2598 * 'httpSetField()' - Set the value of an HTTP header.
2602 httpSetField(http_t *http, /* I - HTTP connection */ in httpSetField()
2603 http_field_t field, /* I - Field index */ in httpSetField()
2604 const char *value) /* I - Value */ in httpSetField()
2616 * 'httpSetKeepAlive()' - Set the current Keep-Alive state of a connection.
2623 http_t *http, /* I - HTTP connection */ in httpSetKeepAlive()
2624 http_keepalive_t keep_alive) /* I - New Keep-Alive value */ in httpSetKeepAlive()
2627 http->keep_alive = keep_alive; in httpSetKeepAlive()
2632 * 'httpSetLength()' - Set the content-length and content-encoding.
2638 httpSetLength(http_t *http, /* I - HTTP connection */ in httpSetLength()
2639 size_t length) /* I - Length (0 for chunked) */ in httpSetLength()
2664 * 'httpSetTimeout()' - Set read/write timeouts and an optional callback.
2667 * data pointer and must return 1 to continue or 0 to error (time) out.
2674 http_t *http, /* I - HTTP connection */ in httpSetTimeout()
2675 double timeout, /* I - Number of seconds for timeout, in httpSetTimeout()
2677 http_timeout_cb_t cb, /* I - Callback function or @code NULL@ */ in httpSetTimeout()
2678 void *user_data) /* I - User data pointer */ in httpSetTimeout()
2683 http->timeout_cb = cb; in httpSetTimeout()
2684 http->timeout_data = user_data; in httpSetTimeout()
2685 http->timeout_value = timeout; in httpSetTimeout()
2687 if (http->fd >= 0) in httpSetTimeout()
2688 http_set_timeout(http->fd, timeout); in httpSetTimeout()
2695 * 'httpShutdown()' - Shutdown one side of an HTTP connection.
2701 httpShutdown(http_t *http) /* I - HTTP connection */ in httpShutdown()
2703 if (!http || http->fd < 0) in httpShutdown()
2707 if (http->tls) in httpShutdown()
2712 shutdown(http->fd, SD_RECEIVE); /* Microsoft-ism... */ in httpShutdown()
2714 shutdown(http->fd, SHUT_RD); in httpShutdown()
2720 * 'httpTrace()' - Send an TRACE request to the server.
2725 int /* O - Status of call (0 = success) */
2726 httpTrace(http_t *http, /* I - HTTP connection */ in httpTrace()
2727 const char *uri) /* I - URI for trace */ in httpTrace() argument
2729 return (http_send(http, HTTP_STATE_TRACE, uri)); in httpTrace()
2734 * '_httpUpdate()' - Update the current HTTP status for incoming data.
2736 * Note: Unlike httpUpdate(), this function does not flush pending write data
2740 int /* O - 1 to continue, 0 to stop */
2741 _httpUpdate(http_t *http, /* I - HTTP connection */ in _httpUpdate()
2742 http_status_t *status) /* O - Current HTTP status */ in _httpUpdate()
2745 *value; /* Pointer to value on line */ in _httpUpdate()
2750 …pdate(http=%p, status=%p), state=%s", (void *)http, (void *)status, httpStateString(http->state))); in _httpUpdate()
2767 * Blank line means the start of the data section (if any). Return in _httpUpdate()
2771 * states. Instead, we just return HTTP_STATUS_CONTINUE to the caller and in _httpUpdate()
2775 if (http->status == HTTP_STATUS_CONTINUE) in _httpUpdate()
2777 *status = http->status; in _httpUpdate()
2781 if (http->status < HTTP_STATUS_BAD_REQUEST) in _httpUpdate()
2782 http->digest_tries = 0; in _httpUpdate()
2785 if (http->status == HTTP_STATUS_SWITCHING_PROTOCOLS && !http->tls) in _httpUpdate()
2789 httpAddrClose(NULL, http->fd); in _httpUpdate()
2790 http->fd = -1; in _httpUpdate()
2792 *status = http->status = HTTP_STATUS_ERROR; in _httpUpdate()
2803 DEBUG_puts("1_httpUpdate: Bad Content-Length."); in _httpUpdate()
2804 http->error = EINVAL; in _httpUpdate()
2805 http->status = *status = HTTP_STATUS_ERROR; in _httpUpdate()
2809 switch (http->state) in _httpUpdate()
2815 http->state ++; in _httpUpdate()
2817 DEBUG_printf(("1_httpUpdate: Set state to %s.", in _httpUpdate()
2818 httpStateString(http->state))); in _httpUpdate()
2825 http->state = HTTP_STATE_WAITING; in _httpUpdate()
2827 DEBUG_puts("1_httpUpdate: Reset state to HTTP_STATE_WAITING."); in _httpUpdate()
2837 *status = http->status; in _httpUpdate()
2840 else if (!strncmp(line, "HTTP/", 5) && http->mode == _HTTP_MODE_CLIENT) in _httpUpdate()
2850 *status = http->status = HTTP_STATUS_ERROR; in _httpUpdate()
2856 http->version = (http_version_t)(major * 100 + minor); in _httpUpdate()
2857 *status = http->status = (http_status_t)intstatus; in _httpUpdate()
2878 * "Expect: 100-continue" or similar... in _httpUpdate()
2881 http->expect = (http_status_t)atoi(value); in _httpUpdate()
2886 * "Cookie: name=value[; name=value ...]" - replaces previous cookies... in _httpUpdate()
2896 …ield2(http, HTTP_FIELD_AUTHENTICATION_INFO, "nextnonce", http->nextnonce, (int)sizeof(http->nextno… in _httpUpdate()
2906 http->error = EINVAL; in _httpUpdate()
2907 http->status = *status = HTTP_STATUS_ERROR; in _httpUpdate()
2916 * 'httpUpdate()' - Update the current HTTP state for incoming data.
2919 http_status_t /* O - HTTP status */
2920 httpUpdate(http_t *http) /* I - HTTP connection */ in httpUpdate()
2925 DEBUG_printf(("httpUpdate(http=%p), state=%s", (void *)http, httpStateString(http->state))); in httpUpdate()
2928 * Flush pending data, if any... in httpUpdate()
2931 if (http->wused) in httpUpdate()
2933 DEBUG_puts("2httpUpdate: flushing buffer..."); in httpUpdate()
2940 * If we haven't issued any commands, then there is nothing to "update"... in httpUpdate()
2943 if (http->state == HTTP_STATE_WAITING) in httpUpdate()
2956 if (http->error == EPIPE && http->status > HTTP_STATUS_CONTINUE) in httpUpdate()
2958 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status)); in httpUpdate()
2959 return (http->status); in httpUpdate()
2962 if (http->error) in httpUpdate()
2964 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error, in httpUpdate()
2965 strerror(http->error))); in httpUpdate()
2966 http->status = HTTP_STATUS_ERROR; in httpUpdate()
2979 * '_httpWait()' - Wait for data available on a connection (no flush).
2982 int /* O - 1 if data is available, 0 otherwise */
2983 _httpWait(http_t *http, /* I - HTTP connection */ in _httpWait()
2984 int msec, /* I - Milliseconds to wait */ in _httpWait()
2985 int usessl) /* I - Use SSL context? */ in _httpWait()
2998 if (http->fd < 0) in _httpWait()
3000 DEBUG_printf(("5_httpWait: Returning 0 since fd=%d", http->fd)); in _httpWait()
3005 * Check the SSL/TLS buffers for data first... in _httpWait()
3009 if (http->tls && _httpTLSPending(http)) in _httpWait()
3011 DEBUG_puts("5_httpWait: Return 1 since there is pending TLS data."); in _httpWait()
3017 * Then try doing a select() or poll() to poll the socket... in _httpWait()
3021 pfd.fd = http->fd; in _httpWait()
3034 FD_SET(http->fd, &input_set); in _httpWait()
3036 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd)); in _httpWait()
3043 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout); in _httpWait()
3046 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL); in _httpWait()
3066 * 'httpWait()' - Wait for data available on a connection.
3071 int /* O - 1 if data is available, 0 otherwise */
3072 httpWait(http_t *http, /* I - HTTP connection */ in httpWait()
3073 int msec) /* I - Milliseconds to wait */ in httpWait()
3076 * First see if there is data in the buffer... in httpWait()
3084 if (http->used) in httpWait()
3086 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready."); in httpWait()
3091 if (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in > 0) in httpWait()
3093 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready."); in httpWait()
3099 * Flush pending data, if any... in httpWait()
3102 if (http->wused) in httpWait()
3104 DEBUG_puts("3httpWait: Flushing write buffer."); in httpWait()
3119 * 'httpWrite()' - Write data to a HTTP connection.
3122 * write more than 2GB of data.
3127 int /* O - Number of bytes written */
3128 httpWrite(http_t *http, /* I - HTTP connection */ in httpWrite()
3129 const char *buffer, /* I - Buffer for data */ in httpWrite() argument
3130 int length) /* I - Number of bytes to write */ in httpWrite()
3132 return ((int)httpWrite2(http, buffer, (size_t)length)); in httpWrite()
3137 * 'httpWrite2()' - Write data to a HTTP connection.
3142 ssize_t /* O - Number of bytes written */
3143 httpWrite2(http_t *http, /* I - HTTP connection */ in httpWrite2()
3144 const char *buffer, /* I - Buffer for data */ in httpWrite2() argument
3145 size_t length) /* I - Number of bytes to write */ in httpWrite2()
3150 …DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffe… in httpWrite2()
3156 if (!http || !buffer) in httpWrite2()
3158 DEBUG_puts("1httpWrite2: Returning -1 due to bad input."); in httpWrite2()
3159 return (-1); in httpWrite2()
3166 http->activity = time(NULL); in httpWrite2()
3169 * Buffer small writes for better performance... in httpWrite2()
3173 if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE) in httpWrite2()
3175 DEBUG_printf(("1httpWrite2: http->coding=%d", http->coding)); in httpWrite2()
3184 size_t slen; /* Bytes to write */ in httpWrite2()
3187 ((z_stream *)http->stream)->next_in = (Bytef *)buffer; in httpWrite2()
3188 ((z_stream *)http->stream)->avail_in = (uInt)length; in httpWrite2()
3190 while (deflate((z_stream *)http->stream, Z_NO_FLUSH) == Z_OK) in httpWrite2()
3192 DEBUG_printf(("1httpWrite2: avail_out=%d", ((z_stream *)http->stream)->avail_out)); in httpWrite2()
3194 if (((z_stream *)http->stream)->avail_out > 0) in httpWrite2()
3197 slen = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out; in httpWrite2()
3201 if (slen > 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) in httpWrite2()
3202 sret = http_write_chunk(http, (char *)http->sbuffer, slen); in httpWrite2()
3204 sret = http_write(http, (char *)http->sbuffer, slen); in httpWrite2()
3210 DEBUG_puts("1httpWrite2: Unable to write, returning -1."); in httpWrite2()
3211 return (-1); in httpWrite2()
3214 ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; in httpWrite2()
3215 ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; in httpWrite2()
3225 if (http->wused && (length + (size_t)http->wused) > sizeof(http->wbuffer)) in httpWrite2()
3227 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length=" in httpWrite2()
3228 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length)); in httpWrite2()
3233 if ((length + (size_t)http->wused) <= sizeof(http->wbuffer) && length < sizeof(http->wbuffer)) in httpWrite2()
3236 * Write to buffer... in httpWrite2()
3239 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...", in httpWrite2()
3242 memcpy(http->wbuffer + http->wused, buffer, length); in httpWrite2()
3243 http->wused += (int)length; in httpWrite2()
3249 * Otherwise write the data directly... in httpWrite2()
3252 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...", in httpWrite2()
3255 if (http->data_encoding == HTTP_ENCODING_CHUNKED) in httpWrite2()
3256 bytes = (ssize_t)http_write_chunk(http, buffer, length); in httpWrite2()
3258 bytes = (ssize_t)http_write(http, buffer, length); in httpWrite2()
3264 if (http->data_encoding == HTTP_ENCODING_LENGTH) in httpWrite2()
3265 http->data_remaining -= bytes; in httpWrite2()
3271 * Handle end-of-request processing... in httpWrite2()
3274 if ((http->data_encoding == HTTP_ENCODING_CHUNKED && length == 0) || in httpWrite2()
3275 (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0)) in httpWrite2()
3279 * data, go idle... in httpWrite2()
3283 if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE) in httpWrite2()
3287 if (http->wused) in httpWrite2()
3290 return (-1); in httpWrite2()
3293 if (http->data_encoding == HTTP_ENCODING_CHUNKED) in httpWrite2()
3296 * Send a 0-length chunk at the end of the request... in httpWrite2()
3302 * Reset the data state... in httpWrite2()
3305 http->data_encoding = HTTP_ENCODING_FIELDS; in httpWrite2()
3306 http->data_remaining = 0; in httpWrite2()
3309 if (http->state == HTTP_STATE_POST_RECV) in httpWrite2()
3310 http->state ++; in httpWrite2()
3311 else if (http->state == HTTP_STATE_POST_SEND || in httpWrite2()
3312 http->state == HTTP_STATE_GET_SEND) in httpWrite2()
3313 http->state = HTTP_STATE_WAITING; in httpWrite2()
3315 http->state = HTTP_STATE_STATUS; in httpWrite2()
3317 DEBUG_printf(("2httpWrite2: Changed state to %s.", in httpWrite2()
3318 httpStateString(http->state))); in httpWrite2()
3328 * 'httpWriteResponse()' - Write a HTTP response to a client connection.
3333 int /* O - 0 on success, -1 on error */
3334 httpWriteResponse(http_t *http, /* I - HTTP connection */ in httpWriteResponse()
3335 http_status_t status) /* I - Status code */ in httpWriteResponse()
3350 return (-1); in httpWriteResponse()
3357 if (!http->fields[HTTP_FIELD_DATE]) in httpWriteResponse()
3360 if (status >= HTTP_STATUS_BAD_REQUEST && http->keep_alive) in httpWriteResponse()
3362 http->keep_alive = HTTP_KEEPALIVE_OFF; in httpWriteResponse()
3366 if (http->version == HTTP_VERSION_1_1) in httpWriteResponse()
3368 if (!http->fields[HTTP_FIELD_CONNECTION]) in httpWriteResponse()
3370 if (http->keep_alive) in httpWriteResponse()
3371 httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive"); in httpWriteResponse()
3376 if (http->keep_alive && !http->fields[HTTP_FIELD_KEEP_ALIVE]) in httpWriteResponse()
3384 if (!http->fields[HTTP_FIELD_CONNECTION]) in httpWriteResponse()
3387 if (!http->fields[HTTP_FIELD_UPGRADE]) in httpWriteResponse()
3390 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH]) in httpWriteResponse()
3395 if (!http->fields[HTTP_FIELD_SERVER]) in httpWriteResponse()
3396 …httpSetField(http, HTTP_FIELD_SERVER, http->default_fields[HTTP_FIELD_SERVER] ? http->default_fiel… in httpWriteResponse()
3399 * Set the Accept-Encoding field if it isn't already... in httpWriteResponse()
3402 if (!http->fields[HTTP_FIELD_ACCEPT_ENCODING]) in httpWriteResponse()
3403 …ttpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, http->default_fields[HTTP_FIELD_ACCEPT_ENCODING] ? h… in httpWriteResponse()
3414 old_encoding = http->data_encoding; in httpWriteResponse()
3415 old_remaining = http->data_remaining; in httpWriteResponse()
3416 http->data_encoding = HTTP_ENCODING_FIELDS; in httpWriteResponse()
3418 …if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100, http->version % 100, (int)status… in httpWriteResponse()
3420 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3421 return (-1); in httpWriteResponse()
3439 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3440 return (-1); in httpWriteResponse()
3445 if (http->cookie) in httpWriteResponse()
3447 if (strchr(http->cookie, ';')) in httpWriteResponse()
3449 if (httpPrintf(http, "Set-Cookie: %s\r\n", http->cookie) < 1) in httpWriteResponse()
3451 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3452 return (-1); in httpWriteResponse()
3455 …else if (httpPrintf(http, "Set-Cookie: %s; path=/; httponly;%s\r\n", http->cookie, http->tls ? " s… in httpWriteResponse()
3457 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3458 return (-1); in httpWriteResponse()
3463 * "Click-jacking" defense (STR #4492)... in httpWriteResponse()
3466 if (httpPrintf(http, "X-Frame-Options: DENY\r\n" in httpWriteResponse()
3467 "Content-Security-Policy: frame-ancestors 'none'\r\n") < 1) in httpWriteResponse()
3469 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3470 return (-1); in httpWriteResponse()
3476 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3477 return (-1); in httpWriteResponse()
3482 http->status = HTTP_STATUS_ERROR; in httpWriteResponse()
3483 return (-1); in httpWriteResponse()
3493 http->data_encoding = old_encoding; in httpWriteResponse()
3494 http->data_remaining = old_remaining; in httpWriteResponse()
3497 http->_data_remaining = (int)old_remaining; in httpWriteResponse()
3499 http->_data_remaining = INT_MAX; in httpWriteResponse()
3501 else if (http->state == HTTP_STATE_OPTIONS || in httpWriteResponse()
3502 http->state == HTTP_STATE_HEAD || in httpWriteResponse()
3503 http->state == HTTP_STATE_PUT || in httpWriteResponse()
3504 http->state == HTTP_STATE_TRACE || in httpWriteResponse()
3505 http->state == HTTP_STATE_CONNECT || in httpWriteResponse()
3506 http->state == HTTP_STATE_STATUS) in httpWriteResponse()
3508 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, " in httpWriteResponse()
3509 "was %s.", httpStateString(http->state))); in httpWriteResponse()
3510 http->state = HTTP_STATE_WAITING; in httpWriteResponse()
3515 * Force data_encoding and data_length to be set according to the response in httpWriteResponse()
3521 if (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0) in httpWriteResponse()
3523 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, " in httpWriteResponse()
3524 "was %s.", httpStateString(http->state))); in httpWriteResponse()
3525 http->state = HTTP_STATE_WAITING; in httpWriteResponse()
3529 if (http->state == HTTP_STATE_POST_RECV || http->state == HTTP_STATE_GET) in httpWriteResponse()
3530 http->state ++; in httpWriteResponse()
3549 * 'http_add_field()' - Add a value for a HTTP field, appending if needed.
3553 http_add_field(http_t *http, /* I - HTTP connection */ in http_add_field()
3554 http_field_t field, /* I - HTTP field */ in http_add_field()
3555 const char *value, /* I - Value string */ in http_add_field()
3556 int append) /* I - Append value? */ in http_add_field()
3567 * Special-case for Host: as we don't want a trailing "." on the hostname and in http_add_field()
3568 * need to bracket IPv6 numeric addresses. in http_add_field()
3593 ptr = temp + strlen(temp) - 1; in http_add_field()
3603 if (!append && http->fields[field]) in http_add_field()
3605 if (http->fields[field] != http->_fields[field]) in http_add_field()
3606 free(http->fields[field]); in http_add_field()
3608 http->fields[field] = NULL; in http_add_field()
3615 http->_fields[field][0] = '\0'; in http_add_field()
3619 if (http->fields[field]) in http_add_field()
3621 fieldlen = strlen(http->fields[field]); in http_add_field()
3633 * Copy short values to legacy char arrays (maintained for binary in http_add_field()
3642 snprintf(combined, sizeof(combined), "%s, %s", http->_fields[field], value); in http_add_field()
3646 strlcpy(http->_fields[field], value, sizeof(http->_fields[field])); in http_add_field()
3647 http->fields[field] = http->_fields[field]; in http_add_field()
3657 if (http->fields[field] == http->_fields[field]) in http_add_field()
3661 http->fields[field] = combined; in http_add_field()
3662 snprintf(combined, total + 1, "%s, %s", http->_fields[field], value); in http_add_field()
3665 else if ((combined = realloc(http->fields[field], total + 1)) != NULL) in http_add_field()
3667 http->fields[field] = combined; in http_add_field()
3678 http->fields[field] = strdup(value); in http_add_field()
3682 if (field == HTTP_FIELD_CONTENT_ENCODING && http->data_encoding != HTTP_ENCODING_FIELDS) in http_add_field()
3693 * 'http_content_coding_finish()' - Finish doing any content encoding.
3698 http_t *http) /* I - HTTP connection */ in http_content_coding_finish()
3701 Byte dummy[1]; /* Dummy read buffer */ in http_content_coding_finish()
3702 size_t bytes; /* Number of bytes to write */ in http_content_coding_finish()
3706 DEBUG_printf(("1http_content_coding_finishing: http->coding=%d", http->coding)); in http_content_coding_finish()
3708 switch (http->coding) in http_content_coding_finish()
3712 ((z_stream *)http->stream)->next_in = dummy; in http_content_coding_finish()
3713 ((z_stream *)http->stream)->avail_in = 0; in http_content_coding_finish()
3717 zerr = deflate((z_stream *)http->stream, Z_FINISH); in http_content_coding_finish()
3718 bytes = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out; in http_content_coding_finish()
3724 if (http->data_encoding == HTTP_ENCODING_CHUNKED) in http_content_coding_finish()
3725 http_write_chunk(http, (char *)http->sbuffer, bytes); in http_content_coding_finish()
3727 http_write(http, (char *)http->sbuffer, bytes); in http_content_coding_finish()
3730 ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; in http_content_coding_finish()
3731 ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; in http_content_coding_finish()
3735 deflateEnd((z_stream *)http->stream); in http_content_coding_finish()
3737 free(http->sbuffer); in http_content_coding_finish()
3738 free(http->stream); in http_content_coding_finish()
3740 http->sbuffer = NULL; in http_content_coding_finish()
3741 http->stream = NULL; in http_content_coding_finish()
3743 if (http->wused) in http_content_coding_finish()
3749 inflateEnd((z_stream *)http->stream); in http_content_coding_finish()
3751 free(http->sbuffer); in http_content_coding_finish()
3752 free(http->stream); in http_content_coding_finish()
3754 http->sbuffer = NULL; in http_content_coding_finish()
3755 http->stream = NULL; in http_content_coding_finish()
3762 http->coding = _HTTP_CODING_IDENTITY; in http_content_coding_finish()
3767 * 'http_content_coding_start()' - Start doing content encoding.
3772 http_t *http, /* I - HTTP connection */ in http_content_coding_start()
3773 const char *value) /* I - Value of Content-Encoding */ in http_content_coding_start()
3781 if (http->coding != _HTTP_CODING_IDENTITY) in http_content_coding_start()
3783 DEBUG_printf(("1http_content_coding_start: http->coding already %d.", in http_content_coding_start()
3784 http->coding)); in http_content_coding_start()
3787 else if (!strcmp(value, "x-gzip") || !strcmp(value, "gzip")) in http_content_coding_start()
3789 if (http->state == HTTP_STATE_GET_SEND || in http_content_coding_start()
3790 http->state == HTTP_STATE_POST_SEND) in http_content_coding_start()
3791 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_GZIP : in http_content_coding_start()
3793 else if (http->state == HTTP_STATE_POST_RECV || in http_content_coding_start()
3794 http->state == HTTP_STATE_PUT_RECV) in http_content_coding_start()
3795 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_GZIP : in http_content_coding_start()
3803 else if (!strcmp(value, "x-deflate") || !strcmp(value, "deflate")) in http_content_coding_start()
3805 if (http->state == HTTP_STATE_GET_SEND || in http_content_coding_start()
3806 http->state == HTTP_STATE_POST_SEND) in http_content_coding_start()
3807 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_DEFLATE : in http_content_coding_start()
3809 else if (http->state == HTTP_STATE_POST_RECV || in http_content_coding_start()
3810 http->state == HTTP_STATE_PUT_RECV) in http_content_coding_start()
3811 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_DEFLATE : in http_content_coding_start()
3829 if (http->wused) in http_content_coding_start()
3832 if ((http->sbuffer = malloc(_HTTP_MAX_SBUFFER)) == NULL) in http_content_coding_start()
3834 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3835 http->error = errno; in http_content_coding_start()
3840 * Window size for compression is 11 bits - optimal based on PWG Raster in http_content_coding_start()
3841 * sample files on pwg.org. -11 is raw deflate, 27 is gzip, per ZLIB in http_content_coding_start()
3845 if ((http->stream = calloc(1, sizeof(z_stream))) == NULL) in http_content_coding_start()
3847 free(http->sbuffer); in http_content_coding_start()
3849 http->sbuffer = NULL; in http_content_coding_start()
3850 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3851 http->error = errno; in http_content_coding_start()
3855 …(zerr = deflateInit2((z_stream *)http->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, coding == _HTTP_… in http_content_coding_start()
3857 free(http->sbuffer); in http_content_coding_start()
3858 free(http->stream); in http_content_coding_start()
3860 http->sbuffer = NULL; in http_content_coding_start()
3861 http->stream = NULL; in http_content_coding_start()
3862 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3863 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; in http_content_coding_start()
3867 ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; in http_content_coding_start()
3868 ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; in http_content_coding_start()
3873 if ((http->sbuffer = malloc(_HTTP_MAX_SBUFFER)) == NULL) in http_content_coding_start()
3875 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3876 http->error = errno; in http_content_coding_start()
3881 * Window size for decompression is up to 15 bits (maximum supported). in http_content_coding_start()
3882 * -15 is raw inflate, 31 is gunzip, per ZLIB documentation. in http_content_coding_start()
3885 if ((http->stream = calloc(1, sizeof(z_stream))) == NULL) in http_content_coding_start()
3887 free(http->sbuffer); in http_content_coding_start()
3889 http->sbuffer = NULL; in http_content_coding_start()
3890 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3891 http->error = errno; in http_content_coding_start()
3895 …if ((zerr = inflateInit2((z_stream *)http->stream, coding == _HTTP_CODING_INFLATE ? -15 : 31)) < Z… in http_content_coding_start()
3897 free(http->sbuffer); in http_content_coding_start()
3898 free(http->stream); in http_content_coding_start()
3900 http->sbuffer = NULL; in http_content_coding_start()
3901 http->stream = NULL; in http_content_coding_start()
3902 http->status = HTTP_STATUS_ERROR; in http_content_coding_start()
3903 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; in http_content_coding_start()
3907 ((z_stream *)http->stream)->avail_in = 0; in http_content_coding_start()
3908 ((z_stream *)http->stream)->next_in = http->sbuffer; in http_content_coding_start()
3915 http->coding = coding; in http_content_coding_start()
3917 DEBUG_printf(("1http_content_coding_start: http->coding now %d.", in http_content_coding_start()
3918 http->coding)); in http_content_coding_start()
3924 * 'http_create()' - Create an unconnected HTTP connection.
3927 static http_t * /* O - HTTP connection */
3929 const char *host, /* I - Hostname */ in http_create()
3930 int port, /* I - Port number */ in http_create()
3931 http_addrlist_t *addrlist, /* I - Address list or @code NULL@ */ in http_create()
3932 int family, /* I - Address family or AF_UNSPEC */ in http_create()
3933 http_encryption_t encryption, /* I - Encryption to use */ in http_create()
3934 int blocking, /* I - 1 for blocking mode */ in http_create()
3935 _http_mode_t mode) /* I - _HTTP_MODE_CLIENT or _SERVER */ in http_create()
3979 * Initialize the HTTP data... in http_create()
3982 http->mode = mode; in http_create()
3983 http->activity = time(NULL); in http_create()
3984 http->addrlist = myaddrlist; in http_create()
3985 http->blocking = blocking; in http_create()
3986 http->fd = -1; in http_create()
3988 http->gssctx = GSS_C_NO_CONTEXT; in http_create()
3989 http->gssname = GSS_C_NO_NAME; in http_create()
3991 http->status = HTTP_STATUS_CONTINUE; in http_create()
3992 http->version = HTTP_VERSION_1_1; in http_create()
3995 strlcpy(http->hostname, host, sizeof(http->hostname)); in http_create()
3998 http->encryption = HTTP_ENCRYPTION_ALWAYS; in http_create()
4000 http->encryption = encryption; in http_create()
4014 * 'http_debug_hex()' - Do a hex dump of a buffer.
4018 http_debug_hex(const char *prefix, /* I - Prefix for line */ in http_debug_hex()
4019 const char *buffer, /* I - Buffer to dump */ in http_debug_hex() argument
4020 int bytes) /* I - Bytes to dump */ in http_debug_hex()
4024 char line[255], /* Line buffer */ in http_debug_hex()
4040 snprintf(ptr, 3, "%02X", buffer[i + j] & 255); in http_debug_hex()
4054 ch = buffer[i + j] & 255; in http_debug_hex()
4070 * 'http_read()' - Read a buffer from a HTTP connection.
4072 * This function does the low-level read from the socket, retrying and timing
4076 static ssize_t /* O - Number of bytes read or -1 on error */
4077 http_read(http_t *http, /* I - HTTP connection */ in http_read()
4078 char *buffer, /* I - Buffer */ in http_read() argument
4079 size_t length) /* I - Maximum bytes to read */ in http_read()
4084 …DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffer… in http_read()
4086 if (!http->blocking || http->timeout_value > 0.0) in http_read()
4088 while (!httpWait(http, http->wait_value)) in http_read()
4090 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in http_read()
4098 DEBUG_printf(("2http_read: Reading %d bytes into buffer.", (int)length)); in http_read()
4103 if (http->tls) in http_read()
4104 bytes = _httpTLSRead(http, buffer, (int)length); in http_read()
4107 bytes = recv(http->fd, buffer, length, 0); in http_read()
4114 http->error = WSAGetLastError(); in http_read()
4115 return (-1); in http_read()
4119 if (!http->timeout_cb || in http_read()
4120 !(*http->timeout_cb)(http, http->timeout_data)) in http_read()
4122 http->error = WSAEWOULDBLOCK; in http_read()
4123 return (-1); in http_read()
4131 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data)) in http_read()
4133 http->error = errno; in http_read()
4134 return (-1); in http_read()
4136 else if (!http->timeout_cb && errno != EAGAIN) in http_read()
4138 http->error = errno; in http_read()
4139 return (-1); in http_read()
4144 http->error = errno; in http_read()
4145 return (-1); in http_read()
4152 DEBUG_printf(("2http_read: Read " CUPS_LLFMT " bytes into buffer.", in http_read()
4156 http_debug_hex("http_read", buffer, (int)bytes); in http_read()
4165 http->error = WSAGetLastError(); in http_read()
4167 if (errno == EINTR || (errno == EAGAIN && !http->timeout_cb)) in http_read()
4170 http->error = errno; in http_read()
4175 http->error = EPIPE; in http_read()
4184 * 'http_read_buffered()' - Do a buffered read from a HTTP connection.
4186 * This function reads data from the HTTP buffer or from the socket, as needed.
4189 static ssize_t /* O - Number of bytes read or -1 on error */
4190 http_read_buffered(http_t *http, /* I - HTTP connection */ in http_read_buffered()
4191 char *buffer, /* I - Buffer */ in http_read_buffered() argument
4192 size_t length) /* I - Maximum bytes to read */ in http_read_buffered()
4197 …ttp_read_buffered(http=%p, buffer=%p, length=" CUPS_LLFMT ") used=%d", (void *)http, (void *)buffe… in http_read_buffered()
4199 if (http->used > 0) in http_read_buffered()
4201 if (length > (size_t)http->used) in http_read_buffered()
4202 bytes = (ssize_t)http->used; in http_read_buffered()
4206 DEBUG_printf(("2http_read: Grabbing %d bytes from input buffer.", in http_read_buffered()
4209 memcpy(buffer, http->buffer, (size_t)bytes); in http_read_buffered()
4210 http->used -= (int)bytes; in http_read_buffered()
4212 if (http->used > 0) in http_read_buffered()
4213 memmove(http->buffer, http->buffer + bytes, (size_t)http->used); in http_read_buffered()
4216 bytes = http_read(http, buffer, length); in http_read_buffered()
4223 * 'http_read_chunk()' - Read a chunk from a HTTP connection.
4226 * returning the number of bytes placed in the buffer.
4229 static ssize_t /* O - Number of bytes read or -1 on error */
4230 http_read_chunk(http_t *http, /* I - HTTP connection */ in http_read_chunk()
4231 char *buffer, /* I - Buffer */ in http_read_chunk() argument
4232 size_t length) /* I - Maximum bytes to read */ in http_read_chunk()
4234 …DEBUG_printf(("http_read_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)… in http_read_chunk()
4236 if (http->data_remaining <= 0) in http_read_chunk()
4256 http->data_remaining = strtoll(len, NULL, 16); in http_read_chunk()
4258 if (http->data_remaining < 0) in http_read_chunk()
4261 CUPS_LLFMT ")", len, CUPS_LLCAST http->data_remaining)); in http_read_chunk()
4266 len, CUPS_LLCAST http->data_remaining)); in http_read_chunk()
4268 if (http->data_remaining == 0) in http_read_chunk()
4271 * 0-length chunk, grab trailing blank line... in http_read_chunk()
4279 CUPS_LLCAST http->data_remaining)); in http_read_chunk()
4281 if (http->data_remaining <= 0) in http_read_chunk()
4283 else if (length > (size_t)http->data_remaining) in http_read_chunk()
4284 length = (size_t)http->data_remaining; in http_read_chunk()
4286 return (http_read_buffered(http, buffer, length)); in http_read_chunk()
4291 * 'http_send()' - Send a request with all fields and the trailing blank line.
4294 static int /* O - 0 on success, non-zero on error */
4295 http_send(http_t *http, /* I - HTTP connection */ in http_send()
4296 http_state_t request, /* I - Request code */ in http_send()
4297 const char *uri) /* I - URI */ in http_send() argument
4300 char buf[1024]; /* Encoded URI buffer */ in http_send()
4322 …DEBUG_printf(("4http_send(http=%p, request=HTTP_%s, uri=\"%s\")", (void *)http, codes[request], ur… in http_send()
4324 if (http == NULL || uri == NULL) in http_send()
4325 return (-1); in http_send()
4328 * Set the User-Agent field if it isn't already... in http_send()
4331 if (!http->fields[HTTP_FIELD_USER_AGENT]) in http_send()
4333 if (http->default_fields[HTTP_FIELD_USER_AGENT]) in http_send()
4334 httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_fields[HTTP_FIELD_USER_AGENT]); in http_send()
4340 * Set the Accept-Encoding field if it isn't already... in http_send()
4343 if (!http->fields[HTTP_FIELD_ACCEPT_ENCODING] && http->default_fields[HTTP_FIELD_ACCEPT_ENCODING]) in http_send()
4344 … httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, http->default_fields[HTTP_FIELD_ACCEPT_ENCODING]); in http_send()
4347 * Encode the URI as needed... in http_send()
4350 _httpEncodeURI(buf, uri, sizeof(buf)); in http_send()
4356 if (http->fd < 0 || http->status == HTTP_STATUS_ERROR || in http_send()
4357 http->status >= HTTP_STATUS_BAD_REQUEST) in http_send()
4360 http->fd, http->status, http->tls_upgrade)); in http_send()
4363 return (-1); in http_send()
4367 * Flush any written data that is pending... in http_send()
4370 if (http->wused) in http_send()
4374 return (-1); in http_send()
4381 http->state = request; in http_send()
4382 http->data_encoding = HTTP_ENCODING_FIELDS; in http_send()
4385 http->state ++; in http_send()
4387 http->status = HTTP_STATUS_CONTINUE; in http_send()
4390 if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls) in http_send()
4399 http->status = HTTP_STATUS_ERROR; in http_send()
4400 return (-1); in http_send()
4411 httpAddrPort(http->hostaddr)) < 1) in http_send()
4413 http->status = HTTP_STATUS_ERROR; in http_send()
4414 return (-1); in http_send()
4419 http->status = HTTP_STATUS_ERROR; in http_send()
4420 return (-1); in http_send()
4424 if (http->cookie) in http_send()
4425 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1) in http_send()
4427 http->status = HTTP_STATUS_ERROR; in http_send()
4428 return (-1); in http_send()
4431 DEBUG_printf(("5http_send: expect=%d, mode=%d, state=%d", http->expect, in http_send()
4432 http->mode, http->state)); in http_send()
4434 if (http->expect == HTTP_STATUS_CONTINUE && http->mode == _HTTP_MODE_CLIENT && in http_send()
4435 (http->state == HTTP_STATE_POST_RECV || in http_send()
4436 http->state == HTTP_STATE_PUT_RECV)) in http_send()
4437 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1) in http_send()
4439 http->status = HTTP_STATUS_ERROR; in http_send()
4440 return (-1); in http_send()
4445 http->status = HTTP_STATUS_ERROR; in http_send()
4446 return (-1); in http_send()
4450 return (-1); in http_send()
4459 if (http->fields[HTTP_FIELD_AUTHORIZATION] && http->authstring && in http_send()
4460 (!strncmp(http->authstring, "Negotiate", 9) || in http_send()
4461 !strncmp(http->authstring, "AuthRef", 7))) in http_send()
4463 http->_authstring[0] = '\0'; in http_send()
4465 if (http->authstring != http->_authstring) in http_send()
4466 free(http->authstring); in http_send()
4468 http->authstring = http->_authstring; in http_send()
4476 * 'http_set_length()' - Set the data_encoding and data_remaining values.
4479 static off_t /* O - Remainder or -1 on error */
4480 http_set_length(http_t *http) /* I - Connection */ in http_set_length()
4485 …http_set_length(http=%p) mode=%d state=%s", (void *)http, http->mode, httpStateString(http->state)… in http_set_length()
4489 if (http->mode == _HTTP_MODE_SERVER && in http_set_length()
4490 http->state != HTTP_STATE_GET_SEND && in http_set_length()
4491 http->state != HTTP_STATE_PUT && in http_set_length()
4492 http->state != HTTP_STATE_POST && in http_set_length()
4493 http->state != HTTP_STATE_POST_SEND) in http_set_length()
4501 DEBUG_puts("1http_set_length: Setting data_encoding to " in http_set_length()
4503 http->data_encoding = HTTP_ENCODING_CHUNKED; in http_set_length()
4507 DEBUG_puts("1http_set_length: Setting data_encoding to " in http_set_length()
4509 http->data_encoding = HTTP_ENCODING_LENGTH; in http_set_length()
4512 DEBUG_printf(("1http_set_length: Setting data_remaining to " CUPS_LLFMT ".", in http_set_length()
4514 http->data_remaining = remaining; in http_set_length()
4517 http->_data_remaining = (int)remaining; in http_set_length()
4519 http->_data_remaining = INT_MAX; in http_set_length()
4526 * 'http_set_timeout()' - Set the socket timeout values.
4530 http_set_timeout(int fd, /* I - File descriptor */ in http_set_timeout()
4531 double timeout) /* I - Timeout in seconds */ in http_set_timeout()
4553 * 'http_set_wait()' - Set the default wait value for reads.
4557 http_set_wait(http_t *http) /* I - HTTP connection */ in http_set_wait()
4559 if (http->blocking) in http_set_wait()
4561 http->wait_value = (int)(http->timeout_value * 1000); in http_set_wait()
4563 if (http->wait_value <= 0) in http_set_wait()
4564 http->wait_value = 60000; in http_set_wait()
4567 http->wait_value = 10000; in http_set_wait()
4573 * 'http_tls_upgrade()' - Force upgrade to TLS encryption.
4576 static int /* O - Status of connection */
4577 http_tls_upgrade(http_t *http) /* I - HTTP connection */ in http_tls_upgrade()
4580 http_t myhttp; /* Local copy of HTTP data */ in http_tls_upgrade()
4586 * Flush the connection to make sure any previous "Upgrade" message in http_tls_upgrade()
4593 * Copy the HTTP data to a local variable so we can do the OPTIONS in http_tls_upgrade()
4594 * request without interfering with the existing request data... in http_tls_upgrade()
4600 * Send an OPTIONS request to the server, requiring SSL or TLS in http_tls_upgrade()
4604 http->tls_upgrade = 1; in http_tls_upgrade()
4605 memset(http->fields, 0, sizeof(http->fields)); in http_tls_upgrade()
4606 http->expect = (http_status_t)0; in http_tls_upgrade()
4608 if (http->hostname[0] == '/') in http_tls_upgrade()
4611 httpSetField(http, HTTP_FIELD_HOST, http->hostname); in http_tls_upgrade()
4626 * Restore the HTTP request data... in http_tls_upgrade()
4629 memcpy(http->_fields, myhttp._fields, sizeof(http->_fields)); in http_tls_upgrade()
4630 memcpy(http->fields, myhttp.fields, sizeof(http->fields)); in http_tls_upgrade()
4632 http->data_encoding = myhttp.data_encoding; in http_tls_upgrade()
4633 http->data_remaining = myhttp.data_remaining; in http_tls_upgrade()
4634 http->_data_remaining = myhttp._data_remaining; in http_tls_upgrade()
4635 http->expect = myhttp.expect; in http_tls_upgrade()
4636 http->digest_tries = myhttp.digest_tries; in http_tls_upgrade()
4637 http->tls_upgrade = 0; in http_tls_upgrade()
4643 if (!http->tls) in http_tls_upgrade()
4652 httpAddrClose(NULL, http->fd); in http_tls_upgrade()
4654 http->fd = -1; in http_tls_upgrade()
4656 return (-1); in http_tls_upgrade()
4665 * 'http_write()' - Write a buffer to a HTTP connection.
4668 static ssize_t /* O - Number of bytes written */
4669 http_write(http_t *http, /* I - HTTP connection */ in http_write()
4670 const char *buffer, /* I - Buffer for data */ in http_write() argument
4671 size_t length) /* I - Number of bytes to write */ in http_write()
4677 …DEBUG_printf(("2http_write(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buff… in http_write()
4678 http->error = 0; in http_write()
4683 DEBUG_printf(("3http_write: About to write %d bytes.", (int)length)); in http_write()
4685 if (http->timeout_value > 0.0) in http_write()
4698 pfd.fd = http->fd; in http_write()
4701 while ((nfds = poll(&pfd, 1, http->wait_value)) < 0 && in http_write()
4709 FD_SET(http->fd, &output_set); in http_write()
4711 timeout.tv_sec = http->wait_value / 1000; in http_write()
4712 timeout.tv_usec = 1000 * (http->wait_value % 1000); in http_write()
4714 nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout); in http_write()
4726 http->error = errno; in http_write()
4727 return (-1); in http_write()
4729 else if (nfds == 0 && (!http->timeout_cb || !(*http->timeout_cb)(http, http->timeout_data))) in http_write()
4732 http->error = WSAEWOULDBLOCK; in http_write()
4734 http->error = EWOULDBLOCK; in http_write()
4736 return (-1); in http_write()
4743 if (http->tls) in http_write()
4744 bytes = _httpTLSWrite(http, buffer, (int)length); in http_write()
4747 bytes = send(http->fd, buffer, length, 0); in http_write()
4759 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in http_write()
4762 http->error = WSAGetLastError(); in http_write()
4764 else if (WSAGetLastError() != http->error && in http_write()
4767 http->error = WSAGetLastError(); in http_write()
4776 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) in http_write()
4778 else if (!http->timeout_cb && errno == EAGAIN) in http_write()
4781 http->error = errno; in http_write()
4783 else if (errno != http->error && errno != ECONNRESET) in http_write()
4785 http->error = errno; in http_write()
4790 DEBUG_printf(("3http_write: error writing data (%s).", in http_write()
4791 strerror(http->error))); in http_write()
4793 return (-1); in http_write()
4796 buffer += bytes; in http_write()
4798 length -= (size_t)bytes; in http_write()
4802 http_debug_hex("http_write", buffer - tbytes, (int)tbytes); in http_write()
4812 * 'http_write_chunk()' - Write a chunked buffer.
4815 static ssize_t /* O - Number bytes written */
4816 http_write_chunk(http_t *http, /* I - HTTP connection */ in http_write_chunk()
4817 const char *buffer, /* I - Buffer to write */ in http_write_chunk() argument
4818 size_t length) /* I - Length of buffer */ in http_write_chunk()
4824 …DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void … in http_write_chunk()
4827 * Write the chunk header, data, and trailer. in http_write_chunk()
4834 return (-1); in http_write_chunk()
4837 if ((bytes = http_write(http, buffer, length)) < 0) in http_write_chunk()
4839 DEBUG_puts("8http_write_chunk: http_write of buffer failed."); in http_write_chunk()
4840 return (-1); in http_write_chunk()
4846 return (-1); in http_write_chunk()