]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Merge changes from CUPS 1.7svn-r10861.
[thirdparty/cups.git] / cups / http.c
1 /*
2 * "$Id: http.c 7850 2008-08-20 00:07:25Z mike $"
3 *
4 * HTTP routines for CUPS.
5 *
6 * Copyright 2007-2013 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
8 *
9 * This file contains Kerberos support code, copyright 2006 by
10 * Jelmer Vernooij.
11 *
12 * These coded instructions, statements, and computer programs are the
13 * property of Apple Inc. and are protected by Federal copyright
14 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
15 * which should have been included with this file. If this file is
16 * file is missing or damaged, see the license at "http://www.cups.org/".
17 *
18 * This file is subject to the Apple OS-Developed Software exception.
19 *
20 * Contents:
21 *
22 * httpAcceptConnection() - Accept a new HTTP client connection from
23 * the specified listening socket.
24 * httpAddCredential() - Allocates and adds a single credential to
25 * an array.
26 * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP
27 * connections.
28 * httpBlocking() - Set blocking/non-blocking behavior on a
29 * connection.
30 * httpCheck() - Check to see if there is a pending response
31 * from the server.
32 * httpClearCookie() - Clear the cookie value(s).
33 * httpClearFields() - Clear HTTP request fields.
34 * httpClose() - Close an HTTP connection.
35 * httpConnect() - Connect to a HTTP server.
36 * httpConnect2() - Connect to a HTTP server.
37 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
38 * httpCopyCredentials() - Copy the credentials associated with an
39 * encrypted connection.
40 * _httpCreateCredentials() - Create credentials in the internal format.
41 * httpDelete() - Send a DELETE request to the server.
42 * _httpDisconnect() - Disconnect a HTTP connection.
43 * httpEncryption() - Set the required encryption on the link.
44 * httpError() - Get the last error on a connection.
45 * httpFlush() - Flush data from a HTTP connection.
46 * httpFlushWrite() - Flush data in write buffer.
47 * _httpFreeCredentials() - Free internal credentials.
48 * httpFreeCredentials() - Free an array of credentials.
49 * httpGet() - Send a GET request to the server.
50 * httpGetContentEncoding() - Get a common content encoding, if any,
51 * between the client and server.
52 * httpGetAuthString() - Get the current authorization string.
53 * httpGetBlocking() - Get the blocking/non-block state of a
54 * connection.
55 * httpGetCookie() - Get any cookie data from the response.
56 * httpGetExpect() - Get the value of the Expect header, if any.
57 * httpGetFd() - Get the file descriptor associated with a
58 * connection.
59 * httpGetField() - Get a field value from a request/response.
60 * httpGetLength() - Get the amount of data remaining from the
61 * content-length or transfer-encoding fields.
62 * httpGetLength2() - Get the amount of data remaining from the
63 * content-length or transfer-encoding fields.
64 * httpGets() - Get a line of text from a HTTP connection.
65 * httpGetState() - Get the current state of the HTTP request.
66 * httpGetStatus() - Get the status of the last HTTP request.
67 * httpGetSubField() - Get a sub-field value.
68 * httpGetSubField2() - Get a sub-field value.
69 * httpGetVersion() - Get the HTTP version at the other end.
70 * httpHead() - Send a HEAD request to the server.
71 * httpInitialize() - Initialize the HTTP interface library and
72 * set the default HTTP proxy (if any).
73 * httpOptions() - Send an OPTIONS request to the server.
74 * httpPeek() - Peek at data from a HTTP connection.
75 * httpPost() - Send a POST request to the server.
76 * httpPrintf() - Print a formatted string to a HTTP
77 * connection.
78 * httpPut() - Send a PUT request to the server.
79 * httpRead() - Read data from a HTTP connection.
80 * httpRead2() - Read data from a HTTP connection.
81 * _httpReadCDSA() - Read function for the CDSA library.
82 * _httpReadGNUTLS() - Read function for the GNU TLS library.
83 * httpReadRequest() - Read a HTTP request from a connection.
84 * httpReconnect() - Reconnect to a HTTP server.
85 * httpReconnect2() - Reconnect to a HTTP server with timeout and
86 * optional cancel.
87 * httpSetAuthString() - Set the current authorization string.
88 * httpSetCredentials() - Set the credentials associated with an
89 * encrypted connection.
90 * httpSetCookie() - Set the cookie value(s).
91 * httpSetDefaultField() - Set the default value of an HTTP header.
92 * httpSetExpect() - Set the Expect: header in a request.
93 * httpSetField() - Set the value of an HTTP header.
94 * httpSetLength() - Set the content-length and
95 * content-encoding.
96 * httpSetTimeout() - Set read/write timeouts and an optional
97 * callback.
98 * httpTrace() - Send an TRACE request to the server.
99 * _httpUpdate() - Update the current HTTP status for incoming
100 * data.
101 * httpUpdate() - Update the current HTTP state for incoming
102 * data.
103 * _httpWait() - Wait for data available on a connection (no
104 * flush).
105 * httpWait() - Wait for data available on a connection.
106 * httpWrite() - Write data to a HTTP connection.
107 * httpWrite2() - Write data to a HTTP connection.
108 * _httpWriteCDSA() - Write function for the CDSA library.
109 * _httpWriteGNUTLS() - Write function for the GNU TLS library.
110 * httpWriteResponse() - Write a HTTP response to a client
111 * connection.
112 * http_bio_ctrl() - Control the HTTP connection.
113 * http_bio_free() - Free OpenSSL data.
114 * http_bio_new() - Initialize an OpenSSL BIO structure.
115 * http_bio_puts() - Send a string for OpenSSL.
116 * http_bio_read() - Read data for OpenSSL.
117 * http_bio_write() - Write data for OpenSSL.
118 * http_content_coding_finish() - Finish doing any content encoding.
119 * http_content_coding_start() - Start doing content encoding.
120 * http_create() - Create an unconnected HTTP connection.
121 * http_debug_hex() - Do a hex dump of a buffer.
122 * http_field() - Return the field index for a field name.
123 * http_read() - Read a buffer from a HTTP connection.
124 * http_read_buffered() - Do a buffered read from a HTTP connection.
125 * http_read_chunk() - Read a chunk from a HTTP connection.
126 * http_read_ssl() - Read from a SSL/TLS connection.
127 * http_send() - Send a request with all fields and the
128 * trailing blank line.
129 * http_set_credentials() - Set the SSL/TLS credentials.
130 * http_set_length() - Set the data_encoding and data_remaining
131 * values.
132 * http_set_timeout() - Set the socket timeout values.
133 * http_set_wait() - Set the default wait value for reads.
134 * http_setup_ssl() - Set up SSL/TLS support on a connection.
135 * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
136 * http_upgrade() - Force upgrade to TLS encryption.
137 * http_write() - Write a buffer to a HTTP connection.
138 * http_write_chunk() - Write a chunked buffer.
139 * http_write_ssl() - Write to a SSL/TLS connection.
140 */
141
142 /*
143 * Include necessary headers...
144 */
145
146 #include "cups-private.h"
147 #include <fcntl.h>
148 #include <math.h>
149 #ifdef WIN32
150 # include <tchar.h>
151 #else
152 # include <signal.h>
153 # include <sys/time.h>
154 # include <sys/resource.h>
155 #endif /* WIN32 */
156 #ifdef HAVE_POLL
157 # include <poll.h>
158 #endif /* HAVE_POLL */
159
160
161 /*
162 * Local functions...
163 */
164
165 #ifdef HAVE_LIBZ
166 static void http_content_coding_finish(http_t *http);
167 static void http_content_coding_start(http_t *http,
168 const char *value);
169 #endif /* HAVE_LIBZ */
170 static http_t *http_create(const char *host, int port,
171 http_addrlist_t *addrlist, int family,
172 http_encryption_t encryption,
173 int blocking, _http_mode_t mode);
174 #ifdef DEBUG
175 static void http_debug_hex(const char *prefix, const char *buffer,
176 int bytes);
177 #endif /* DEBUG */
178 static http_field_t http_field(const char *name);
179 static ssize_t http_read(http_t *http, char *buffer, size_t length);
180 static ssize_t http_read_buffered(http_t *http, char *buffer, size_t length);
181 static ssize_t http_read_chunk(http_t *http, char *buffer, size_t length);
182 static int http_send(http_t *http, http_state_t request,
183 const char *uri);
184 static ssize_t http_write(http_t *http, const char *buffer,
185 size_t length);
186 static ssize_t http_write_chunk(http_t *http, const char *buffer,
187 size_t length);
188 #ifdef HAVE_SSL
189 static int http_read_ssl(http_t *http, char *buf, int len);
190 # ifdef HAVE_CDSASSL
191 static int http_set_credentials(http_t *http);
192 # endif /* HAVE_CDSASSL */
193 #endif /* HAVE_SSL */
194 static off_t http_set_length(http_t *http);
195 static void http_set_timeout(int fd, double timeout);
196 static void http_set_wait(http_t *http);
197 #ifdef HAVE_SSL
198 static int http_setup_ssl(http_t *http);
199 static void http_shutdown_ssl(http_t *http);
200 static int http_upgrade(http_t *http);
201 static int http_write_ssl(http_t *http, const char *buf, int len);
202 #endif /* HAVE_SSL */
203
204
205 /*
206 * Local globals...
207 */
208
209 static const char * const http_fields[] =
210 {
211 "Accept-Language",
212 "Accept-Ranges",
213 "Authorization",
214 "Connection",
215 "Content-Encoding",
216 "Content-Language",
217 "Content-Length",
218 "Content-Location",
219 "Content-MD5",
220 "Content-Range",
221 "Content-Type",
222 "Content-Version",
223 "Date",
224 "Host",
225 "If-Modified-Since",
226 "If-Unmodified-since",
227 "Keep-Alive",
228 "Last-Modified",
229 "Link",
230 "Location",
231 "Range",
232 "Referer",
233 "Retry-After",
234 "Transfer-Encoding",
235 "Upgrade",
236 "User-Agent",
237 "WWW-Authenticate",
238 "Accept-Encoding",
239 "Allow",
240 "Server"
241 };
242 #ifdef DEBUG
243 static const char * const http_states[] =
244 {
245 "HTTP_STATE_ERROR",
246 "HTTP_STATE_WAITING",
247 "HTTP_STATE_OPTIONS",
248 "HTTP_STATE_GET",
249 "HTTP_STATE_GET_SEND",
250 "HTTP_STATE_HEAD",
251 "HTTP_STATE_POST",
252 "HTTP_STATE_POST_RECV",
253 "HTTP_STATE_POST_SEND",
254 "HTTP_STATE_PUT",
255 "HTTP_STATE_PUT_RECV",
256 "HTTP_STATE_DELETE",
257 "HTTP_STATE_TRACE",
258 "HTTP_STATE_CONNECT",
259 "HTTP_STATE_STATUS",
260 "HTTP_STATE_UNKNOWN_METHOD",
261 "HTTP_STATE_UNKNOWN_VERSION"
262 };
263 #endif /* DEBUG */
264
265
266 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
267 /*
268 * BIO methods for OpenSSL...
269 */
270
271 static int http_bio_write(BIO *h, const char *buf, int num);
272 static int http_bio_read(BIO *h, char *buf, int size);
273 static int http_bio_puts(BIO *h, const char *str);
274 static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
275 static int http_bio_new(BIO *h);
276 static int http_bio_free(BIO *data);
277
278 static BIO_METHOD http_bio_methods =
279 {
280 BIO_TYPE_SOCKET,
281 "http",
282 http_bio_write,
283 http_bio_read,
284 http_bio_puts,
285 NULL, /* http_bio_gets, */
286 http_bio_ctrl,
287 http_bio_new,
288 http_bio_free,
289 NULL,
290 };
291 #endif /* HAVE_SSL && HAVE_LIBSSL */
292
293
294 /*
295 * 'httpAcceptConnection()' - Accept a new HTTP client connection from the
296 * specified listening socket.
297 *
298 * @since CUPS 1.7@
299 */
300
301 http_t * /* O - HTTP connection or @code NULL@ */
302 httpAcceptConnection(int fd, /* I - Listen socket file descriptor */
303 int blocking) /* I - 1 if the connection should be
304 blocking, 0 otherwise */
305 {
306 http_t *http; /* HTTP connection */
307 http_addrlist_t addrlist; /* Dummy address list */
308 socklen_t addrlen; /* Length of address */
309 int val; /* Socket option value */
310
311
312 /*
313 * Range check input...
314 */
315
316 if (fd < 0)
317 return (NULL);
318
319 /*
320 * Create the client connection...
321 */
322
323 memset(&addrlist, 0, sizeof(addrlist));
324
325 if ((http = http_create(NULL, 0, &addrlist, AF_UNSPEC,
326 HTTP_ENCRYPTION_IF_REQUESTED, blocking,
327 _HTTP_MODE_SERVER)) == NULL)
328 return (NULL);
329
330 /*
331 * Accept the client and get the remote address...
332 */
333
334 addrlen = sizeof(http_addr_t);
335
336 if ((http->fd = accept(fd, (struct sockaddr *)&(http->addrlist->addr),
337 &addrlen)) < 0)
338 {
339 _cupsSetHTTPError(HTTP_STATUS_ERROR);
340 httpClose(http);
341
342 return (NULL);
343 }
344
345 httpAddrString(&(http->addrlist->addr), http->hostname,
346 sizeof(http->hostname));
347
348 #ifdef SO_NOSIGPIPE
349 /*
350 * Disable SIGPIPE for this socket.
351 */
352
353 val = 1;
354 setsockopt(http->fd, SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val));
355 #endif /* SO_NOSIGPIPE */
356
357 /*
358 * Using TCP_NODELAY improves responsiveness, especially on systems
359 * with a slow loopback interface. Since we write large buffers
360 * when sending print files and requests, there shouldn't be any
361 * performance penalty for this...
362 */
363
364 val = 1;
365 setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, CUPS_SOCAST &val, sizeof(val));
366
367 #ifdef FD_CLOEXEC
368 /*
369 * Close this socket when starting another process...
370 */
371
372 fcntl(http->fd, F_SETFD, FD_CLOEXEC);
373 #endif /* FD_CLOEXEC */
374
375 return (http);
376 }
377
378
379 /*
380 * 'httpAddCredential()' - Allocates and adds a single credential to an array.
381 *
382 * Use @code cupsArrayNew(NULL, NULL)@ to create a credentials array.
383 *
384 * @since CUPS 1.5/OS X 10.7@
385 */
386
387 int /* O - 0 on success, -1 on error */
388 httpAddCredential(
389 cups_array_t *credentials, /* I - Credentials array */
390 const void *data, /* I - PEM-encoded X.509 data */
391 size_t datalen) /* I - Length of data */
392 {
393 http_credential_t *credential; /* Credential data */
394
395
396 if ((credential = malloc(sizeof(http_credential_t))) != NULL)
397 {
398 credential->datalen = datalen;
399
400 if ((credential->data = malloc(datalen)) != NULL)
401 {
402 memcpy(credential->data, data, datalen);
403 cupsArrayAdd(credentials, credential);
404 return (0);
405 }
406
407 free(credential);
408 }
409
410 return (-1);
411 }
412
413
414 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
415 /*
416 * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections.
417 */
418
419 BIO_METHOD * /* O - BIO methods for OpenSSL */
420 _httpBIOMethods(void)
421 {
422 return (&http_bio_methods);
423 }
424 #endif /* HAVE_SSL && HAVE_LIBSSL */
425
426
427 /*
428 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
429 */
430
431 void
432 httpBlocking(http_t *http, /* I - Connection to server */
433 int b) /* I - 1 = blocking, 0 = non-blocking */
434 {
435 if (http)
436 {
437 http->blocking = b;
438 http_set_wait(http);
439 }
440 }
441
442
443 /*
444 * 'httpCheck()' - Check to see if there is a pending response from the server.
445 */
446
447 int /* O - 0 = no data, 1 = data available */
448 httpCheck(http_t *http) /* I - Connection to server */
449 {
450 return (httpWait(http, 0));
451 }
452
453
454 /*
455 * 'httpClearCookie()' - Clear the cookie value(s).
456 *
457 * @since CUPS 1.1.19/OS X 10.3@
458 */
459
460 void
461 httpClearCookie(http_t *http) /* I - Connection to server */
462 {
463 if (!http)
464 return;
465
466 if (http->cookie)
467 {
468 free(http->cookie);
469 http->cookie = NULL;
470 }
471 }
472
473
474 /*
475 * 'httpClearFields()' - Clear HTTP request fields.
476 */
477
478 void
479 httpClearFields(http_t *http) /* I - Connection to server */
480 {
481 DEBUG_printf(("httpClearFields(http=%p)", http));
482
483 if (http)
484 {
485 memset(http->fields, 0, sizeof(http->fields));
486
487 if (http->mode == _HTTP_MODE_CLIENT)
488 {
489 if (http->hostname[0] == '/')
490 httpSetField(http, HTTP_FIELD_HOST, "localhost");
491 else
492 httpSetField(http, HTTP_FIELD_HOST, http->hostname);
493 }
494
495 if (http->field_authorization)
496 {
497 free(http->field_authorization);
498 http->field_authorization = NULL;
499 }
500
501 if (http->accept_encoding)
502 {
503 _cupsStrFree(http->accept_encoding);
504 http->accept_encoding = NULL;
505 }
506
507 if (http->allow)
508 {
509 _cupsStrFree(http->allow);
510 http->allow = NULL;
511 }
512
513 if (http->server)
514 {
515 _cupsStrFree(http->server);
516 http->server = NULL;
517 }
518
519 http->expect = (http_status_t)0;
520 }
521 }
522
523
524 /*
525 * 'httpClose()' - Close an HTTP connection.
526 */
527
528 void
529 httpClose(http_t *http) /* I - Connection to server */
530 {
531 #ifdef HAVE_GSSAPI
532 OM_uint32 minor_status; /* Minor status code */
533 #endif /* HAVE_GSSAPI */
534
535
536 DEBUG_printf(("httpClose(http=%p)", http));
537
538 /*
539 * Range check input...
540 */
541
542 if (!http)
543 return;
544
545 /*
546 * Close any open connection...
547 */
548
549 _httpDisconnect(http);
550
551 /*
552 * Free memory used...
553 */
554
555 httpAddrFreeList(http->addrlist);
556
557 if (http->cookie)
558 free(http->cookie);
559
560 #ifdef HAVE_GSSAPI
561 if (http->gssctx != GSS_C_NO_CONTEXT)
562 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
563
564 if (http->gssname != GSS_C_NO_NAME)
565 gss_release_name(&minor_status, &http->gssname);
566 #endif /* HAVE_GSSAPI */
567
568 #ifdef HAVE_AUTHORIZATION_H
569 if (http->auth_ref)
570 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
571 #endif /* HAVE_AUTHORIZATION_H */
572
573 httpClearFields(http);
574
575 if (http->authstring && http->authstring != http->_authstring)
576 free(http->authstring);
577
578 free(http);
579 }
580
581
582 /*
583 * 'httpConnect()' - Connect to a HTTP server.
584 *
585 * This function is deprecated - use @link httpConnect2@ instead.
586 *
587 * @deprecated@
588 */
589
590 http_t * /* O - New HTTP connection */
591 httpConnect(const char *host, /* I - Host to connect to */
592 int port) /* I - Port number */
593 {
594 return (httpConnect2(host, port, NULL, AF_UNSPEC, HTTP_ENCRYPT_IF_REQUESTED,
595 1, 30000, NULL));
596 }
597
598
599 /*
600 * 'httpConnect2()' - Connect to a HTTP server.
601 *
602 * @since CUPS 1.7@
603 */
604
605 http_t * /* O - New HTTP connection */
606 httpConnect2(
607 const char *host, /* I - Host to connect to */
608 int port, /* I - Port number */
609 http_addrlist_t *addrlist, /* I - List of addresses or NULL to lookup */
610 int family, /* I - Address family to use or @code AF_UNSPEC@ for any */
611 http_encryption_t encryption, /* I - Type of encryption to use */
612 int blocking, /* I - 1 for blocking connection, 0 for non-blocking */
613 int msec, /* I - Connection timeout in milliseconds, 0 means don't connect */
614 int *cancel) /* I - Pointer to "cancel" variable */
615 {
616 http_t *http; /* New HTTP connection */
617
618
619 DEBUG_printf(("httpConnect2(host=\"%s\", port=%d, addrlist=%p, family=%d, "
620 "encryption=%d, blocking=%d, msec=%d, cancel=%p)", host, port,
621 addrlist, family, encryption, blocking, msec, cancel));
622
623 /*
624 * Create the HTTP structure...
625 */
626
627 if ((http = http_create(host, port, addrlist, family, encryption, blocking,
628 _HTTP_MODE_CLIENT)) == NULL)
629 return (NULL);
630
631 /*
632 * Optionally connect to the remote system...
633 */
634
635 if (msec == 0 || !httpReconnect2(http, msec, cancel))
636 return (http);
637
638 /*
639 * Could not connect to any known address - bail out!
640 */
641
642 httpClose(http);
643
644 return (NULL);
645 }
646
647
648 /*
649 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
650 *
651 * This function is now deprecated. Please use the @link httpConnect2@ function
652 * instead.
653 *
654 * @deprecated@
655 */
656
657 http_t * /* O - New HTTP connection */
658 httpConnectEncrypt(
659 const char *host, /* I - Host to connect to */
660 int port, /* I - Port number */
661 http_encryption_t encryption) /* I - Type of encryption to use */
662 {
663 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)",
664 host, port, encryption));
665
666 return (httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 30000,
667 NULL));
668 }
669
670
671 /*
672 * 'httpCopyCredentials()' - Copy the credentials associated with an encrypted
673 * connection.
674 *
675 * @since CUPS 1.5/OS X 10.7@
676 */
677
678 int /* O - Status of call (0 = success) */
679 httpCopyCredentials(
680 http_t *http, /* I - Connection to server */
681 cups_array_t **credentials) /* O - Array of credentials */
682 {
683 # ifdef HAVE_LIBSSL
684 # elif defined(HAVE_GNUTLS)
685 # elif defined(HAVE_CDSASSL)
686 OSStatus error; /* Error code */
687 SecTrustRef peerTrust; /* Peer trust reference */
688 CFIndex count; /* Number of credentials */
689 SecCertificateRef secCert; /* Certificate reference */
690 CFDataRef data; /* Certificate data */
691 int i; /* Looping var */
692 # elif defined(HAVE_SSPISSL)
693 # endif /* HAVE_LIBSSL */
694
695
696 if (credentials)
697 *credentials = NULL;
698
699 if (!http || !http->tls || !credentials)
700 return (-1);
701
702 # ifdef HAVE_LIBSSL
703 return (-1);
704
705 # elif defined(HAVE_GNUTLS)
706 return (-1);
707
708 # elif defined(HAVE_CDSASSL)
709 if (!(error = SSLCopyPeerTrust(http->tls, &peerTrust)) && peerTrust)
710 {
711 if ((*credentials = cupsArrayNew(NULL, NULL)) != NULL)
712 {
713 count = SecTrustGetCertificateCount(peerTrust);
714
715 for (i = 0; i < count; i ++)
716 {
717 secCert = SecTrustGetCertificateAtIndex(peerTrust, i);
718 if ((data = SecCertificateCopyData(secCert)))
719 {
720 httpAddCredential(*credentials, CFDataGetBytePtr(data),
721 CFDataGetLength(data));
722 CFRelease(data);
723 }
724 }
725 }
726
727 CFRelease(peerTrust);
728 }
729
730 return (error);
731
732 # elif defined(HAVE_SSPISSL)
733 return (-1);
734
735 # else
736 return (-1);
737 # endif /* HAVE_LIBSSL */
738 }
739
740
741 /*
742 * '_httpCreateCredentials()' - Create credentials in the internal format.
743 */
744
745 http_tls_credentials_t /* O - Internal credentials */
746 _httpCreateCredentials(
747 cups_array_t *credentials) /* I - Array of credentials */
748 {
749 if (!credentials)
750 return (NULL);
751
752 # ifdef HAVE_LIBSSL
753 return (NULL);
754
755 # elif defined(HAVE_GNUTLS)
756 return (NULL);
757
758 # elif defined(HAVE_CDSASSL)
759 CFMutableArrayRef peerCerts; /* Peer credentials reference */
760 SecCertificateRef secCert; /* Certificate reference */
761 CFDataRef data; /* Credential data reference */
762 http_credential_t *credential; /* Credential data */
763
764
765 if ((peerCerts = CFArrayCreateMutable(kCFAllocatorDefault,
766 cupsArrayCount(credentials),
767 &kCFTypeArrayCallBacks)) == NULL)
768 return (NULL);
769
770 for (credential = (http_credential_t *)cupsArrayFirst(credentials);
771 credential;
772 credential = (http_credential_t *)cupsArrayNext(credentials))
773 {
774 if ((data = CFDataCreate(kCFAllocatorDefault, credential->data,
775 credential->datalen)))
776 {
777 if ((secCert = SecCertificateCreateWithData(kCFAllocatorDefault, data))
778 != NULL)
779 {
780 CFArrayAppendValue(peerCerts, secCert);
781 CFRelease(secCert);
782 }
783
784 CFRelease(data);
785 }
786 }
787
788 return (peerCerts);
789
790 # elif defined(HAVE_SSPISSL)
791 return (NULL);
792
793 # else
794 return (NULL);
795 # endif /* HAVE_LIBSSL */
796 }
797
798
799 /*
800 * 'httpDelete()' - Send a DELETE request to the server.
801 */
802
803 int /* O - Status of call (0 = success) */
804 httpDelete(http_t *http, /* I - Connection to server */
805 const char *uri) /* I - URI to delete */
806 {
807 return (http_send(http, HTTP_DELETE, uri));
808 }
809
810
811 /*
812 * '_httpDisconnect()' - Disconnect a HTTP connection.
813 */
814
815 void
816 _httpDisconnect(http_t *http) /* I - Connection to server */
817 {
818 #ifdef HAVE_SSL
819 if (http->tls)
820 http_shutdown_ssl(http);
821 #endif /* HAVE_SSL */
822
823 #ifdef WIN32
824 closesocket(http->fd);
825 #else
826 close(http->fd);
827 #endif /* WIN32 */
828
829 http->fd = -1;
830 }
831
832
833 /*
834 * 'httpEncryption()' - Set the required encryption on the link.
835 */
836
837 int /* O - -1 on error, 0 on success */
838 httpEncryption(http_t *http, /* I - Connection to server */
839 http_encryption_t e) /* I - New encryption preference */
840 {
841 DEBUG_printf(("httpEncryption(http=%p, e=%d)", http, e));
842
843 #ifdef HAVE_SSL
844 if (!http)
845 return (0);
846
847 http->encryption = e;
848
849 if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
850 (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
851 return (httpReconnect(http));
852 else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
853 return (http_upgrade(http));
854 else
855 return (0);
856 #else
857 if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
858 return (-1);
859 else
860 return (0);
861 #endif /* HAVE_SSL */
862 }
863
864
865 /*
866 * 'httpError()' - Get the last error on a connection.
867 */
868
869 int /* O - Error code (errno) value */
870 httpError(http_t *http) /* I - Connection to server */
871 {
872 if (http)
873 return (http->error);
874 else
875 return (EINVAL);
876 }
877
878
879 /*
880 * 'httpFlush()' - Flush data from a HTTP connection.
881 */
882
883 void
884 httpFlush(http_t *http) /* I - Connection to server */
885 {
886 char buffer[8192]; /* Junk buffer */
887 int blocking; /* To block or not to block */
888 http_state_t oldstate; /* Old state */
889
890
891 DEBUG_printf(("httpFlush(http=%p), state=%s", http,
892 http_states[http->state + 1]));
893
894 /*
895 * Nothing to do if we are in the "waiting" state...
896 */
897
898 if (http->state == HTTP_STATE_WAITING)
899 return;
900
901 /*
902 * Temporarily set non-blocking mode so we don't get stuck in httpRead()...
903 */
904
905 blocking = http->blocking;
906 http->blocking = 0;
907
908 /*
909 * Read any data we can...
910 */
911
912 oldstate = http->state;
913 while (httpRead2(http, buffer, sizeof(buffer)) > 0);
914
915 /*
916 * Restore blocking and reset the connection if we didn't get all of
917 * the remaining data...
918 */
919
920 http->blocking = blocking;
921
922 if (http->state == oldstate && http->state != HTTP_STATE_WAITING &&
923 http->fd >= 0)
924 {
925 /*
926 * Didn't get the data back, so close the current connection.
927 */
928
929 #ifdef HAVE_LIBZ
930 if (http->coding)
931 http_content_coding_finish(http);
932 #endif /* HAVE_LIBZ */
933
934 DEBUG_puts("1httpFlush: Setting state to HTTP_STATE_WAITING and closing.");
935
936 http->state = HTTP_STATE_WAITING;
937
938 #ifdef HAVE_SSL
939 if (http->tls)
940 http_shutdown_ssl(http);
941 #endif /* HAVE_SSL */
942
943 #ifdef WIN32
944 closesocket(http->fd);
945 #else
946 close(http->fd);
947 #endif /* WIN32 */
948
949 http->fd = -1;
950 }
951 }
952
953
954 /*
955 * 'httpFlushWrite()' - Flush data in write buffer.
956 *
957 * @since CUPS 1.2/OS X 10.5@
958 */
959
960 int /* O - Bytes written or -1 on error */
961 httpFlushWrite(http_t *http) /* I - Connection to server */
962 {
963 int bytes; /* Bytes written */
964
965
966 DEBUG_printf(("httpFlushWrite(http=%p) data_encoding=%d", http,
967 http ? http->data_encoding : -1));
968
969 if (!http || !http->wused)
970 {
971 DEBUG_puts(http ? "1httpFlushWrite: Write buffer is empty." :
972 "1httpFlushWrite: No connection.");
973 return (0);
974 }
975
976 if (http->data_encoding == HTTP_ENCODING_CHUNKED)
977 bytes = http_write_chunk(http, http->wbuffer, http->wused);
978 else
979 {
980 bytes = http_write(http, http->wbuffer, http->wused);
981
982 if (bytes > 0 && http->data_encoding == HTTP_ENCODING_LENGTH)
983 {
984 http->data_remaining -= bytes;
985
986 if (http->data_remaining <= 0)
987 {
988 }
989 }
990 }
991
992 http->wused = 0;
993
994 DEBUG_printf(("1httpFlushWrite: Returning %d, errno=%d.", bytes, errno));
995
996 return (bytes);
997 }
998
999
1000 /*
1001 * '_httpFreeCredentials()' - Free internal credentials.
1002 */
1003
1004 void
1005 _httpFreeCredentials(
1006 http_tls_credentials_t credentials) /* I - Internal credentials */
1007 {
1008 if (!credentials)
1009 return;
1010
1011 #ifdef HAVE_LIBSSL
1012 (void)credentials;
1013
1014 #elif defined(HAVE_GNUTLS)
1015 (void)credentials;
1016
1017 #elif defined(HAVE_CDSASSL)
1018 CFRelease(credentials);
1019
1020 #elif defined(HAVE_SSPISSL)
1021 (void)credentials;
1022
1023 #endif /* HAVE_LIBSSL */
1024 }
1025
1026
1027 /*
1028 * 'httpFreeCredentials()' - Free an array of credentials.
1029 */
1030
1031 void
1032 httpFreeCredentials(
1033 cups_array_t *credentials) /* I - Array of credentials */
1034 {
1035 http_credential_t *credential; /* Credential */
1036
1037
1038 for (credential = (http_credential_t *)cupsArrayFirst(credentials);
1039 credential;
1040 credential = (http_credential_t *)cupsArrayNext(credentials))
1041 {
1042 cupsArrayRemove(credentials, credential);
1043 free((void *)credential->data);
1044 free(credential);
1045 }
1046
1047 cupsArrayDelete(credentials);
1048 }
1049
1050
1051 /*
1052 * 'httpGet()' - Send a GET request to the server.
1053 */
1054
1055 int /* O - Status of call (0 = success) */
1056 httpGet(http_t *http, /* I - Connection to server */
1057 const char *uri) /* I - URI to get */
1058 {
1059 return (http_send(http, HTTP_GET, uri));
1060 }
1061
1062
1063 /*
1064 * 'httpGetContentEncoding()' - Get a common content encoding, if any, between
1065 * the client and server.
1066 *
1067 * This function uses the value of the Accepts-Encoding HTTP header and must be
1068 * called after receiving a response from the server or a request from the
1069 * client. The value returned can be use in subsequent requests (for clients)
1070 * or in the response (for servers) in order to compress the content stream.
1071 *
1072 * @since CUPS 1.7@
1073 */
1074
1075 const char * /* O - Content-Coding value or
1076 @code NULL@ for the identity
1077 coding. */
1078 httpGetContentEncoding(http_t *http) /* I - Connection to client/server */
1079 {
1080 #ifdef HAVE_LIBZ
1081 if (http && http->accept_encoding)
1082 {
1083 int i; /* Looping var */
1084 char temp[HTTP_MAX_VALUE], /* Copy of Accepts-Encoding value */
1085 *start, /* Start of coding value */
1086 *end; /* End of coding value */
1087 double qvalue; /* "qvalue" for coding */
1088 struct lconv *loc = localeconv(); /* Locale data */
1089 static const char * const codings[] =
1090 { /* Supported content codings */
1091 "deflate",
1092 "gzip",
1093 "x-deflate",
1094 "x-gzip"
1095 };
1096
1097 strlcpy(temp, http->accept_encoding, sizeof(temp));
1098
1099 for (start = temp; *start; start = end)
1100 {
1101 /*
1102 * Find the end of the coding name...
1103 */
1104
1105 qvalue = 1.0;
1106 end = start;
1107 while (*end && *end != ';' && *end != ',' && !isspace(*end & 255))
1108 end ++;
1109
1110 if (*end == ';')
1111 {
1112 /*
1113 * Grab the qvalue as needed...
1114 */
1115
1116 if (!strncmp(end, ";q=", 3))
1117 qvalue = _cupsStrScand(end + 3, NULL, loc);
1118
1119 /*
1120 * Skip past all attributes...
1121 */
1122
1123 *end++ = '\0';
1124 while (*end && *end != ',' && !isspace(*end & 255))
1125 end ++;
1126 }
1127 else if (*end)
1128 *end++ = '\0';
1129
1130 while (*end && isspace(*end & 255))
1131 end ++;
1132
1133 /*
1134 * Check value if it matches something we support...
1135 */
1136
1137 if (qvalue <= 0.0)
1138 continue;
1139
1140 for (i = 0; i < (int)(sizeof(codings) / sizeof(codings[0])); i ++)
1141 if (!strcmp(start, codings[i]))
1142 return (codings[i]);
1143 }
1144 }
1145 #endif /* HAVE_LIBZ */
1146
1147 return (NULL);
1148 }
1149
1150
1151 /*
1152 * 'httpGetAuthString()' - Get the current authorization string.
1153 *
1154 * The authorization string is set by cupsDoAuthentication() and
1155 * httpSetAuthString(). Use httpGetAuthString() to retrieve the
1156 * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION
1157 * value.
1158 *
1159 * @since CUPS 1.3/OS X 10.5@
1160 */
1161
1162 char * /* O - Authorization string */
1163 httpGetAuthString(http_t *http) /* I - Connection to server */
1164 {
1165 if (http)
1166 return (http->authstring);
1167 else
1168 return (NULL);
1169 }
1170
1171
1172 /*
1173 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection.
1174 *
1175 * @since CUPS 1.2/OS X 10.5@
1176 */
1177
1178 int /* O - 1 if blocking, 0 if non-blocking */
1179 httpGetBlocking(http_t *http) /* I - Connection to server */
1180 {
1181 return (http ? http->blocking : 0);
1182 }
1183
1184
1185 /*
1186 * 'httpGetCookie()' - Get any cookie data from the response.
1187 *
1188 * @since CUPS 1.1.19/OS X 10.3@
1189 */
1190
1191 const char * /* O - Cookie data or NULL */
1192 httpGetCookie(http_t *http) /* I - HTTP connecion */
1193 {
1194 return (http ? http->cookie : NULL);
1195 }
1196
1197
1198 /*
1199 * 'httpGetExpect()' - Get the value of the Expect header, if any.
1200 *
1201 * Returns @code HTTP_STATUS_NONE@ if there is no Expect header, otherwise
1202 * returns the expected HTTP status code, typically @code HTTP_STATUS_CONTINUE@.
1203 *
1204 * @since CUPS 1.7@
1205 */
1206
1207 http_status_t /* O - Expect: status, if any */
1208 httpGetExpect(http_t *http) /* I - Connection to client */
1209 {
1210 if (!http)
1211 return (HTTP_STATUS_ERROR);
1212 else
1213 return (http->expect);
1214 }
1215
1216
1217 /*
1218 * 'httpGetFd()' - Get the file descriptor associated with a connection.
1219 *
1220 * @since CUPS 1.2/OS X 10.5@
1221 */
1222
1223 int /* O - File descriptor or -1 if none */
1224 httpGetFd(http_t *http) /* I - Connection to server */
1225 {
1226 return (http ? http->fd : -1);
1227 }
1228
1229
1230 /*
1231 * 'httpGetField()' - Get a field value from a request/response.
1232 */
1233
1234 const char * /* O - Field value */
1235 httpGetField(http_t *http, /* I - Connection to server */
1236 http_field_t field) /* I - Field to get */
1237 {
1238 if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
1239 return (NULL);
1240
1241 switch (field)
1242 {
1243 case HTTP_FIELD_ACCEPT_ENCODING :
1244 return (http->accept_encoding);
1245
1246 case HTTP_FIELD_ALLOW :
1247 return (http->allow);
1248
1249 case HTTP_FIELD_SERVER :
1250 return (http->server);
1251
1252 case HTTP_FIELD_AUTHORIZATION :
1253 if (http->field_authorization)
1254 {
1255 /*
1256 * Special case for WWW-Authenticate: as its contents can be
1257 * longer than HTTP_MAX_VALUE...
1258 */
1259
1260 return (http->field_authorization);
1261 }
1262
1263 default :
1264 return (http->fields[field]);
1265 }
1266 }
1267
1268
1269 /*
1270 * 'httpGetLength()' - Get the amount of data remaining from the
1271 * content-length or transfer-encoding fields.
1272 *
1273 * This function is deprecated and will not return lengths larger than
1274 * 2^31 - 1; use httpGetLength2() instead.
1275 *
1276 * @deprecated@
1277 */
1278
1279 int /* O - Content length */
1280 httpGetLength(http_t *http) /* I - Connection to server */
1281 {
1282 /*
1283 * Get the read content length and return the 32-bit value.
1284 */
1285
1286 if (http)
1287 {
1288 httpGetLength2(http);
1289
1290 return (http->_data_remaining);
1291 }
1292 else
1293 return (-1);
1294 }
1295
1296
1297 /*
1298 * 'httpGetLength2()' - Get the amount of data remaining from the
1299 * content-length or transfer-encoding fields.
1300 *
1301 * This function returns the complete content length, even for
1302 * content larger than 2^31 - 1.
1303 *
1304 * @since CUPS 1.2/OS X 10.5@
1305 */
1306
1307 off_t /* O - Content length */
1308 httpGetLength2(http_t *http) /* I - Connection to server */
1309 {
1310 off_t remaining; /* Remaining length */
1311
1312
1313 DEBUG_printf(("2httpGetLength2(http=%p), state=%s", http,
1314 http_states[http->state + 1]));
1315
1316 if (!http)
1317 return (-1);
1318
1319 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"))
1320 {
1321 DEBUG_puts("4httpGetLength2: chunked request!");
1322 remaining = 0;
1323 }
1324 else
1325 {
1326 /*
1327 * The following is a hack for HTTP servers that don't send a
1328 * Content-Length or Transfer-Encoding field...
1329 *
1330 * If there is no Content-Length then the connection must close
1331 * after the transfer is complete...
1332 */
1333
1334 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0])
1335 {
1336 /*
1337 * Default content length is 0 for errors and certain types of operations,
1338 * and 2^31-1 for other successful requests...
1339 */
1340
1341 if (http->status >= HTTP_MULTIPLE_CHOICES ||
1342 http->state == HTTP_STATE_OPTIONS ||
1343 (http->state == HTTP_STATE_GET && http->mode == _HTTP_MODE_SERVER) ||
1344 http->state == HTTP_STATE_HEAD ||
1345 (http->state == HTTP_STATE_PUT && http->mode == _HTTP_MODE_CLIENT) ||
1346 http->state == HTTP_STATE_DELETE ||
1347 http->state == HTTP_STATE_TRACE ||
1348 http->state == HTTP_STATE_CONNECT)
1349 remaining = 0;
1350 else
1351 remaining = 2147483647;
1352 }
1353 else if ((remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH],
1354 NULL, 10)) < 0)
1355 remaining = -1;
1356
1357 DEBUG_printf(("4httpGetLength2: content_length=" CUPS_LLFMT,
1358 CUPS_LLCAST remaining));
1359 }
1360
1361 return (remaining);
1362 }
1363
1364
1365 /*
1366 * 'httpGets()' - Get a line of text from a HTTP connection.
1367 */
1368
1369 char * /* O - Line or NULL */
1370 httpGets(char *line, /* I - Line to read into */
1371 int length, /* I - Max length of buffer */
1372 http_t *http) /* I - Connection to server */
1373 {
1374 char *lineptr, /* Pointer into line */
1375 *lineend, /* End of line */
1376 *bufptr, /* Pointer into input buffer */
1377 *bufend; /* Pointer to end of buffer */
1378 int bytes, /* Number of bytes read */
1379 eol; /* End-of-line? */
1380
1381
1382 DEBUG_printf(("2httpGets(line=%p, length=%d, http=%p)", line, length, http));
1383
1384 if (!http || !line || length <= 1)
1385 return (NULL);
1386
1387 /*
1388 * Read a line from the buffer...
1389 */
1390
1391 http->error = 0;
1392 lineptr = line;
1393 lineend = line + length - 1;
1394 eol = 0;
1395
1396 while (lineptr < lineend)
1397 {
1398 /*
1399 * Pre-load the buffer as needed...
1400 */
1401
1402 #ifdef WIN32
1403 WSASetLastError(0);
1404 #else
1405 errno = 0;
1406 #endif /* WIN32 */
1407
1408 while (http->used == 0)
1409 {
1410 /*
1411 * No newline; see if there is more data to be read...
1412 */
1413
1414 while (!_httpWait(http, http->wait_value, 1))
1415 {
1416 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1417 continue;
1418
1419 DEBUG_puts("3httpGets: Timed out!");
1420 #ifdef WIN32
1421 http->error = WSAETIMEDOUT;
1422 #else
1423 http->error = ETIMEDOUT;
1424 #endif /* WIN32 */
1425 return (NULL);
1426 }
1427
1428 bytes = http_read(http, http->buffer + http->used,
1429 HTTP_MAX_BUFFER - http->used);
1430
1431 DEBUG_printf(("4httpGets: read %d bytes.", bytes));
1432
1433 if (bytes < 0)
1434 {
1435 /*
1436 * Nope, can't get a line this time...
1437 */
1438
1439 #ifdef WIN32
1440 DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError()));
1441
1442 if (WSAGetLastError() == WSAEINTR)
1443 continue;
1444 else if (WSAGetLastError() == WSAEWOULDBLOCK)
1445 {
1446 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1447 continue;
1448
1449 http->error = WSAGetLastError();
1450 }
1451 else if (WSAGetLastError() != http->error)
1452 {
1453 http->error = WSAGetLastError();
1454 continue;
1455 }
1456
1457 #else
1458 DEBUG_printf(("3httpGets: recv() error %d!", errno));
1459
1460 if (errno == EINTR)
1461 continue;
1462 else if (errno == EWOULDBLOCK || errno == EAGAIN)
1463 {
1464 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1465 continue;
1466 else if (!http->timeout_cb && errno == EAGAIN)
1467 continue;
1468
1469 http->error = errno;
1470 }
1471 else if (errno != http->error)
1472 {
1473 http->error = errno;
1474 continue;
1475 }
1476 #endif /* WIN32 */
1477
1478 return (NULL);
1479 }
1480 else if (bytes == 0)
1481 {
1482 http->error = EPIPE;
1483
1484 return (NULL);
1485 }
1486
1487 /*
1488 * Yup, update the amount used...
1489 */
1490
1491 http->used += bytes;
1492 }
1493
1494 /*
1495 * Now copy as much of the current line as possible...
1496 */
1497
1498 for (bufptr = http->buffer, bufend = http->buffer + http->used;
1499 lineptr < lineend && bufptr < bufend;)
1500 {
1501 if (*bufptr == 0x0a)
1502 {
1503 eol = 1;
1504 bufptr ++;
1505 break;
1506 }
1507 else if (*bufptr == 0x0d)
1508 bufptr ++;
1509 else
1510 *lineptr++ = *bufptr++;
1511 }
1512
1513 http->used -= (int)(bufptr - http->buffer);
1514 if (http->used > 0)
1515 memmove(http->buffer, bufptr, http->used);
1516
1517 if (eol)
1518 {
1519 /*
1520 * End of line...
1521 */
1522
1523 http->activity = time(NULL);
1524
1525 *lineptr = '\0';
1526
1527 DEBUG_printf(("3httpGets: Returning \"%s\"", line));
1528
1529 return (line);
1530 }
1531 }
1532
1533 DEBUG_puts("3httpGets: No new line available!");
1534
1535 return (NULL);
1536 }
1537
1538
1539 /*
1540 * 'httpGetState()' - Get the current state of the HTTP request.
1541 */
1542
1543 http_state_t /* O - HTTP state */
1544 httpGetState(http_t *http) /* I - Connection to server */
1545 {
1546 return (http ? http->state : HTTP_STATE_ERROR);
1547 }
1548
1549
1550 /*
1551 * 'httpGetStatus()' - Get the status of the last HTTP request.
1552 *
1553 * @since CUPS 1.2/OS X 10.5@
1554 */
1555
1556 http_status_t /* O - HTTP status */
1557 httpGetStatus(http_t *http) /* I - Connection to server */
1558 {
1559 return (http ? http->status : HTTP_ERROR);
1560 }
1561
1562
1563 /*
1564 * 'httpGetSubField()' - Get a sub-field value.
1565 *
1566 * @deprecated@
1567 */
1568
1569 char * /* O - Value or NULL */
1570 httpGetSubField(http_t *http, /* I - Connection to server */
1571 http_field_t field, /* I - Field index */
1572 const char *name, /* I - Name of sub-field */
1573 char *value) /* O - Value string */
1574 {
1575 return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE));
1576 }
1577
1578
1579 /*
1580 * 'httpGetSubField2()' - Get a sub-field value.
1581 *
1582 * @since CUPS 1.2/OS X 10.5@
1583 */
1584
1585 char * /* O - Value or NULL */
1586 httpGetSubField2(http_t *http, /* I - Connection to server */
1587 http_field_t field, /* I - Field index */
1588 const char *name, /* I - Name of sub-field */
1589 char *value, /* O - Value string */
1590 int valuelen) /* I - Size of value buffer */
1591 {
1592 const char *fptr; /* Pointer into field */
1593 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
1594 *ptr, /* Pointer into string buffer */
1595 *end; /* End of value buffer */
1596
1597 DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, "
1598 "valuelen=%d)", http, field, name, value, valuelen));
1599
1600 if (!http || !name || !value || valuelen < 2 ||
1601 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
1602 return (NULL);
1603
1604 end = value + valuelen - 1;
1605
1606 for (fptr = http->fields[field]; *fptr;)
1607 {
1608 /*
1609 * Skip leading whitespace...
1610 */
1611
1612 while (_cups_isspace(*fptr))
1613 fptr ++;
1614
1615 if (*fptr == ',')
1616 {
1617 fptr ++;
1618 continue;
1619 }
1620
1621 /*
1622 * Get the sub-field name...
1623 */
1624
1625 for (ptr = temp;
1626 *fptr && *fptr != '=' && !_cups_isspace(*fptr) &&
1627 ptr < (temp + sizeof(temp) - 1);
1628 *ptr++ = *fptr++);
1629
1630 *ptr = '\0';
1631
1632 DEBUG_printf(("4httpGetSubField2: name=\"%s\"", temp));
1633
1634 /*
1635 * Skip trailing chars up to the '='...
1636 */
1637
1638 while (_cups_isspace(*fptr))
1639 fptr ++;
1640
1641 if (!*fptr)
1642 break;
1643
1644 if (*fptr != '=')
1645 continue;
1646
1647 /*
1648 * Skip = and leading whitespace...
1649 */
1650
1651 fptr ++;
1652
1653 while (_cups_isspace(*fptr))
1654 fptr ++;
1655
1656 if (*fptr == '\"')
1657 {
1658 /*
1659 * Read quoted string...
1660 */
1661
1662 for (ptr = value, fptr ++;
1663 *fptr && *fptr != '\"' && ptr < end;
1664 *ptr++ = *fptr++);
1665
1666 *ptr = '\0';
1667
1668 while (*fptr && *fptr != '\"')
1669 fptr ++;
1670
1671 if (*fptr)
1672 fptr ++;
1673 }
1674 else
1675 {
1676 /*
1677 * Read unquoted string...
1678 */
1679
1680 for (ptr = value;
1681 *fptr && !_cups_isspace(*fptr) && *fptr != ',' && ptr < end;
1682 *ptr++ = *fptr++);
1683
1684 *ptr = '\0';
1685
1686 while (*fptr && !_cups_isspace(*fptr) && *fptr != ',')
1687 fptr ++;
1688 }
1689
1690 DEBUG_printf(("4httpGetSubField2: value=\"%s\"", value));
1691
1692 /*
1693 * See if this is the one...
1694 */
1695
1696 if (!strcmp(name, temp))
1697 {
1698 DEBUG_printf(("3httpGetSubField2: Returning \"%s\"", value));
1699 return (value);
1700 }
1701 }
1702
1703 value[0] = '\0';
1704
1705 DEBUG_puts("3httpGetSubField2: Returning NULL");
1706
1707 return (NULL);
1708 }
1709
1710
1711 /*
1712 * 'httpGetVersion()' - Get the HTTP version at the other end.
1713 */
1714
1715 http_version_t /* O - Version number */
1716 httpGetVersion(http_t *http) /* I - Connection to server */
1717 {
1718 return (http ? http->version : HTTP_VERSION_1_0);
1719 }
1720
1721
1722 /*
1723 * 'httpHead()' - Send a HEAD request to the server.
1724 */
1725
1726 int /* O - Status of call (0 = success) */
1727 httpHead(http_t *http, /* I - Connection to server */
1728 const char *uri) /* I - URI for head */
1729 {
1730 DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", http, uri));
1731 return (http_send(http, HTTP_HEAD, uri));
1732 }
1733
1734
1735 /*
1736 * 'httpInitialize()' - Initialize the HTTP interface library and set the
1737 * default HTTP proxy (if any).
1738 */
1739
1740 void
1741 httpInitialize(void)
1742 {
1743 static int initialized = 0; /* Have we been called before? */
1744 #ifdef WIN32
1745 WSADATA winsockdata; /* WinSock data */
1746 #endif /* WIN32 */
1747 #ifdef HAVE_LIBSSL
1748 int i; /* Looping var */
1749 unsigned char data[1024]; /* Seed data */
1750 #endif /* HAVE_LIBSSL */
1751
1752
1753 _cupsGlobalLock();
1754 if (initialized)
1755 {
1756 _cupsGlobalUnlock();
1757 return;
1758 }
1759
1760 #ifdef WIN32
1761 WSAStartup(MAKEWORD(2,2), &winsockdata);
1762
1763 #elif !defined(SO_NOSIGPIPE)
1764 /*
1765 * Ignore SIGPIPE signals...
1766 */
1767
1768 # ifdef HAVE_SIGSET
1769 sigset(SIGPIPE, SIG_IGN);
1770
1771 # elif defined(HAVE_SIGACTION)
1772 struct sigaction action; /* POSIX sigaction data */
1773
1774
1775 memset(&action, 0, sizeof(action));
1776 action.sa_handler = SIG_IGN;
1777 sigaction(SIGPIPE, &action, NULL);
1778
1779 # else
1780 signal(SIGPIPE, SIG_IGN);
1781 # endif /* !SO_NOSIGPIPE */
1782 #endif /* WIN32 */
1783
1784 #ifdef HAVE_GNUTLS
1785 /*
1786 * Initialize GNU TLS...
1787 */
1788
1789 gnutls_global_init();
1790
1791 #elif defined(HAVE_LIBSSL)
1792 /*
1793 * Initialize OpenSSL...
1794 */
1795
1796 SSL_load_error_strings();
1797 SSL_library_init();
1798
1799 /*
1800 * Using the current time is a dubious random seed, but on some systems
1801 * it is the best we can do (on others, this seed isn't even used...)
1802 */
1803
1804 CUPS_SRAND(time(NULL));
1805
1806 for (i = 0; i < sizeof(data); i ++)
1807 data[i] = CUPS_RAND();
1808
1809 RAND_seed(data, sizeof(data));
1810 #endif /* HAVE_GNUTLS */
1811
1812 initialized = 1;
1813 _cupsGlobalUnlock();
1814 }
1815
1816
1817 /*
1818 * 'httpOptions()' - Send an OPTIONS request to the server.
1819 */
1820
1821 int /* O - Status of call (0 = success) */
1822 httpOptions(http_t *http, /* I - Connection to server */
1823 const char *uri) /* I - URI for options */
1824 {
1825 return (http_send(http, HTTP_OPTIONS, uri));
1826 }
1827
1828
1829 /*
1830 * 'httpPeek()' - Peek at data from a HTTP connection.
1831 *
1832 * This function copies available data from the given HTTP connection, reading
1833 * a buffer as needed. The data is still available for reading using
1834 * @link httpRead@ or @link httpRead2@.
1835 *
1836 * For non-blocking connections the usual timeouts apply.
1837 *
1838 * @since CUPS 1.7@
1839 */
1840
1841 ssize_t /* O - Number of bytes copied */
1842 httpPeek(http_t *http, /* I - Connection to server */
1843 char *buffer, /* I - Buffer for data */
1844 size_t length) /* I - Maximum number of bytes */
1845 {
1846 ssize_t bytes; /* Bytes read */
1847 char len[32]; /* Length string */
1848
1849
1850 DEBUG_printf(("httpPeek(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
1851 http, buffer, CUPS_LLCAST length));
1852
1853 if (http == NULL || buffer == NULL)
1854 return (-1);
1855
1856 http->activity = time(NULL);
1857 http->error = 0;
1858
1859 if (length <= 0)
1860 return (0);
1861
1862 if (http->data_encoding == HTTP_ENCODING_CHUNKED &&
1863 http->data_remaining <= 0)
1864 {
1865 DEBUG_puts("2httpPeek: Getting chunk length...");
1866
1867 if (httpGets(len, sizeof(len), http) == NULL)
1868 {
1869 DEBUG_puts("1httpPeek: Could not get length!");
1870 return (0);
1871 }
1872
1873 if (!len[0])
1874 {
1875 DEBUG_puts("1httpPeek: Blank chunk length, trying again...");
1876 if (!httpGets(len, sizeof(len), http))
1877 {
1878 DEBUG_puts("1httpPeek: Could not get chunk length.");
1879 return (0);
1880 }
1881 }
1882
1883 http->data_remaining = strtoll(len, NULL, 16);
1884
1885 if (http->data_remaining < 0)
1886 {
1887 DEBUG_puts("1httpPeek: Negative chunk length!");
1888 return (0);
1889 }
1890 }
1891
1892 DEBUG_printf(("2httpPeek: data_remaining=" CUPS_LLFMT,
1893 CUPS_LLCAST http->data_remaining));
1894
1895 if (http->data_remaining <= 0 && http->data_encoding != HTTP_ENCODING_FIELDS)
1896 {
1897 /*
1898 * A zero-length chunk ends a transfer; unless we are reading POST
1899 * data, go idle...
1900 */
1901
1902 #ifdef HAVE_LIBZ
1903 if (http->coding)
1904 http_content_coding_finish(http);
1905 #endif /* HAVE_LIBZ */
1906
1907 if (http->data_encoding == HTTP_ENCODING_CHUNKED)
1908 httpGets(len, sizeof(len), http);
1909
1910 if (http->state == HTTP_STATE_POST_RECV)
1911 http->state ++;
1912 else
1913 http->state = HTTP_STATE_WAITING;
1914
1915 DEBUG_printf(("1httpPeek: 0-length chunk, set state to %s.",
1916 http_states[http->state + 1]));
1917
1918 /*
1919 * Prevent future reads for this request...
1920 */
1921
1922 http->data_encoding = HTTP_ENCODING_FIELDS;
1923
1924 return (0);
1925 }
1926 else if (length > (size_t)http->data_remaining)
1927 length = (size_t)http->data_remaining;
1928
1929 #ifdef HAVE_LIBZ
1930 if (http->used == 0 &&
1931 (http->coding == _HTTP_CODING_IDENTITY || http->stream.avail_in == 0))
1932 #else
1933 if (http->used == 0)
1934 #endif /* HAVE_LIBZ */
1935 {
1936 /*
1937 * Buffer small reads for better performance...
1938 */
1939
1940 ssize_t buflen; /* Length of read for buffer */
1941
1942 if (!http->blocking)
1943 {
1944 while (!httpWait(http, http->wait_value))
1945 {
1946 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1947 continue;
1948
1949 return (0);
1950 }
1951 }
1952
1953 if (http->data_remaining > sizeof(http->buffer))
1954 buflen = sizeof(http->buffer);
1955 else
1956 buflen = http->data_remaining;
1957
1958 DEBUG_printf(("2httpPeek: Reading %d bytes into buffer.", (int)buflen));
1959 bytes = http_read(http, http->buffer, buflen);
1960
1961 DEBUG_printf(("2httpPeek: Read " CUPS_LLFMT " bytes into buffer.",
1962 CUPS_LLCAST bytes));
1963 if (bytes > 0)
1964 {
1965 #ifdef DEBUG
1966 http_debug_hex("httpPeek", http->buffer, (int)bytes);
1967 #endif /* DEBUG */
1968
1969 http->used = bytes;
1970 }
1971 }
1972
1973 #ifdef HAVE_LIBZ
1974 if (http->coding)
1975 {
1976 # ifdef HAVE_INFLATECOPY
1977 int zerr; /* Decompressor error */
1978 z_stream stream; /* Copy of decompressor stream */
1979
1980 if (http->used > 0 && http->stream.avail_in < HTTP_MAX_BUFFER)
1981 {
1982 size_t buflen = buflen = HTTP_MAX_BUFFER - http->stream.avail_in;
1983 /* Number of bytes to copy */
1984
1985 if (http->stream.avail_in > 0 &&
1986 http->stream.next_in > http->dbuffer)
1987 memmove(http->dbuffer, http->stream.next_in, http->stream.avail_in);
1988
1989 http->stream.next_in = http->dbuffer;
1990
1991 if (buflen > http->data_remaining)
1992 buflen = http->data_remaining;
1993
1994 if (buflen > http->used)
1995 buflen = http->used;
1996
1997 DEBUG_printf(("1httpPeek: Copying %d more bytes of data into "
1998 "decompression buffer.", (int)buflen));
1999
2000 memcpy(http->dbuffer + http->stream.avail_in, http->buffer, buflen);
2001 http->stream.avail_in += buflen;
2002 http->used -= buflen;
2003 http->data_remaining -= buflen;
2004
2005 if (http->used > 0)
2006 memmove(http->buffer, http->buffer + buflen, http->used);
2007 }
2008
2009 DEBUG_printf(("2httpPeek: length=%d, avail_in=%d", (int)length,
2010 (int)http->stream.avail_in));
2011
2012 if (inflateCopy(&stream, &(http->stream)) != Z_OK)
2013 {
2014 DEBUG_puts("2httpPeek: Unable to copy decompressor stream.");
2015 http->error = ENOMEM;
2016 return (-1);
2017 }
2018
2019 stream.next_out = (Bytef *)buffer;
2020 stream.avail_out = length;
2021
2022 zerr = inflate(&stream, Z_SYNC_FLUSH);
2023 inflateEnd(&stream);
2024
2025 if (zerr < Z_OK)
2026 {
2027 DEBUG_printf(("2httpPeek: zerr=%d", zerr));
2028 #ifdef DEBUG
2029 http_debug_hex("2httpPeek", (char *)http->dbuffer,
2030 http->stream.avail_in);
2031 #endif /* DEBUG */
2032
2033 http->error = EIO;
2034 return (-1);
2035 }
2036
2037 bytes = length - http->stream.avail_out;
2038
2039 # else
2040 DEBUG_puts("2httpPeek: No inflateCopy on this platform, httpPeek does not "
2041 "work with compressed streams.");
2042 return (-1);
2043 # endif /* HAVE_INFLATECOPY */
2044 }
2045 else
2046 #endif /* HAVE_LIBZ */
2047 if (http->used > 0)
2048 {
2049 if (length > (size_t)http->used)
2050 length = (size_t)http->used;
2051
2052 bytes = (ssize_t)length;
2053
2054 DEBUG_printf(("2httpPeek: grabbing %d bytes from input buffer...",
2055 (int)bytes));
2056
2057 memcpy(buffer, http->buffer, length);
2058 }
2059 else
2060 bytes = 0;
2061
2062 if (bytes < 0)
2063 {
2064 #ifdef WIN32
2065 if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)
2066 bytes = 0;
2067 else
2068 http->error = WSAGetLastError();
2069 #else
2070 if (errno == EINTR || errno == EAGAIN)
2071 bytes = 0;
2072 else
2073 http->error = errno;
2074 #endif /* WIN32 */
2075 }
2076 else if (bytes == 0)
2077 {
2078 http->error = EPIPE;
2079 return (0);
2080 }
2081
2082 return (bytes);
2083 }
2084
2085 /* For OS X 10.8 and earlier */
2086 ssize_t _httpPeek(http_t *http, char *buffer, size_t length)
2087 { return (httpPeek(http, buffer, length)); }
2088
2089
2090 /*
2091 * 'httpPost()' - Send a POST request to the server.
2092 */
2093
2094 int /* O - Status of call (0 = success) */
2095 httpPost(http_t *http, /* I - Connection to server */
2096 const char *uri) /* I - URI for post */
2097 {
2098 return (http_send(http, HTTP_POST, uri));
2099 }
2100
2101
2102 /*
2103 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
2104 *
2105 * @private@
2106 */
2107
2108 int /* O - Number of bytes written */
2109 httpPrintf(http_t *http, /* I - Connection to server */
2110 const char *format, /* I - printf-style format string */
2111 ...) /* I - Additional args as needed */
2112 {
2113 int bytes; /* Number of bytes to write */
2114 char buf[16384]; /* Buffer for formatted string */
2115 va_list ap; /* Variable argument pointer */
2116
2117
2118 DEBUG_printf(("2httpPrintf(http=%p, format=\"%s\", ...)", http, format));
2119
2120 va_start(ap, format);
2121 bytes = vsnprintf(buf, sizeof(buf), format, ap);
2122 va_end(ap);
2123
2124 DEBUG_printf(("3httpPrintf: (%d bytes) %s", bytes, buf));
2125
2126 if (http->data_encoding == HTTP_ENCODING_FIELDS)
2127 return (httpWrite2(http, buf, bytes));
2128 else
2129 {
2130 if (http->wused)
2131 {
2132 DEBUG_puts("4httpPrintf: flushing existing data...");
2133
2134 if (httpFlushWrite(http) < 0)
2135 return (-1);
2136 }
2137
2138 return (http_write(http, buf, bytes));
2139 }
2140 }
2141
2142
2143 /*
2144 * 'httpPut()' - Send a PUT request to the server.
2145 */
2146
2147 int /* O - Status of call (0 = success) */
2148 httpPut(http_t *http, /* I - Connection to server */
2149 const char *uri) /* I - URI to put */
2150 {
2151 DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", http, uri));
2152 return (http_send(http, HTTP_PUT, uri));
2153 }
2154
2155
2156 /*
2157 * 'httpRead()' - Read data from a HTTP connection.
2158 *
2159 * This function is deprecated. Use the httpRead2() function which can
2160 * read more than 2GB of data.
2161 *
2162 * @deprecated@
2163 */
2164
2165 int /* O - Number of bytes read */
2166 httpRead(http_t *http, /* I - Connection to server */
2167 char *buffer, /* I - Buffer for data */
2168 int length) /* I - Maximum number of bytes */
2169 {
2170 return ((int)httpRead2(http, buffer, length));
2171 }
2172
2173
2174 /*
2175 * 'httpRead2()' - Read data from a HTTP connection.
2176 *
2177 * @since CUPS 1.2/OS X 10.5@
2178 */
2179
2180 ssize_t /* O - Number of bytes read */
2181 httpRead2(http_t *http, /* I - Connection to server */
2182 char *buffer, /* I - Buffer for data */
2183 size_t length) /* I - Maximum number of bytes */
2184 {
2185 ssize_t bytes; /* Bytes read */
2186
2187
2188 #ifdef HAVE_LIBZ
2189 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT
2190 ") coding=%d data_encoding=%d data_remaining=" CUPS_LLFMT,
2191 http, buffer, CUPS_LLCAST length,
2192 http->coding,
2193 http->data_encoding, CUPS_LLCAST http->data_remaining));
2194 #else
2195 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT
2196 ") data_encoding=%d data_remaining=" CUPS_LLFMT,
2197 http, buffer, CUPS_LLCAST length,
2198 http->data_encoding, CUPS_LLCAST http->data_remaining));
2199 #endif /* HAVE_LIBZ */
2200
2201 if (http == NULL || buffer == NULL)
2202 return (-1);
2203
2204 http->activity = time(NULL);
2205 http->error = 0;
2206
2207 if (length <= 0)
2208 return (0);
2209
2210 #ifdef HAVE_LIBZ
2211 if (http->coding)
2212 {
2213 do
2214 {
2215 if (http->stream.avail_in > 0)
2216 {
2217 int zerr; /* Decompressor error */
2218
2219 DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d",
2220 (int)http->stream.avail_in, (int)length));
2221
2222 http->stream.next_out = (Bytef *)buffer;
2223 http->stream.avail_out = length;
2224
2225 if ((zerr = inflate(&(http->stream), Z_SYNC_FLUSH)) < Z_OK)
2226 {
2227 DEBUG_printf(("2httpRead2: zerr=%d", zerr));
2228 #ifdef DEBUG
2229 http_debug_hex("2httpRead2", (char *)http->dbuffer,
2230 http->stream.avail_in);
2231 #endif /* DEBUG */
2232
2233 http->error = EIO;
2234 return (-1);
2235 }
2236
2237 bytes = length - http->stream.avail_out;
2238
2239 DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d, bytes=%d",
2240 http->stream.avail_in, http->stream.avail_out,
2241 (int)bytes));
2242 }
2243 else
2244 bytes = 0;
2245
2246 if (bytes == 0)
2247 {
2248 ssize_t buflen = HTTP_MAX_BUFFER - http->stream.avail_in;
2249 /* Additional bytes for buffer */
2250
2251 if (buflen > 0)
2252 {
2253 if (http->stream.avail_in > 0 &&
2254 http->stream.next_in > http->dbuffer)
2255 memmove(http->dbuffer, http->stream.next_in, http->stream.avail_in);
2256
2257 http->stream.next_in = http->dbuffer;
2258
2259 DEBUG_printf(("1httpRead2: Reading up to %d more bytes of data into "
2260 "decompression buffer.", (int)buflen));
2261
2262 if (http->data_remaining > 0)
2263 {
2264 if (buflen > http->data_remaining)
2265 buflen = http->data_remaining;
2266
2267 bytes = http_read_buffered(http,
2268 (char *)http->dbuffer +
2269 http->stream.avail_in, buflen);
2270 }
2271 else if (http->data_encoding == HTTP_ENCODING_CHUNKED)
2272 bytes = http_read_chunk(http,
2273 (char *)http->dbuffer +
2274 http->stream.avail_in, buflen);
2275 else
2276 bytes = 0;
2277
2278 if (bytes < 0)
2279 return (bytes);
2280 else if (bytes == 0)
2281 break;
2282
2283 DEBUG_printf(("1httpRead2: Adding " CUPS_LLFMT " bytes to "
2284 "decompression buffer.", CUPS_LLCAST bytes));
2285
2286 http->data_remaining -= bytes;
2287 http->stream.avail_in += bytes;
2288
2289 bytes = 0;
2290 }
2291 else
2292 return (0);
2293 }
2294 }
2295 while (bytes == 0);
2296 }
2297 else
2298 #endif /* HAVE_LIBZ */
2299 if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODING_CHUNKED)
2300 {
2301 if ((bytes = http_read_chunk(http, buffer, length)) > 0)
2302 http->data_remaining -= bytes;
2303 }
2304 else if (http->data_remaining <= 0)
2305 {
2306 /*
2307 * No more data to read...
2308 */
2309
2310 return (0);
2311 }
2312 else
2313 {
2314 DEBUG_printf(("1httpRead2: Reading up to %d bytes into buffer.",
2315 (int)length));
2316
2317 if (length > (size_t)http->data_remaining)
2318 length = (size_t)http->data_remaining;
2319
2320 if ((bytes = http_read_buffered(http, buffer, length)) > 0)
2321 http->data_remaining -= bytes;
2322 }
2323
2324 if (
2325 #ifdef HAVE_LIBZ
2326 (http->coding == _HTTP_CODING_IDENTITY || http->stream.avail_in == 0) &&
2327 #endif /* HAVE_LIBZ */
2328 ((http->data_remaining <= 0 &&
2329 http->data_encoding == HTTP_ENCODING_LENGTH) ||
2330 (http->data_encoding == HTTP_ENCODING_CHUNKED && bytes == 0)))
2331 {
2332 #ifdef HAVE_LIBZ
2333 if (http->coding)
2334 http_content_coding_finish(http);
2335 #endif /* HAVE_LIBZ */
2336
2337 if (http->state == HTTP_STATE_POST_RECV)
2338 http->state ++;
2339 else
2340 http->state = HTTP_STATE_WAITING;
2341
2342 DEBUG_printf(("1httpRead2: End of content, set state to %s.",
2343 http_states[http->state + 1]));
2344 }
2345
2346 return (bytes);
2347 }
2348
2349
2350 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2351 /*
2352 * '_httpReadCDSA()' - Read function for the CDSA library.
2353 */
2354
2355 OSStatus /* O - -1 on error, 0 on success */
2356 _httpReadCDSA(
2357 SSLConnectionRef connection, /* I - SSL/TLS connection */
2358 void *data, /* I - Data buffer */
2359 size_t *dataLength) /* IO - Number of bytes */
2360 {
2361 OSStatus result; /* Return value */
2362 ssize_t bytes; /* Number of bytes read */
2363 http_t *http; /* HTTP connection */
2364
2365
2366 http = (http_t *)connection;
2367
2368 if (!http->blocking)
2369 {
2370 /*
2371 * Make sure we have data before we read...
2372 */
2373
2374 while (!_httpWait(http, http->wait_value, 0))
2375 {
2376 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2377 continue;
2378
2379 http->error = ETIMEDOUT;
2380 return (-1);
2381 }
2382 }
2383
2384 do
2385 {
2386 bytes = recv(http->fd, data, *dataLength, 0);
2387 }
2388 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
2389
2390 if (bytes == *dataLength)
2391 {
2392 result = 0;
2393 }
2394 else if (bytes > 0)
2395 {
2396 *dataLength = bytes;
2397 result = errSSLWouldBlock;
2398 }
2399 else
2400 {
2401 *dataLength = 0;
2402
2403 if (bytes == 0)
2404 result = errSSLClosedGraceful;
2405 else if (errno == EAGAIN)
2406 result = errSSLWouldBlock;
2407 else
2408 result = errSSLClosedAbort;
2409 }
2410
2411 return (result);
2412 }
2413 #endif /* HAVE_SSL && HAVE_CDSASSL */
2414
2415
2416 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
2417 /*
2418 * '_httpReadGNUTLS()' - Read function for the GNU TLS library.
2419 */
2420
2421 ssize_t /* O - Number of bytes read or -1 on error */
2422 _httpReadGNUTLS(
2423 gnutls_transport_ptr ptr, /* I - Connection to server */
2424 void *data, /* I - Buffer */
2425 size_t length) /* I - Number of bytes to read */
2426 {
2427 http_t *http; /* HTTP connection */
2428 ssize_t bytes; /* Bytes read */
2429
2430
2431 DEBUG_printf(("6_httpReadGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data, (int)length));
2432
2433 http = (http_t *)ptr;
2434
2435 if (!http->blocking)
2436 {
2437 /*
2438 * Make sure we have data before we read...
2439 */
2440
2441 while (!_httpWait(http, http->wait_value, 0))
2442 {
2443 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2444 continue;
2445
2446 http->error = ETIMEDOUT;
2447 return (-1);
2448 }
2449 }
2450
2451 bytes = recv(http->fd, data, length, 0);
2452 DEBUG_printf(("6_httpReadGNUTLS: bytes=%d", (int)bytes));
2453 return (bytes);
2454 }
2455 #endif /* HAVE_SSL && HAVE_GNUTLS */
2456
2457
2458 /*
2459 * 'httpReadRequest()' - Read a HTTP request from a connection.
2460 *
2461 * @since CUPS 1.7@
2462 */
2463
2464 http_state_t /* O - New state of connection */
2465 httpReadRequest(http_t *http, /* I - HTTP connection */
2466 char *uri, /* I - URI buffer */
2467 size_t urilen) /* I - Size of URI buffer */
2468 {
2469 char line[4096], /* HTTP request line */
2470 *req_method, /* HTTP request method */
2471 *req_uri, /* HTTP request URI */
2472 *req_version; /* HTTP request version number string */
2473
2474
2475 /*
2476 * Range check input...
2477 */
2478
2479 DEBUG_printf(("httpReadRequest(http=%p, uri=%p, urilen=" CUPS_LLFMT ")",
2480 http, uri, CUPS_LLCAST urilen));
2481
2482 if (uri)
2483 *uri = '\0';
2484
2485 if (!http || !uri || urilen < 1)
2486 {
2487 DEBUG_puts("1httpReadRequest: Bad arguments, returning HTTP_STATE_ERROR.");
2488 return (HTTP_STATE_ERROR);
2489 }
2490 else if (http->state != HTTP_STATE_WAITING)
2491 {
2492 DEBUG_printf(("1httpReadRequest: Bad state %s, returning HTTP_STATE_ERROR.",
2493 http_states[http->state + 1]));
2494 return (HTTP_STATE_ERROR);
2495 }
2496
2497 /*
2498 * Reset state...
2499 */
2500
2501 httpClearFields(http);
2502
2503 http->activity = time(NULL);
2504 http->data_encoding = HTTP_ENCODING_FIELDS;
2505 http->data_remaining = 0;
2506 http->keep_alive = HTTP_KEEPALIVE_OFF;
2507 http->status = HTTP_STATUS_OK;
2508 http->version = HTTP_VERSION_1_1;
2509
2510 /*
2511 * Read a line from the socket...
2512 */
2513
2514 if (!httpGets(line, sizeof(line), http))
2515 {
2516 DEBUG_puts("1httpReadRequest: Unable to read, returning HTTP_STATE_ERROR");
2517 return (HTTP_STATE_ERROR);
2518 }
2519
2520 if (!line[0])
2521 {
2522 DEBUG_puts("1httpReadRequest: Blank line, returning HTTP_STATE_WAITING");
2523 return (HTTP_STATE_WAITING);
2524 }
2525
2526 DEBUG_printf(("1httpReadRequest: %s", line));
2527
2528 /*
2529 * Parse it...
2530 */
2531
2532 req_method = line;
2533 req_uri = line;
2534
2535 while (*req_uri && !isspace(*req_uri & 255))
2536 req_uri ++;
2537
2538 if (!*req_uri)
2539 {
2540 DEBUG_puts("1httpReadRequest: No request URI.");
2541 return (HTTP_STATE_ERROR);
2542 }
2543
2544 *req_uri++ = '\0';
2545
2546 while (*req_uri && isspace(*req_uri & 255))
2547 req_uri ++;
2548
2549 req_version = req_uri;
2550
2551 while (*req_version && !isspace(*req_version & 255))
2552 req_version ++;
2553
2554 if (!*req_version)
2555 {
2556 DEBUG_puts("1httpReadRequest: No request protocol version.");
2557 return (HTTP_STATE_ERROR);
2558 }
2559
2560 *req_version++ = '\0';
2561
2562 while (*req_version && isspace(*req_version & 255))
2563 req_version ++;
2564
2565 /*
2566 * Validate...
2567 */
2568
2569 if (!strcmp(req_method, "OPTIONS"))
2570 http->state = HTTP_STATE_OPTIONS;
2571 else if (!strcmp(req_method, "GET"))
2572 http->state = HTTP_STATE_GET;
2573 else if (!strcmp(req_method, "HEAD"))
2574 http->state = HTTP_STATE_HEAD;
2575 else if (!strcmp(req_method, "POST"))
2576 http->state = HTTP_STATE_POST;
2577 else if (!strcmp(req_method, "PUT"))
2578 http->state = HTTP_STATE_PUT;
2579 else if (!strcmp(req_method, "DELETE"))
2580 http->state = HTTP_STATE_DELETE;
2581 else if (!strcmp(req_method, "TRACE"))
2582 http->state = HTTP_STATE_TRACE;
2583 else if (!strcmp(req_method, "CONNECT"))
2584 http->state = HTTP_STATE_CONNECT;
2585 else
2586 {
2587 DEBUG_printf(("1httpReadRequest: Unknown method \"%s\".", req_method));
2588 return (HTTP_STATE_UNKNOWN_METHOD);
2589 }
2590
2591 DEBUG_printf(("1httpReadRequest: Set state to %s.",
2592 http_states[http->state + 1]));
2593
2594 if (!strcmp(req_version, "HTTP/1.0"))
2595 {
2596 http->version = HTTP_VERSION_1_0;
2597 http->keep_alive = HTTP_KEEPALIVE_OFF;
2598 }
2599 else if (!strcmp(req_version, "HTTP/1.1"))
2600 {
2601 http->version = HTTP_VERSION_1_1;
2602 http->keep_alive = HTTP_KEEPALIVE_ON;
2603 }
2604 else
2605 {
2606 DEBUG_printf(("1httpReadRequest: Unknown version \"%s\".", req_version));
2607 return (HTTP_STATE_UNKNOWN_VERSION);
2608 }
2609
2610 DEBUG_printf(("1httpReadRequest: URI is \"%s\".", req_uri));
2611 strlcpy(uri, req_uri, urilen);
2612
2613 return (http->state);
2614 }
2615
2616
2617 /*
2618 * 'httpReconnect()' - Reconnect to a HTTP server.
2619 *
2620 * This function is deprecated. Please use the @link httpReconnect2@ function
2621 * instead.
2622 *
2623 * @deprecated@
2624 */
2625
2626 int /* O - 0 on success, non-zero on failure */
2627 httpReconnect(http_t *http) /* I - Connection to server */
2628 {
2629 DEBUG_printf(("httpReconnect(http=%p)", http));
2630
2631 return (httpReconnect2(http, 30000, NULL));
2632 }
2633
2634
2635 /*
2636 * 'httpReconnect2()' - Reconnect to a HTTP server with timeout and optional
2637 * cancel.
2638 */
2639
2640 int /* O - 0 on success, non-zero on failure */
2641 httpReconnect2(http_t *http, /* I - Connection to server */
2642 int msec, /* I - Timeout in milliseconds */
2643 int *cancel) /* I - Pointer to "cancel" variable */
2644 {
2645 http_addrlist_t *addr; /* Connected address */
2646 #ifdef DEBUG
2647 http_addrlist_t *current; /* Current address */
2648 char temp[256]; /* Temporary address string */
2649 #endif /* DEBUG */
2650
2651
2652 DEBUG_printf(("httpReconnect2(http=%p, msec=%d, cancel=%p)", http, msec,
2653 cancel));
2654
2655 if (!http)
2656 {
2657 _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
2658 return (-1);
2659 }
2660
2661 #ifdef HAVE_SSL
2662 if (http->tls)
2663 {
2664 DEBUG_puts("2httpReconnect2: Shutting down SSL/TLS...");
2665 http_shutdown_ssl(http);
2666 }
2667 #endif /* HAVE_SSL */
2668
2669 /*
2670 * Close any previously open socket...
2671 */
2672
2673 if (http->fd >= 0)
2674 {
2675 DEBUG_printf(("2httpReconnect2: Closing socket %d...", http->fd));
2676
2677 #ifdef WIN32
2678 closesocket(http->fd);
2679 #else
2680 close(http->fd);
2681 #endif /* WIN32 */
2682
2683 http->fd = -1;
2684 }
2685
2686 /*
2687 * Reset all state (except fields, which may be reused)...
2688 */
2689
2690 http->state = HTTP_STATE_WAITING;
2691 http->status = HTTP_STATUS_CONTINUE;
2692 http->version = HTTP_VERSION_1_1;
2693 http->keep_alive = HTTP_KEEPALIVE_OFF;
2694 memset(&http->_hostaddr, 0, sizeof(http->_hostaddr));
2695 http->data_encoding = HTTP_ENCODING_FIELDS;
2696 http->_data_remaining = 0;
2697 http->used = 0;
2698 http->expect = 0;
2699 http->data_remaining = 0;
2700 http->hostaddr = NULL;
2701 http->wused = 0;
2702
2703 /*
2704 * Connect to the server...
2705 */
2706
2707 #ifdef DEBUG
2708 for (current = http->addrlist; current; current = current->next)
2709 DEBUG_printf(("2httpReconnect2: Address %s:%d",
2710 httpAddrString(&(current->addr), temp, sizeof(temp)),
2711 httpAddrPort(&(current->addr))));
2712 #endif /* DEBUG */
2713
2714 if ((addr = httpAddrConnect2(http->addrlist, &(http->fd), msec,
2715 cancel)) == NULL)
2716 {
2717 /*
2718 * Unable to connect...
2719 */
2720
2721 #ifdef WIN32
2722 http->error = WSAGetLastError();
2723 #else
2724 http->error = errno;
2725 #endif /* WIN32 */
2726 http->status = HTTP_ERROR;
2727
2728 DEBUG_printf(("1httpReconnect2: httpAddrConnect failed: %s",
2729 strerror(http->error)));
2730
2731 return (-1);
2732 }
2733
2734 DEBUG_printf(("2httpReconnect2: New socket=%d", http->fd));
2735
2736 if (http->timeout_value > 0)
2737 http_set_timeout(http->fd, http->timeout_value);
2738
2739 http->hostaddr = &(addr->addr);
2740 http->error = 0;
2741
2742 #ifdef HAVE_SSL
2743 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
2744 {
2745 /*
2746 * Always do encryption via SSL.
2747 */
2748
2749 if (http_setup_ssl(http) != 0)
2750 {
2751 # ifdef WIN32
2752 closesocket(http->fd);
2753 # else
2754 close(http->fd);
2755 # endif /* WIN32 */
2756
2757 return (-1);
2758 }
2759 }
2760 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
2761 return (http_upgrade(http));
2762 #endif /* HAVE_SSL */
2763
2764 DEBUG_printf(("1httpReconnect2: Connected to %s:%d...",
2765 httpAddrString(http->hostaddr, temp, sizeof(temp)),
2766 httpAddrPort(http->hostaddr)));
2767
2768 return (0);
2769 }
2770
2771
2772 /*
2773 * 'httpSetAuthString()' - Set the current authorization string.
2774 *
2775 * This function just stores a copy of the current authorization string in
2776 * the HTTP connection object. You must still call httpSetField() to set
2777 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
2778 * httpHead(), httpOptions(), httpPost, or httpPut().
2779 *
2780 * @since CUPS 1.3/OS X 10.5@
2781 */
2782
2783 void
2784 httpSetAuthString(http_t *http, /* I - Connection to server */
2785 const char *scheme, /* I - Auth scheme (NULL to clear it) */
2786 const char *data) /* I - Auth data (NULL for none) */
2787 {
2788 /*
2789 * Range check input...
2790 */
2791
2792 if (!http)
2793 return;
2794
2795 if (http->authstring && http->authstring != http->_authstring)
2796 free(http->authstring);
2797
2798 http->authstring = http->_authstring;
2799
2800 if (scheme)
2801 {
2802 /*
2803 * Set the current authorization string...
2804 */
2805
2806 int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1;
2807 char *temp;
2808
2809 if (len > (int)sizeof(http->_authstring))
2810 {
2811 if ((temp = malloc(len)) == NULL)
2812 len = sizeof(http->_authstring);
2813 else
2814 http->authstring = temp;
2815 }
2816
2817 if (data)
2818 snprintf(http->authstring, len, "%s %s", scheme, data);
2819 else
2820 strlcpy(http->authstring, scheme, len);
2821 }
2822 else
2823 {
2824 /*
2825 * Clear the current authorization string...
2826 */
2827
2828 http->_authstring[0] = '\0';
2829 }
2830 }
2831
2832
2833 /*
2834 * 'httpSetCredentials()' - Set the credentials associated with an encrypted
2835 * connection.
2836 *
2837 * @since CUPS 1.5/OS X 10.7@
2838 */
2839
2840 int /* O - Status of call (0 = success) */
2841 httpSetCredentials(http_t *http, /* I - Connection to server */
2842 cups_array_t *credentials) /* I - Array of credentials */
2843 {
2844 if (!http || cupsArrayCount(credentials) < 1)
2845 return (-1);
2846
2847 _httpFreeCredentials(http->tls_credentials);
2848
2849 http->tls_credentials = _httpCreateCredentials(credentials);
2850
2851 return (http->tls_credentials ? 0 : -1);
2852 }
2853
2854
2855 /*
2856 * 'httpSetCookie()' - Set the cookie value(s).
2857 *
2858 * @since CUPS 1.1.19/OS X 10.3@
2859 */
2860
2861 void
2862 httpSetCookie(http_t *http, /* I - Connection */
2863 const char *cookie) /* I - Cookie string */
2864 {
2865 if (!http)
2866 return;
2867
2868 if (http->cookie)
2869 free(http->cookie);
2870
2871 if (cookie)
2872 http->cookie = strdup(cookie);
2873 else
2874 http->cookie = NULL;
2875 }
2876
2877
2878 /*
2879 * 'httpSetDefaultField()' - Set the default value of an HTTP header.
2880 *
2881 * Currently only HTTP_FIELD_ACCEPT_ENCODING, HTTP_FIELD_SERVER, and
2882 * HTTP_FIELD_USER_AGENT can be set.
2883 *
2884 * @since CUPS 1.7@
2885 */
2886
2887 void
2888 httpSetDefaultField(http_t *http, /* I - Connection to server */
2889 http_field_t field, /* I - Field index */
2890 const char *value)/* I - Value */
2891 {
2892 DEBUG_printf(("httpSetDefaultField(http=%p, field=%d(%s), value=\"%s\")",
2893 http, field, http_fields[field], value));
2894
2895 if (!http)
2896 return;
2897
2898 switch (field)
2899 {
2900 case HTTP_FIELD_ACCEPT_ENCODING :
2901 if (http->default_accept_encoding)
2902 _cupsStrFree(http->default_accept_encoding);
2903
2904 http->default_accept_encoding = value ? _cupsStrAlloc(value) : NULL;
2905 break;
2906
2907 case HTTP_FIELD_SERVER :
2908 if (http->default_server)
2909 _cupsStrFree(http->default_server);
2910
2911 http->default_server = value ? _cupsStrAlloc(value) : NULL;
2912 break;
2913
2914 case HTTP_FIELD_USER_AGENT :
2915 if (http->default_user_agent)
2916 _cupsStrFree(http->default_user_agent);
2917
2918 http->default_user_agent = value ? _cupsStrAlloc(value) : NULL;
2919 break;
2920
2921 default :
2922 DEBUG_puts("1httpSetDefaultField: Ignored.");
2923 break;
2924 }
2925 }
2926
2927
2928 /*
2929 * 'httpSetExpect()' - Set the Expect: header in a request.
2930 *
2931 * Currently only @code HTTP_STATUS_CONTINUE@ is supported for the "expect"
2932 * argument.
2933 *
2934 * @since CUPS 1.2/OS X 10.5@
2935 */
2936
2937 void
2938 httpSetExpect(http_t *http, /* I - Connection to server */
2939 http_status_t expect) /* I - HTTP status to expect
2940 (@code HTTP_CONTINUE@) */
2941 {
2942 if (http)
2943 http->expect = expect;
2944 }
2945
2946
2947 /*
2948 * 'httpSetField()' - Set the value of an HTTP header.
2949 */
2950
2951 void
2952 httpSetField(http_t *http, /* I - Connection to server */
2953 http_field_t field, /* I - Field index */
2954 const char *value) /* I - Value */
2955 {
2956 DEBUG_printf(("httpSetField(http=%p, field=%d(%s), value=\"%s\")", http,
2957 field, http_fields[field], value));
2958
2959 if (http == NULL ||
2960 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
2961 field >= HTTP_FIELD_MAX ||
2962 value == NULL)
2963 return;
2964
2965 switch (field)
2966 {
2967 case HTTP_FIELD_ACCEPT_ENCODING :
2968 if (http->accept_encoding)
2969 _cupsStrFree(http->accept_encoding);
2970
2971 http->accept_encoding = _cupsStrAlloc(value);
2972 break;
2973
2974 case HTTP_FIELD_ALLOW :
2975 if (http->allow)
2976 _cupsStrFree(http->allow);
2977
2978 http->allow = _cupsStrAlloc(value);
2979 break;
2980
2981 case HTTP_FIELD_SERVER :
2982 if (http->server)
2983 _cupsStrFree(http->server);
2984
2985 http->server = _cupsStrAlloc(value);
2986 break;
2987
2988 default :
2989 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
2990 break;
2991 }
2992
2993 if (field == HTTP_FIELD_AUTHORIZATION)
2994 {
2995 /*
2996 * Special case for Authorization: as its contents can be
2997 * longer than HTTP_MAX_VALUE
2998 */
2999
3000 if (http->field_authorization)
3001 free(http->field_authorization);
3002
3003 http->field_authorization = strdup(value);
3004 }
3005 else if (field == HTTP_FIELD_HOST)
3006 {
3007 /*
3008 * Special-case for Host: as we don't want a trailing "." on the hostname and
3009 * need to bracket IPv6 numeric addresses.
3010 */
3011
3012 char *ptr = strchr(value, ':');
3013
3014 if (value[0] != '[' && ptr && strchr(ptr + 1, ':'))
3015 {
3016 /*
3017 * Bracket IPv6 numeric addresses...
3018 *
3019 * This is slightly inefficient (basically copying twice), but is an edge
3020 * case and not worth optimizing...
3021 */
3022
3023 snprintf(http->fields[HTTP_FIELD_HOST],
3024 sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value);
3025 }
3026 else
3027 {
3028 /*
3029 * Check for a trailing dot on the hostname...
3030 */
3031
3032 ptr = http->fields[HTTP_FIELD_HOST];
3033
3034 if (*ptr)
3035 {
3036 ptr += strlen(ptr) - 1;
3037
3038 if (*ptr == '.')
3039 *ptr = '\0';
3040 }
3041 }
3042 }
3043 #ifdef HAVE_LIBZ
3044 else if (field == HTTP_FIELD_CONTENT_ENCODING &&
3045 http->data_encoding != HTTP_ENCODING_FIELDS)
3046 {
3047 DEBUG_puts("1httpSetField: Calling http_content_coding_start.");
3048 http_content_coding_start(http, value);
3049 }
3050 #endif /* HAVE_LIBZ */
3051 }
3052
3053
3054 /*
3055 * 'httpSetLength()' - Set the content-length and content-encoding.
3056 *
3057 * @since CUPS 1.2/OS X 10.5@
3058 */
3059
3060 void
3061 httpSetLength(http_t *http, /* I - Connection to server */
3062 size_t length) /* I - Length (0 for chunked) */
3063 {
3064 DEBUG_printf(("httpSetLength(http=%p, length=" CUPS_LLFMT ")", http,
3065 CUPS_LLCAST length));
3066
3067 if (!http)
3068 return;
3069
3070 if (!length)
3071 {
3072 strlcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked",
3073 HTTP_MAX_VALUE);
3074 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
3075 }
3076 else
3077 {
3078 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
3079 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
3080 CUPS_LLFMT, CUPS_LLCAST length);
3081 }
3082 }
3083
3084
3085 /*
3086 * 'httpSetTimeout()' - Set read/write timeouts and an optional callback.
3087 *
3088 * The optional timeout callback receives both the HTTP connection and a user
3089 * data pointer and must return 1 to continue or 0 to error (time) out.
3090 *
3091 * @since CUPS 1.5/OS X 10.7@
3092 */
3093
3094 void
3095 httpSetTimeout(
3096 http_t *http, /* I - Connection to server */
3097 double timeout, /* I - Number of seconds for timeout,
3098 must be greater than 0 */
3099 http_timeout_cb_t cb, /* I - Callback function or NULL */
3100 void *user_data) /* I - User data pointer */
3101 {
3102 if (!http || timeout <= 0.0)
3103 return;
3104
3105 http->timeout_cb = cb;
3106 http->timeout_data = user_data;
3107 http->timeout_value = timeout;
3108
3109 if (http->fd >= 0)
3110 http_set_timeout(http->fd, timeout);
3111
3112 http_set_wait(http);
3113 }
3114
3115
3116 /*
3117 * 'httpTrace()' - Send an TRACE request to the server.
3118 */
3119
3120 int /* O - Status of call (0 = success) */
3121 httpTrace(http_t *http, /* I - Connection to server */
3122 const char *uri) /* I - URI for trace */
3123 {
3124 return (http_send(http, HTTP_TRACE, uri));
3125 }
3126
3127
3128 /*
3129 * '_httpUpdate()' - Update the current HTTP status for incoming data.
3130 *
3131 * Note: Unlike httpUpdate(), this function does not flush pending write data
3132 * and only retrieves a single status line from the HTTP connection.
3133 */
3134
3135 int /* O - 1 to continue, 0 to stop */
3136 _httpUpdate(http_t *http, /* I - Connection to server */
3137 http_status_t *status) /* O - Current HTTP status */
3138 {
3139 char line[32768], /* Line from connection... */
3140 *value; /* Pointer to value on line */
3141 http_field_t field; /* Field index */
3142 int major, minor; /* HTTP version numbers */
3143
3144
3145 DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", http, status,
3146 http_states[http->state + 1]));
3147
3148 /*
3149 * Grab a single line from the connection...
3150 */
3151
3152 if (!httpGets(line, sizeof(line), http))
3153 {
3154 *status = HTTP_ERROR;
3155 return (0);
3156 }
3157
3158 DEBUG_printf(("2_httpUpdate: Got \"%s\"", line));
3159
3160 if (line[0] == '\0')
3161 {
3162 /*
3163 * Blank line means the start of the data section (if any). Return
3164 * the result code, too...
3165 *
3166 * If we get status 100 (HTTP_STATUS_CONTINUE), then we *don't* change
3167 * states. Instead, we just return HTTP_STATUS_CONTINUE to the caller and
3168 * keep on tryin'...
3169 */
3170
3171 if (http->status == HTTP_STATUS_CONTINUE)
3172 {
3173 *status = http->status;
3174 return (0);
3175 }
3176
3177 if (http->status < HTTP_BAD_REQUEST)
3178 http->digest_tries = 0;
3179
3180 #ifdef HAVE_SSL
3181 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
3182 {
3183 if (http_setup_ssl(http) != 0)
3184 {
3185 # ifdef WIN32
3186 closesocket(http->fd);
3187 # else
3188 close(http->fd);
3189 # endif /* WIN32 */
3190
3191 *status = http->status = HTTP_ERROR;
3192 return (0);
3193 }
3194
3195 *status = HTTP_STATUS_CONTINUE;
3196 return (0);
3197 }
3198 #endif /* HAVE_SSL */
3199
3200 if (http_set_length(http) < 0)
3201 {
3202 DEBUG_puts("1_httpUpdate: Bad Content-Length.");
3203 http->error = EINVAL;
3204 http->status = *status = HTTP_ERROR;
3205 return (0);
3206 }
3207
3208 switch (http->state)
3209 {
3210 case HTTP_STATE_GET :
3211 case HTTP_STATE_POST :
3212 case HTTP_STATE_POST_RECV :
3213 case HTTP_STATE_PUT :
3214 http->state ++;
3215
3216 DEBUG_printf(("1_httpUpdate: Set state to %s.",
3217 http_states[http->state + 1]));
3218
3219 case HTTP_STATE_POST_SEND :
3220 case HTTP_STATE_HEAD :
3221 break;
3222
3223 default :
3224 http->state = HTTP_STATE_WAITING;
3225
3226 DEBUG_puts("1_httpUpdate: Unknown state, reset state to "
3227 "HTTP_STATE_WAITING.");
3228 break;
3229 }
3230
3231 #ifdef HAVE_LIBZ
3232 DEBUG_puts("1_httpUpdate: Calling http_content_coding_start.");
3233 http_content_coding_start(http,
3234 httpGetField(http, HTTP_FIELD_CONTENT_ENCODING));
3235 #endif /* HAVE_LIBZ */
3236
3237 *status = http->status;
3238 return (0);
3239 }
3240 else if (!strncmp(line, "HTTP/", 5))
3241 {
3242 /*
3243 * Got the beginning of a response...
3244 */
3245
3246 int intstatus; /* Status value as an integer */
3247
3248 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &intstatus) != 3)
3249 {
3250 *status = http->status = HTTP_ERROR;
3251 return (0);
3252 }
3253
3254 httpClearFields(http);
3255
3256 http->version = (http_version_t)(major * 100 + minor);
3257 *status = http->status = (http_status_t)intstatus;
3258 }
3259 else if ((value = strchr(line, ':')) != NULL)
3260 {
3261 /*
3262 * Got a value...
3263 */
3264
3265 *value++ = '\0';
3266 while (_cups_isspace(*value))
3267 value ++;
3268
3269 DEBUG_printf(("1_httpUpdate: Header %s: %s", line, value));
3270
3271 /*
3272 * Be tolerants of servers that send unknown attribute fields...
3273 */
3274
3275 if (!_cups_strcasecmp(line, "expect"))
3276 {
3277 /*
3278 * "Expect: 100-continue" or similar...
3279 */
3280
3281 http->expect = (http_status_t)atoi(value);
3282 }
3283 else if (!_cups_strcasecmp(line, "cookie"))
3284 {
3285 /*
3286 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
3287 */
3288
3289 httpSetCookie(http, value);
3290 }
3291 else if ((field = http_field(line)) != HTTP_FIELD_UNKNOWN)
3292 httpSetField(http, field, value);
3293 #ifdef DEBUG
3294 else
3295 DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line));
3296 #endif /* DEBUG */
3297 }
3298 else
3299 {
3300 DEBUG_printf(("1_httpUpdate: Bad response line \"%s\"!", line));
3301 http->error = EINVAL;
3302 http->status = *status = HTTP_ERROR;
3303 return (0);
3304 }
3305
3306 return (1);
3307 }
3308
3309
3310 /*
3311 * 'httpUpdate()' - Update the current HTTP state for incoming data.
3312 */
3313
3314 http_status_t /* O - HTTP status */
3315 httpUpdate(http_t *http) /* I - Connection to server */
3316 {
3317 http_status_t status; /* Request status */
3318
3319
3320 DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
3321 http_states[http->state + 1]));
3322
3323 /*
3324 * Flush pending data, if any...
3325 */
3326
3327 if (http->wused)
3328 {
3329 DEBUG_puts("2httpUpdate: flushing buffer...");
3330
3331 if (httpFlushWrite(http) < 0)
3332 return (HTTP_ERROR);
3333 }
3334
3335 /*
3336 * If we haven't issued any commands, then there is nothing to "update"...
3337 */
3338
3339 if (http->state == HTTP_STATE_WAITING)
3340 return (HTTP_CONTINUE);
3341
3342 /*
3343 * Grab all of the lines we can from the connection...
3344 */
3345
3346 while (_httpUpdate(http, &status));
3347
3348 /*
3349 * See if there was an error...
3350 */
3351
3352 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
3353 {
3354 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status));
3355 return (http->status);
3356 }
3357
3358 if (http->error)
3359 {
3360 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error,
3361 strerror(http->error)));
3362 http->status = HTTP_ERROR;
3363 return (HTTP_ERROR);
3364 }
3365
3366 /*
3367 * Return the current status...
3368 */
3369
3370 return (status);
3371 }
3372
3373
3374 /*
3375 * '_httpWait()' - Wait for data available on a connection (no flush).
3376 */
3377
3378 int /* O - 1 if data is available, 0 otherwise */
3379 _httpWait(http_t *http, /* I - Connection to server */
3380 int msec, /* I - Milliseconds to wait */
3381 int usessl) /* I - Use SSL context? */
3382 {
3383 #ifdef HAVE_POLL
3384 struct pollfd pfd; /* Polled file descriptor */
3385 #else
3386 fd_set input_set; /* select() input set */
3387 struct timeval timeout; /* Timeout */
3388 #endif /* HAVE_POLL */
3389 int nfds; /* Result from select()/poll() */
3390
3391
3392 DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl));
3393
3394 if (http->fd < 0)
3395 {
3396 DEBUG_printf(("5_httpWait: Returning 0 since fd=%d", http->fd));
3397 return (0);
3398 }
3399
3400 /*
3401 * Check the SSL/TLS buffers for data first...
3402 */
3403
3404 #ifdef HAVE_SSL
3405 if (http->tls && usessl)
3406 {
3407 # ifdef HAVE_LIBSSL
3408 if (SSL_pending(http->tls))
3409 {
3410 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
3411 return (1);
3412 }
3413
3414 # elif defined(HAVE_GNUTLS)
3415 if (gnutls_record_check_pending(http->tls))
3416 {
3417 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
3418 return (1);
3419 }
3420
3421 # elif defined(HAVE_CDSASSL)
3422 size_t bytes; /* Bytes that are available */
3423
3424 if (!SSLGetBufferedReadSize(http->tls, &bytes) &&
3425 bytes > 0)
3426 {
3427 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
3428 return (1);
3429 }
3430 # endif /* HAVE_LIBSSL */
3431 }
3432 #endif /* HAVE_SSL */
3433
3434 /*
3435 * Then try doing a select() or poll() to poll the socket...
3436 */
3437
3438 #ifdef HAVE_POLL
3439 pfd.fd = http->fd;
3440 pfd.events = POLLIN;
3441
3442 do
3443 {
3444 nfds = poll(&pfd, 1, msec);
3445 }
3446 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
3447
3448 #else
3449 do
3450 {
3451 FD_ZERO(&input_set);
3452 FD_SET(http->fd, &input_set);
3453
3454 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd));
3455
3456 if (msec >= 0)
3457 {
3458 timeout.tv_sec = msec / 1000;
3459 timeout.tv_usec = (msec % 1000) * 1000;
3460
3461 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
3462 }
3463 else
3464 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
3465
3466 DEBUG_printf(("6_httpWait: select() returned %d...", nfds));
3467 }
3468 # ifdef WIN32
3469 while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
3470 WSAGetLastError() == WSAEWOULDBLOCK));
3471 # else
3472 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
3473 # endif /* WIN32 */
3474 #endif /* HAVE_POLL */
3475
3476 DEBUG_printf(("5_httpWait: returning with nfds=%d, errno=%d...", nfds,
3477 errno));
3478
3479 return (nfds > 0);
3480 }
3481
3482
3483 /*
3484 * 'httpWait()' - Wait for data available on a connection.
3485 *
3486 * @since CUPS 1.1.19/OS X 10.3@
3487 */
3488
3489 int /* O - 1 if data is available, 0 otherwise */
3490 httpWait(http_t *http, /* I - Connection to server */
3491 int msec) /* I - Milliseconds to wait */
3492 {
3493 /*
3494 * First see if there is data in the buffer...
3495 */
3496
3497 DEBUG_printf(("2httpWait(http=%p, msec=%d)", http, msec));
3498
3499 if (http == NULL)
3500 return (0);
3501
3502 if (http->used)
3503 {
3504 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready.");
3505 return (1);
3506 }
3507
3508 #ifdef HAVE_LIBZ
3509 if (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in > 0)
3510 {
3511 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready.");
3512 return (1);
3513 }
3514 #endif /* HAVE_LIBZ */
3515
3516 /*
3517 * Flush pending data, if any...
3518 */
3519
3520 if (http->wused)
3521 {
3522 DEBUG_puts("3httpWait: Flushing write buffer.");
3523
3524 if (httpFlushWrite(http) < 0)
3525 return (0);
3526 }
3527
3528 /*
3529 * If not, check the SSL/TLS buffers and do a select() on the connection...
3530 */
3531
3532 return (_httpWait(http, msec, 1));
3533 }
3534
3535
3536 /*
3537 * 'httpWrite()' - Write data to a HTTP connection.
3538 *
3539 * This function is deprecated. Use the httpWrite2() function which can
3540 * write more than 2GB of data.
3541 *
3542 * @deprecated@
3543 */
3544
3545 int /* O - Number of bytes written */
3546 httpWrite(http_t *http, /* I - Connection to server */
3547 const char *buffer, /* I - Buffer for data */
3548 int length) /* I - Number of bytes to write */
3549 {
3550 return ((int)httpWrite2(http, buffer, length));
3551 }
3552
3553
3554 /*
3555 * 'httpWrite2()' - Write data to a HTTP connection.
3556 *
3557 * @since CUPS 1.2/OS X 10.5@
3558 */
3559
3560 ssize_t /* O - Number of bytes written */
3561 httpWrite2(http_t *http, /* I - Connection to server */
3562 const char *buffer, /* I - Buffer for data */
3563 size_t length) /* I - Number of bytes to write */
3564 {
3565 ssize_t bytes; /* Bytes written */
3566
3567
3568 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
3569 buffer, CUPS_LLCAST length));
3570
3571 /*
3572 * Range check input...
3573 */
3574
3575 if (!http || !buffer)
3576 {
3577 DEBUG_puts("1httpWrite2: Returning -1 due to bad input.");
3578 return (-1);
3579 }
3580
3581 /*
3582 * Mark activity on the connection...
3583 */
3584
3585 http->activity = time(NULL);
3586
3587 /*
3588 * Buffer small writes for better performance...
3589 */
3590
3591 #ifdef HAVE_LIBZ
3592 if (http->coding)
3593 {
3594 DEBUG_printf(("1httpWrite2: http->coding=%d", http->coding));
3595
3596 if (length == 0)
3597 {
3598 http_content_coding_finish(http);
3599 bytes = 0;
3600 }
3601 else
3602 {
3603 http->stream.next_in = (Bytef *)buffer;
3604 http->stream.avail_in = length;
3605 http->stream.next_out = (Bytef *)http->wbuffer + http->wused;
3606 http->stream.avail_out = sizeof(http->wbuffer) - http->wused;
3607
3608 while (deflate(&(http->stream), Z_NO_FLUSH) == Z_OK)
3609 {
3610 http->wused = sizeof(http->wbuffer) - http->stream.avail_out;
3611
3612 if (http->stream.avail_out == 0)
3613 {
3614 if (httpFlushWrite(http) < 0)
3615 {
3616 DEBUG_puts("1httpWrite2: Unable to flush, returning -1.");
3617 return (-1);
3618 }
3619
3620 http->stream.next_out = (Bytef *)http->wbuffer;
3621 http->stream.avail_out = sizeof(http->wbuffer);
3622 }
3623 }
3624
3625 http->wused = sizeof(http->wbuffer) - http->stream.avail_out;
3626 bytes = length;
3627 }
3628 }
3629 else
3630 #endif /* HAVE_LIBZ */
3631 if (length > 0)
3632 {
3633 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
3634 {
3635 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length="
3636 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length));
3637
3638 httpFlushWrite(http);
3639 }
3640
3641 if ((length + http->wused) <= sizeof(http->wbuffer) &&
3642 length < sizeof(http->wbuffer))
3643 {
3644 /*
3645 * Write to buffer...
3646 */
3647
3648 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...",
3649 CUPS_LLCAST length));
3650
3651 memcpy(http->wbuffer + http->wused, buffer, length);
3652 http->wused += (int)length;
3653 bytes = (ssize_t)length;
3654 }
3655 else
3656 {
3657 /*
3658 * Otherwise write the data directly...
3659 */
3660
3661 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...",
3662 CUPS_LLCAST length));
3663
3664 if (http->data_encoding == HTTP_ENCODING_CHUNKED)
3665 bytes = (ssize_t)http_write_chunk(http, buffer, (int)length);
3666 else
3667 bytes = (ssize_t)http_write(http, buffer, (int)length);
3668
3669 DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...",
3670 CUPS_LLCAST bytes));
3671 }
3672
3673 if (http->data_encoding == HTTP_ENCODING_LENGTH)
3674 http->data_remaining -= bytes;
3675 }
3676 else
3677 bytes = 0;
3678
3679 /*
3680 * Handle end-of-request processing...
3681 */
3682
3683 if ((http->data_encoding == HTTP_ENCODING_CHUNKED && length == 0) ||
3684 (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0))
3685 {
3686 /*
3687 * Finished with the transfer; unless we are sending POST or PUT
3688 * data, go idle...
3689 */
3690
3691 #ifdef HAVE_LIBZ
3692 if (http->coding)
3693 http_content_coding_finish(http);
3694 #endif /* HAVE_LIBZ */
3695
3696 if (http->wused)
3697 {
3698 if (httpFlushWrite(http) < 0)
3699 return (-1);
3700 }
3701
3702 if (http->data_encoding == HTTP_ENCODING_CHUNKED)
3703 {
3704 /*
3705 * Send a 0-length chunk at the end of the request...
3706 */
3707
3708 http_write(http, "0\r\n\r\n", 5);
3709
3710 /*
3711 * Reset the data state...
3712 */
3713
3714 http->data_encoding = HTTP_ENCODING_FIELDS;
3715 http->data_remaining = 0;
3716 }
3717
3718 if (http->state == HTTP_STATE_POST_RECV)
3719 http->state ++;
3720 else
3721 http->state = HTTP_STATE_WAITING;
3722
3723 DEBUG_printf(("2httpWrite2: Changed state to %s.",
3724 http_states[http->state + 1]));
3725 }
3726
3727 DEBUG_printf(("1httpWrite2: Returning " CUPS_LLFMT ".", CUPS_LLCAST bytes));
3728
3729 return (bytes);
3730 }
3731
3732
3733 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
3734 /*
3735 * '_httpWriteCDSA()' - Write function for the CDSA library.
3736 */
3737
3738 OSStatus /* O - -1 on error, 0 on success */
3739 _httpWriteCDSA(
3740 SSLConnectionRef connection, /* I - SSL/TLS connection */
3741 const void *data, /* I - Data buffer */
3742 size_t *dataLength) /* IO - Number of bytes */
3743 {
3744 OSStatus result; /* Return value */
3745 ssize_t bytes; /* Number of bytes read */
3746 http_t *http; /* HTTP connection */
3747
3748
3749 http = (http_t *)connection;
3750
3751 do
3752 {
3753 bytes = write(http->fd, data, *dataLength);
3754 }
3755 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
3756
3757 if (bytes == *dataLength)
3758 {
3759 result = 0;
3760 }
3761 else if (bytes >= 0)
3762 {
3763 *dataLength = bytes;
3764 result = errSSLWouldBlock;
3765 }
3766 else
3767 {
3768 *dataLength = 0;
3769
3770 if (errno == EAGAIN)
3771 result = errSSLWouldBlock;
3772 else
3773 result = errSSLClosedAbort;
3774 }
3775
3776 return (result);
3777 }
3778 #endif /* HAVE_SSL && HAVE_CDSASSL */
3779
3780
3781 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
3782 /*
3783 * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
3784 */
3785
3786 ssize_t /* O - Number of bytes written or -1 on error */
3787 _httpWriteGNUTLS(
3788 gnutls_transport_ptr ptr, /* I - Connection to server */
3789 const void *data, /* I - Data buffer */
3790 size_t length) /* I - Number of bytes to write */
3791 {
3792 ssize_t bytes; /* Bytes written */
3793
3794
3795 DEBUG_printf(("6_httpWriteGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data,
3796 (int)length));
3797 #ifdef DEBUG
3798 http_debug_hex("_httpWriteGNUTLS", data, (int)length);
3799 #endif /* DEBUG */
3800
3801 bytes = send(((http_t *)ptr)->fd, data, length, 0);
3802 DEBUG_printf(("_httpWriteGNUTLS: bytes=%d", (int)bytes));
3803
3804 return (bytes);
3805 }
3806 #endif /* HAVE_SSL && HAVE_GNUTLS */
3807
3808
3809 /*
3810 * 'httpWriteResponse()' - Write a HTTP response to a client connection.
3811 *
3812 * @since CUPS 1.7@
3813 */
3814
3815 int /* O - 0 on success, -1 on error */
3816 httpWriteResponse(http_t *http, /* I - HTTP connection */
3817 http_status_t status) /* I - Status code */
3818 {
3819 http_encoding_t old_encoding; /* Old data_encoding value */
3820 off_t old_remaining; /* Old data_remaining value */
3821
3822
3823 /*
3824 * Range check input...
3825 */
3826
3827 DEBUG_printf(("httpWriteResponse(http=%p, status=%d)", http, status));
3828
3829 if (!http || status < HTTP_STATUS_CONTINUE)
3830 {
3831 DEBUG_puts("1httpWriteResponse: Bad input.");
3832 return (-1);
3833 }
3834
3835 /*
3836 * Set the various standard fields if they aren't already...
3837 */
3838
3839 if (!http->fields[HTTP_FIELD_DATE][0])
3840 httpSetField(http, HTTP_FIELD_DATE, httpGetDateString(time(NULL)));
3841
3842 if (status >= HTTP_BAD_REQUEST && http->keep_alive)
3843 {
3844 http->keep_alive = 0;
3845 httpSetField(http, HTTP_FIELD_KEEP_ALIVE, "");
3846 }
3847
3848 if (http->version == HTTP_VERSION_1_1)
3849 {
3850 if (!http->fields[HTTP_FIELD_CONNECTION][0])
3851 {
3852 if (http->keep_alive)
3853 httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive");
3854 else
3855 httpSetField(http, HTTP_FIELD_CONNECTION, "close");
3856 }
3857
3858 if (http->keep_alive && !http->fields[HTTP_FIELD_KEEP_ALIVE][0])
3859 httpSetField(http, HTTP_FIELD_KEEP_ALIVE, "timeout=10");
3860 }
3861
3862 #ifdef HAVE_SSL
3863 if (status == HTTP_STATUS_UPGRADE_REQUIRED)
3864 {
3865 if (!http->fields[HTTP_FIELD_CONNECTION][0])
3866 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
3867
3868 if (!http->fields[HTTP_FIELD_UPGRADE][0])
3869 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
3870 }
3871 #endif /* HAVE_SSL */
3872
3873 if (!http->server)
3874 httpSetField(http, HTTP_FIELD_SERVER,
3875 http->default_server ? http->default_server : CUPS_MINIMAL);
3876
3877 /*
3878 * Set the Accept-Encoding field if it isn't already...
3879 */
3880
3881 if (!http->accept_encoding)
3882 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
3883 http->default_accept_encoding ? http->default_accept_encoding :
3884 #ifdef HAVE_LIBZ
3885 "gzip, deflate, identity");
3886 #else
3887 "identity");
3888 #endif /* HAVE_LIBZ */
3889
3890 /*
3891 * Send the response header...
3892 */
3893
3894 old_encoding = http->data_encoding;
3895 old_remaining = http->data_remaining;
3896 http->data_encoding = HTTP_ENCODING_FIELDS;
3897
3898 if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100,
3899 http->version % 100, (int)status, httpStatus(status)) < 0)
3900 {
3901 http->status = HTTP_STATUS_ERROR;
3902 return (-1);
3903 }
3904
3905 if (status != HTTP_STATUS_CONTINUE)
3906 {
3907 /*
3908 * 100 Continue doesn't have the rest of the response headers...
3909 */
3910
3911 int i; /* Looping var */
3912 const char *value; /* Field value */
3913
3914 for (i = 0; i < HTTP_FIELD_MAX; i ++)
3915 {
3916 if ((value = httpGetField(http, i)) != NULL && *value)
3917 {
3918 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1)
3919 {
3920 http->status = HTTP_STATUS_ERROR;
3921 return (-1);
3922 }
3923 }
3924 }
3925
3926 if (http->cookie)
3927 {
3928 if (httpPrintf(http, "Set-Cookie: %s path=/%s\r\n", http->cookie,
3929 http->tls ? " secure" : "") < 1)
3930 {
3931 http->status = HTTP_ERROR;
3932 return (-1);
3933 }
3934 }
3935 }
3936
3937 if (httpWrite2(http, "\r\n", 2) < 2)
3938 {
3939 http->status = HTTP_ERROR;
3940 return (-1);
3941 }
3942
3943 if (httpFlushWrite(http) < 0)
3944 {
3945 http->status = HTTP_ERROR;
3946 return (-1);
3947 }
3948
3949 if (status == HTTP_STATUS_CONTINUE)
3950 {
3951 /*
3952 * Restore the old data_encoding and data_length values...
3953 */
3954
3955 http->data_encoding = old_encoding;
3956 http->data_remaining = old_remaining;
3957
3958 if (old_remaining <= INT_MAX)
3959 http->_data_remaining = (int)old_remaining;
3960 else
3961 http->_data_remaining = INT_MAX;
3962 }
3963 else if (http->state == HTTP_STATE_OPTIONS ||
3964 http->state == HTTP_STATE_HEAD ||
3965 http->state == HTTP_STATE_PUT ||
3966 http->state == HTTP_STATE_TRACE ||
3967 http->state == HTTP_STATE_CONNECT)
3968 {
3969 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, "
3970 "was %s.", http_states[http->state + 1]));
3971 http->state = HTTP_STATE_WAITING;
3972 }
3973 else
3974 {
3975 /*
3976 * Force data_encoding and data_length to be set according to the response
3977 * headers...
3978 */
3979
3980 http_set_length(http);
3981
3982 #ifdef HAVE_LIBZ
3983 /*
3984 * Then start any content encoding...
3985 */
3986
3987 DEBUG_puts("1httpWriteResponse: Calling http_content_coding_start.");
3988 http_content_coding_start(http,
3989 httpGetField(http, HTTP_FIELD_CONTENT_ENCODING));
3990 #endif /* HAVE_LIBZ */
3991 }
3992
3993 return (0);
3994 }
3995
3996
3997 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
3998 /*
3999 * 'http_bio_ctrl()' - Control the HTTP connection.
4000 */
4001
4002 static long /* O - Result/data */
4003 http_bio_ctrl(BIO *h, /* I - BIO data */
4004 int cmd, /* I - Control command */
4005 long arg1, /* I - First argument */
4006 void *arg2) /* I - Second argument */
4007 {
4008 switch (cmd)
4009 {
4010 default :
4011 return (0);
4012
4013 case BIO_CTRL_RESET :
4014 h->ptr = NULL;
4015 return (0);
4016
4017 case BIO_C_SET_FILE_PTR :
4018 h->ptr = arg2;
4019 h->init = 1;
4020 return (1);
4021
4022 case BIO_C_GET_FILE_PTR :
4023 if (arg2)
4024 {
4025 *((void **)arg2) = h->ptr;
4026 return (1);
4027 }
4028 else
4029 return (0);
4030
4031 case BIO_CTRL_DUP :
4032 case BIO_CTRL_FLUSH :
4033 return (1);
4034 }
4035 }
4036
4037
4038 /*
4039 * 'http_bio_free()' - Free OpenSSL data.
4040 */
4041
4042 static int /* O - 1 on success, 0 on failure */
4043 http_bio_free(BIO *h) /* I - BIO data */
4044 {
4045 if (!h)
4046 return (0);
4047
4048 if (h->shutdown)
4049 {
4050 h->init = 0;
4051 h->flags = 0;
4052 }
4053
4054 return (1);
4055 }
4056
4057
4058 /*
4059 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
4060 */
4061
4062 static int /* O - 1 on success, 0 on failure */
4063 http_bio_new(BIO *h) /* I - BIO data */
4064 {
4065 if (!h)
4066 return (0);
4067
4068 h->init = 0;
4069 h->num = 0;
4070 h->ptr = NULL;
4071 h->flags = 0;
4072
4073 return (1);
4074 }
4075
4076
4077 /*
4078 * 'http_bio_puts()' - Send a string for OpenSSL.
4079 */
4080
4081 static int /* O - Bytes written */
4082 http_bio_puts(BIO *h, /* I - BIO data */
4083 const char *str) /* I - String to write */
4084 {
4085 #ifdef WIN32
4086 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
4087 #else
4088 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
4089 #endif /* WIN32 */
4090 }
4091
4092
4093 /*
4094 * 'http_bio_read()' - Read data for OpenSSL.
4095 */
4096
4097 static int /* O - Bytes read */
4098 http_bio_read(BIO *h, /* I - BIO data */
4099 char *buf, /* I - Buffer */
4100 int size) /* I - Number of bytes to read */
4101 {
4102 http_t *http; /* HTTP connection */
4103
4104
4105 http = (http_t *)h->ptr;
4106
4107 if (!http->blocking)
4108 {
4109 /*
4110 * Make sure we have data before we read...
4111 */
4112
4113 while (!_httpWait(http, http->wait_value, 0))
4114 {
4115 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4116 continue;
4117
4118 #ifdef WIN32
4119 http->error = WSAETIMEDOUT;
4120 #else
4121 http->error = ETIMEDOUT;
4122 #endif /* WIN32 */
4123
4124 return (-1);
4125 }
4126 }
4127
4128 return (recv(http->fd, buf, size, 0));
4129 }
4130
4131
4132 /*
4133 * 'http_bio_write()' - Write data for OpenSSL.
4134 */
4135
4136 static int /* O - Bytes written */
4137 http_bio_write(BIO *h, /* I - BIO data */
4138 const char *buf, /* I - Buffer to write */
4139 int num) /* I - Number of bytes to write */
4140 {
4141 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
4142 }
4143 #endif /* HAVE_SSL && HAVE_LIBSSL */
4144
4145
4146 #ifdef HAVE_LIBZ
4147 /*
4148 * 'http_content_coding_finish()' - Finish doing any content encoding.
4149 */
4150
4151 static void
4152 http_content_coding_finish(
4153 http_t *http) /* I - HTTP connection */
4154 {
4155 int zerr; /* Compression status */
4156
4157
4158 switch (http->coding)
4159 {
4160 case _HTTP_CODING_DEFLATE :
4161 case _HTTP_CODING_GZIP :
4162 do
4163 {
4164 http->stream.next_out = (Bytef *)http->wbuffer + http->wused;
4165 http->stream.avail_out = sizeof(http->wbuffer) - http->wused;
4166
4167 zerr = deflate(&(http->stream), Z_FINISH);
4168
4169 http->wused = sizeof(http->wbuffer) - http->stream.avail_out;
4170 if (http->wused == sizeof(http->wbuffer))
4171 httpFlushWrite(http);
4172 }
4173 while (zerr == Z_OK);
4174
4175 deflateEnd(&(http->stream));
4176
4177 if (http->wused)
4178 httpFlushWrite(http);
4179 break;
4180
4181 case _HTTP_CODING_INFLATE :
4182 case _HTTP_CODING_GUNZIP :
4183 inflateEnd(&(http->stream));
4184 free(http->dbuffer);
4185 http->dbuffer = NULL;
4186 break;
4187
4188 default :
4189 break;
4190 }
4191
4192 http->coding = _HTTP_CODING_IDENTITY;
4193 }
4194
4195
4196 /*
4197 * 'http_content_coding_start()' - Start doing content encoding.
4198 */
4199
4200 static void
4201 http_content_coding_start(
4202 http_t *http, /* I - HTTP connection */
4203 const char *value) /* I - Value of Content-Encoding */
4204 {
4205 int zerr; /* Error/status */
4206 _http_coding_t coding; /* Content coding value */
4207
4208
4209 DEBUG_printf(("http_content_coding_start(http=%p, value=\"%s\")", http,
4210 value));
4211
4212 if (http->coding != _HTTP_CODING_IDENTITY)
4213 {
4214 DEBUG_printf(("1http_content_coding_start: http->coding already %d.",
4215 http->coding));
4216 return;
4217 }
4218 else if (!strcmp(value, "x-gzip") || !strcmp(value, "gzip"))
4219 {
4220 if (http->state == HTTP_GET_SEND || http->state == HTTP_POST_SEND)
4221 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_GZIP :
4222 _HTTP_CODING_GUNZIP;
4223 else if (http->state == HTTP_STATE_POST_RECV || http->state == HTTP_PUT_RECV)
4224 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_GZIP :
4225 _HTTP_CODING_GUNZIP;
4226 else
4227 {
4228 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4229 return;
4230 }
4231 }
4232 else if (!strcmp(value, "x-deflate") || !strcmp(value, "deflate"))
4233 {
4234 if (http->state == HTTP_GET_SEND || http->state == HTTP_POST_SEND)
4235 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_DEFLATE :
4236 _HTTP_CODING_INFLATE;
4237 else if (http->state == HTTP_STATE_POST_RECV || http->state == HTTP_PUT_RECV)
4238 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_DEFLATE :
4239 _HTTP_CODING_INFLATE;
4240 else
4241 {
4242 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4243 return;
4244 }
4245 }
4246 else
4247 {
4248 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4249 return;
4250 }
4251
4252 memset(&(http->stream), 0, sizeof(http->stream));
4253
4254 switch (coding)
4255 {
4256 case _HTTP_CODING_DEFLATE :
4257 case _HTTP_CODING_GZIP :
4258 if (http->wused)
4259 httpFlushWrite(http);
4260
4261 /*
4262 * Window size for compression is 11 bits - optimal based on PWG Raster
4263 * sample files on pwg.org. -11 is raw deflate, 27 is gzip, per ZLIB
4264 * documentation.
4265 */
4266
4267 if ((zerr = deflateInit2(&(http->stream), Z_DEFAULT_COMPRESSION,
4268 Z_DEFLATED,
4269 coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7,
4270 Z_DEFAULT_STRATEGY)) < Z_OK)
4271 {
4272 http->status = HTTP_ERROR;
4273 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
4274 return;
4275 }
4276 break;
4277
4278 case _HTTP_CODING_INFLATE :
4279 case _HTTP_CODING_GUNZIP :
4280 if ((http->dbuffer = malloc(HTTP_MAX_BUFFER)) == NULL)
4281 {
4282 http->status = HTTP_ERROR;
4283 http->error = errno;
4284 return;
4285 }
4286
4287 /*
4288 * Window size for decompression is up to 15 bits (maximum supported).
4289 * -15 is raw inflate, 31 is gunzip, per ZLIB documentation.
4290 */
4291
4292 if ((zerr = inflateInit2(&(http->stream),
4293 coding == _HTTP_CODING_INFLATE ? -15 : 31))
4294 < Z_OK)
4295 {
4296 free(http->dbuffer);
4297 http->dbuffer = NULL;
4298 http->status = HTTP_ERROR;
4299 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
4300 return;
4301 }
4302
4303 http->stream.avail_in = 0;
4304 http->stream.next_in = http->dbuffer;
4305 break;
4306
4307 default :
4308 break;
4309 }
4310
4311 http->coding = coding;
4312
4313 DEBUG_printf(("1http_content_coding_start: http->coding now %d.",
4314 http->coding));
4315 }
4316 #endif /* HAVE_LIBZ */
4317
4318
4319 /*
4320 * 'http_create()' - Create an unconnected HTTP connection.
4321 */
4322
4323 static http_t * /* O - HTTP connection */
4324 http_create(
4325 const char *host, /* I - Hostname */
4326 int port, /* I - Port number */
4327 http_addrlist_t *addrlist, /* I - Address list or NULL */
4328 int family, /* I - Address family or AF_UNSPEC */
4329 http_encryption_t encryption, /* I - Encryption to use */
4330 int blocking, /* I - 1 for blocking mode */
4331 _http_mode_t mode) /* I - _HTTP_MODE_CLIENT or _SERVER */
4332 {
4333 http_t *http; /* New HTTP connection */
4334 char service[255]; /* Service name */
4335 http_addrlist_t *myaddrlist = NULL; /* My address list */
4336
4337
4338 DEBUG_printf(("4http_create(host=\"%s\", port=%d, addrlist=%p, family=%d, "
4339 "encryption=%d, blocking=%d, mode=%d)", host, port, addrlist,
4340 family, encryption, blocking, mode));
4341
4342 if (!host && mode == _HTTP_MODE_CLIENT)
4343 return (NULL);
4344
4345 httpInitialize();
4346
4347 /*
4348 * Lookup the host...
4349 */
4350
4351 if (addrlist)
4352 {
4353 myaddrlist = httpAddrCopyList(addrlist);
4354 }
4355 else
4356 {
4357 snprintf(service, sizeof(service), "%d", port);
4358
4359 myaddrlist = httpAddrGetList(host, family, service);
4360 }
4361
4362 if (!myaddrlist)
4363 return (NULL);
4364
4365 /*
4366 * Allocate memory for the structure...
4367 */
4368
4369 if ((http = calloc(sizeof(http_t), 1)) == NULL)
4370 {
4371 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
4372 httpAddrFreeList(addrlist);
4373 return (NULL);
4374 }
4375
4376 /*
4377 * Initialize the HTTP data...
4378 */
4379
4380 http->mode = mode;
4381 http->activity = time(NULL);
4382 http->addrlist = myaddrlist;
4383 http->blocking = blocking;
4384 http->fd = -1;
4385 #ifdef HAVE_GSSAPI
4386 http->gssctx = GSS_C_NO_CONTEXT;
4387 http->gssname = GSS_C_NO_NAME;
4388 #endif /* HAVE_GSSAPI */
4389 http->version = HTTP_VERSION_1_1;
4390
4391 if (host)
4392 strlcpy(http->hostname, host, sizeof(http->hostname));
4393
4394 if (port == 443) /* Always use encryption for https */
4395 http->encryption = HTTP_ENCRYPTION_ALWAYS;
4396 else
4397 http->encryption = encryption;
4398
4399 http_set_wait(http);
4400
4401 /*
4402 * Return the new structure...
4403 */
4404
4405 return (http);
4406 }
4407
4408 /* For OS X 10.8 and earlier */
4409 http_t *_httpCreate(const char *host, int port, http_addrlist_t *addrlist,
4410 http_encryption_t encryption, int family)
4411 { return (http_create(host, port, addrlist, family, encryption, 1,
4412 _HTTP_MODE_CLIENT)); }
4413
4414
4415 #ifdef DEBUG
4416 /*
4417 * 'http_debug_hex()' - Do a hex dump of a buffer.
4418 */
4419
4420 static void
4421 http_debug_hex(const char *prefix, /* I - Prefix for line */
4422 const char *buffer, /* I - Buffer to dump */
4423 int bytes) /* I - Bytes to dump */
4424 {
4425 int i, j, /* Looping vars */
4426 ch; /* Current character */
4427 char line[255], /* Line buffer */
4428 *start, /* Start of line after prefix */
4429 *ptr; /* Pointer into line */
4430
4431
4432 if (_cups_debug_fd < 0 || _cups_debug_level < 6)
4433 return;
4434
4435 DEBUG_printf(("6%s: %d bytes:", prefix, bytes));
4436
4437 snprintf(line, sizeof(line), "6%s: ", prefix);
4438 start = line + strlen(line);
4439
4440 for (i = 0; i < bytes; i += 16)
4441 {
4442 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
4443 sprintf(ptr, "%02X", buffer[i + j] & 255);
4444
4445 while (j < 16)
4446 {
4447 memcpy(ptr, " ", 3);
4448 ptr += 2;
4449 j ++;
4450 }
4451
4452 memcpy(ptr, " ", 3);
4453 ptr += 2;
4454
4455 for (j = 0; j < 16 && (i + j) < bytes; j ++)
4456 {
4457 ch = buffer[i + j] & 255;
4458
4459 if (ch < ' ' || ch >= 127)
4460 ch = '.';
4461
4462 *ptr++ = ch;
4463 }
4464
4465 *ptr = '\0';
4466 DEBUG_puts(line);
4467 }
4468 }
4469 #endif /* DEBUG */
4470
4471
4472 /*
4473 * 'http_field()' - Return the field index for a field name.
4474 */
4475
4476 static http_field_t /* O - Field index */
4477 http_field(const char *name) /* I - String name */
4478 {
4479 int i; /* Looping var */
4480
4481
4482 for (i = 0; i < HTTP_FIELD_MAX; i ++)
4483 if (_cups_strcasecmp(name, http_fields[i]) == 0)
4484 return ((http_field_t)i);
4485
4486 return (HTTP_FIELD_UNKNOWN);
4487 }
4488
4489
4490 /*
4491 * 'http_read()' - Read a buffer from a HTTP connection.
4492 *
4493 * This function does the low-level read from the socket, retrying and timing
4494 * out as needed.
4495 */
4496
4497 static ssize_t /* O - Number of bytes read or -1 on error */
4498 http_read(http_t *http, /* I - Connection to server */
4499 char *buffer, /* I - Buffer */
4500 size_t length) /* I - Maximum bytes to read */
4501 {
4502 ssize_t bytes; /* Bytes read */
4503
4504
4505 DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
4506 buffer, CUPS_LLCAST length));
4507
4508 if (!http->blocking)
4509 {
4510 while (!httpWait(http, http->wait_value))
4511 {
4512 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4513 continue;
4514
4515 DEBUG_puts("2http_read: Timeout.");
4516 return (0);
4517 }
4518 }
4519
4520 DEBUG_printf(("2http_read: Reading %d bytes into buffer.", (int)length));
4521
4522 do
4523 {
4524 #ifdef HAVE_SSL
4525 if (http->tls)
4526 bytes = http_read_ssl(http, buffer, length);
4527 else
4528 #endif /* HAVE_SSL */
4529 bytes = recv(http->fd, buffer, length, 0);
4530
4531 if (bytes < 0)
4532 {
4533 #ifdef WIN32
4534 if (WSAGetLastError() != WSAEINTR)
4535 {
4536 http->error = WSAGetLastError();
4537 return (-1);
4538 }
4539 else if (WSAGetLastError() == WSAEWOULDBLOCK)
4540 {
4541 if (!http->timeout_cb ||
4542 !(*http->timeout_cb)(http, http->timeout_data))
4543 {
4544 http->error = WSAEWOULDBLOCK;
4545 return (-1);
4546 }
4547 }
4548 #else
4549 DEBUG_printf(("2http_read: %s", strerror(errno)));
4550
4551 if (errno == EWOULDBLOCK || errno == EAGAIN)
4552 {
4553 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
4554 {
4555 http->error = errno;
4556 return (-1);
4557 }
4558 else if (!http->timeout_cb && errno != EAGAIN)
4559 {
4560 http->error = errno;
4561 return (-1);
4562 }
4563 }
4564 else if (errno != EINTR)
4565 {
4566 http->error = errno;
4567 return (-1);
4568 }
4569 #endif /* WIN32 */
4570 }
4571 }
4572 while (bytes < 0);
4573
4574 DEBUG_printf(("2http_read: Read " CUPS_LLFMT " bytes into buffer.",
4575 CUPS_LLCAST bytes));
4576 #ifdef DEBUG
4577 if (bytes > 0)
4578 http_debug_hex("http_read", http->buffer, (int)bytes);
4579 #endif /* DEBUG */
4580
4581 if (bytes < 0)
4582 {
4583 #ifdef WIN32
4584 if (WSAGetLastError() == WSAEINTR)
4585 bytes = 0;
4586 else
4587 http->error = WSAGetLastError();
4588 #else
4589 if (errno == EINTR || (errno == EAGAIN && !http->timeout_cb))
4590 bytes = 0;
4591 else
4592 http->error = errno;
4593 #endif /* WIN32 */
4594 }
4595 else if (bytes == 0)
4596 {
4597 http->error = EPIPE;
4598 return (0);
4599 }
4600
4601 return (bytes);
4602 }
4603
4604
4605 /*
4606 * 'http_read_buffered()' - Do a buffered read from a HTTP connection.
4607 *
4608 * This function reads data from the HTTP buffer or from the socket, as needed.
4609 */
4610
4611 static ssize_t /* O - Number of bytes read or -1 on error */
4612 http_read_buffered(http_t *http, /* I - Connection to server */
4613 char *buffer, /* I - Buffer */
4614 size_t length) /* I - Maximum bytes to read */
4615 {
4616 ssize_t bytes; /* Bytes read */
4617
4618
4619 DEBUG_printf(("http_read_buffered(http=%p, buffer=%p, length=" CUPS_LLFMT
4620 ") used=%d",
4621 http, buffer, CUPS_LLCAST length, http->used));
4622
4623 if (http->used > 0)
4624 {
4625 if (length > (size_t)http->used)
4626 bytes = (size_t)http->used;
4627 else
4628 bytes = length;
4629
4630 DEBUG_printf(("2http_read: Grabbing %d bytes from input buffer.",
4631 (int)bytes));
4632
4633 memcpy(buffer, http->buffer, bytes);
4634 http->used -= (int)bytes;
4635
4636 if (http->used > 0)
4637 memmove(http->buffer, http->buffer + bytes, http->used);
4638 }
4639 else
4640 bytes = http_read(http, buffer, length);
4641
4642 return (bytes);
4643 }
4644
4645
4646 /*
4647 * 'http_read_chunk()' - Read a chunk from a HTTP connection.
4648 *
4649 * This function reads and validates the chunk length, then does a buffered read
4650 * returning the number of bytes placed in the buffer.
4651 */
4652
4653 static ssize_t /* O - Number of bytes read or -1 on error */
4654 http_read_chunk(http_t *http, /* I - Connection to server */
4655 char *buffer, /* I - Buffer */
4656 size_t length) /* I - Maximum bytes to read */
4657 {
4658 DEBUG_printf(("http_read_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
4659 http, buffer, CUPS_LLCAST length));
4660
4661 if (http->data_remaining <= 0)
4662 {
4663 char len[32]; /* Length string */
4664
4665 if (!httpGets(len, sizeof(len), http))
4666 {
4667 DEBUG_puts("1http_read_chunk: Could not get chunk length.");
4668 return (0);
4669 }
4670
4671 if (!len[0])
4672 {
4673 DEBUG_puts("1http_read_chunk: Blank chunk length, trying again...");
4674 if (!httpGets(len, sizeof(len), http))
4675 {
4676 DEBUG_puts("1http_read_chunk: Could not get chunk length.");
4677 return (0);
4678 }
4679 }
4680
4681 http->data_remaining = strtoll(len, NULL, 16);
4682
4683 if (http->data_remaining < 0)
4684 {
4685 DEBUG_printf(("1http_read_chunk: Negative chunk length \"%s\" ("
4686 CUPS_LLFMT ")", len, CUPS_LLCAST http->data_remaining));
4687 return (0);
4688 }
4689
4690 DEBUG_printf(("2http_read_chunk: Got chunk length \"%s\" (" CUPS_LLFMT ")",
4691 len, CUPS_LLCAST http->data_remaining));
4692
4693 if (http->data_remaining == 0)
4694 {
4695 /*
4696 * 0-length chunk, grab trailing blank line...
4697 */
4698
4699 httpGets(len, sizeof(len), http);
4700 }
4701 }
4702
4703 DEBUG_printf(("2http_read_chunk: data_remaining=" CUPS_LLFMT,
4704 CUPS_LLCAST http->data_remaining));
4705
4706 if (http->data_remaining <= 0)
4707 return (0);
4708 else if (length > (size_t)http->data_remaining)
4709 length = (size_t)http->data_remaining;
4710
4711 return (http_read_buffered(http, buffer, length));
4712 }
4713
4714
4715 #ifdef HAVE_SSL
4716 /*
4717 * 'http_read_ssl()' - Read from a SSL/TLS connection.
4718 */
4719
4720 static int /* O - Bytes read */
4721 http_read_ssl(http_t *http, /* I - Connection to server */
4722 char *buf, /* I - Buffer to store data */
4723 int len) /* I - Length of buffer */
4724 {
4725 # if defined(HAVE_LIBSSL)
4726 return (SSL_read((SSL *)(http->tls), buf, len));
4727
4728 # elif defined(HAVE_GNUTLS)
4729 ssize_t result; /* Return value */
4730
4731
4732 result = gnutls_record_recv(http->tls, buf, len);
4733
4734 if (result < 0 && !errno)
4735 {
4736 /*
4737 * Convert GNU TLS error to errno value...
4738 */
4739
4740 switch (result)
4741 {
4742 case GNUTLS_E_INTERRUPTED :
4743 errno = EINTR;
4744 break;
4745
4746 case GNUTLS_E_AGAIN :
4747 errno = EAGAIN;
4748 break;
4749
4750 default :
4751 errno = EPIPE;
4752 break;
4753 }
4754
4755 result = -1;
4756 }
4757
4758 return ((int)result);
4759
4760 # elif defined(HAVE_CDSASSL)
4761 int result; /* Return value */
4762 OSStatus error; /* Error info */
4763 size_t processed; /* Number of bytes processed */
4764
4765
4766 error = SSLRead(http->tls, buf, len, &processed);
4767 DEBUG_printf(("6http_read_ssl: error=%d, processed=%d", (int)error,
4768 (int)processed));
4769 switch (error)
4770 {
4771 case 0 :
4772 result = (int)processed;
4773 break;
4774
4775 case errSSLWouldBlock :
4776 if (processed)
4777 result = (int)processed;
4778 else
4779 {
4780 result = -1;
4781 errno = EINTR;
4782 }
4783 break;
4784
4785 case errSSLClosedGraceful :
4786 default :
4787 if (processed)
4788 result = (int)processed;
4789 else
4790 {
4791 result = -1;
4792 errno = EPIPE;
4793 }
4794 break;
4795 }
4796
4797 return (result);
4798
4799 # elif defined(HAVE_SSPISSL)
4800 return _sspiRead((_sspi_struct_t*) http->tls, buf, len);
4801 # endif /* HAVE_LIBSSL */
4802 }
4803 #endif /* HAVE_SSL */
4804
4805
4806 /*
4807 * 'http_send()' - Send a request with all fields and the trailing blank line.
4808 */
4809
4810 static int /* O - 0 on success, non-zero on error */
4811 http_send(http_t *http, /* I - Connection to server */
4812 http_state_t request, /* I - Request code */
4813 const char *uri) /* I - URI */
4814 {
4815 int i; /* Looping var */
4816 char buf[1024]; /* Encoded URI buffer */
4817 const char *value; /* Field value */
4818 static const char * const codes[] = /* Request code strings */
4819 {
4820 NULL,
4821 "OPTIONS",
4822 "GET",
4823 NULL,
4824 "HEAD",
4825 "POST",
4826 NULL,
4827 NULL,
4828 "PUT",
4829 NULL,
4830 "DELETE",
4831 "TRACE",
4832 "CLOSE",
4833 NULL,
4834 NULL
4835 };
4836
4837
4838 DEBUG_printf(("7http_send(http=%p, request=HTTP_%s, uri=\"%s\")",
4839 http, codes[request], uri));
4840
4841 if (http == NULL || uri == NULL)
4842 return (-1);
4843
4844 /*
4845 * Set the User-Agent field if it isn't already...
4846 */
4847
4848 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
4849 {
4850 if (http->default_user_agent)
4851 httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_user_agent);
4852 else
4853 httpSetField(http, HTTP_FIELD_USER_AGENT, cupsUserAgent());
4854 }
4855
4856 /*
4857 * Set the Accept-Encoding field if it isn't already...
4858 */
4859
4860 if (!http->accept_encoding && http->default_accept_encoding)
4861 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
4862 http->default_accept_encoding);
4863
4864 /*
4865 * Encode the URI as needed...
4866 */
4867
4868 _httpEncodeURI(buf, uri, sizeof(buf));
4869
4870 /*
4871 * See if we had an error the last time around; if so, reconnect...
4872 */
4873
4874 if (http->fd < 0 || http->status == HTTP_ERROR ||
4875 http->status >= HTTP_BAD_REQUEST)
4876 if (httpReconnect(http))
4877 return (-1);
4878
4879 /*
4880 * Flush any written data that is pending...
4881 */
4882
4883 if (http->wused)
4884 {
4885 if (httpFlushWrite(http) < 0)
4886 if (httpReconnect(http))
4887 return (-1);
4888 }
4889
4890 /*
4891 * Send the request header...
4892 */
4893
4894 http->state = request;
4895 http->data_encoding = HTTP_ENCODING_FIELDS;
4896
4897 if (request == HTTP_POST || request == HTTP_PUT)
4898 http->state ++;
4899
4900 http->status = HTTP_CONTINUE;
4901
4902 #ifdef HAVE_SSL
4903 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
4904 {
4905 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
4906 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
4907 }
4908 #endif /* HAVE_SSL */
4909
4910 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
4911 {
4912 http->status = HTTP_ERROR;
4913 return (-1);
4914 }
4915
4916 for (i = 0; i < HTTP_FIELD_MAX; i ++)
4917 if ((value = httpGetField(http, i)) != NULL && *value)
4918 {
4919 DEBUG_printf(("9http_send: %s: %s", http_fields[i], value));
4920
4921 if (i == HTTP_FIELD_HOST)
4922 {
4923 if (httpPrintf(http, "Host: %s:%d\r\n", value,
4924 httpAddrPort(http->hostaddr)) < 1)
4925 {
4926 http->status = HTTP_ERROR;
4927 return (-1);
4928 }
4929 }
4930 else if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1)
4931 {
4932 http->status = HTTP_ERROR;
4933 return (-1);
4934 }
4935 }
4936
4937 if (http->cookie)
4938 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
4939 {
4940 http->status = HTTP_ERROR;
4941 return (-1);
4942 }
4943
4944 if (http->expect == HTTP_CONTINUE && http->mode == _HTTP_MODE_CLIENT &&
4945 (http->state == HTTP_STATE_POST_RECV || http->state == HTTP_PUT_RECV))
4946 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
4947 {
4948 http->status = HTTP_ERROR;
4949 return (-1);
4950 }
4951
4952 if (httpPrintf(http, "\r\n") < 1)
4953 {
4954 http->status = HTTP_ERROR;
4955 return (-1);
4956 }
4957
4958 if (httpFlushWrite(http) < 0)
4959 return (-1);
4960
4961 http_set_length(http);
4962 httpClearFields(http);
4963
4964 /*
4965 * The Kerberos and AuthRef authentication strings can only be used once...
4966 */
4967
4968 if (http->field_authorization && http->authstring &&
4969 (!strncmp(http->authstring, "Negotiate", 9) ||
4970 !strncmp(http->authstring, "AuthRef", 7)))
4971 {
4972 http->_authstring[0] = '\0';
4973
4974 if (http->authstring != http->_authstring)
4975 free(http->authstring);
4976
4977 http->authstring = http->_authstring;
4978 }
4979
4980 return (0);
4981 }
4982
4983
4984 #ifdef HAVE_SSL
4985 # if defined(HAVE_CDSASSL)
4986 /*
4987 * 'http_set_credentials()' - Set the SSL/TLS credentials.
4988 */
4989
4990 static int /* O - Status of connection */
4991 http_set_credentials(http_t *http) /* I - Connection to server */
4992 {
4993 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
4994 OSStatus error = 0; /* Error code */
4995 http_tls_credentials_t credentials = NULL;
4996 /* TLS credentials */
4997
4998
4999 DEBUG_printf(("7http_set_credentials(%p)", http));
5000
5001 /*
5002 * Prefer connection specific credentials...
5003 */
5004
5005 if ((credentials = http->tls_credentials) == NULL)
5006 credentials = cg->tls_credentials;
5007
5008 if (credentials)
5009 {
5010 error = SSLSetCertificate(http->tls, credentials);
5011 DEBUG_printf(("4http_set_credentials: SSLSetCertificate, error=%d",
5012 (int)error));
5013 }
5014 else
5015 DEBUG_puts("4http_set_credentials: No credentials to set.");
5016
5017 return (error);
5018 }
5019 # endif /* HAVE_CDSASSL */
5020 #endif /* HAVE_SSL */
5021
5022
5023 /*
5024 * 'http_set_length()' - Set the data_encoding and data_remaining values.
5025 */
5026
5027 static off_t /* O - Remainder or -1 on error */
5028 http_set_length(http_t *http) /* I - Connection */
5029 {
5030 off_t remaining; /* Remainder */
5031
5032
5033 DEBUG_printf(("http_set_length(http=%p) mode=%d state=%s", http, http->mode,
5034 http_states[http->state + 1]));
5035
5036 if ((remaining = httpGetLength2(http)) >= 0)
5037 {
5038 if (http->mode == _HTTP_MODE_SERVER &&
5039 http->state != HTTP_STATE_GET_SEND &&
5040 http->state != HTTP_STATE_PUT &&
5041 http->state != HTTP_STATE_POST &&
5042 http->state != HTTP_STATE_POST_SEND)
5043 {
5044 DEBUG_puts("1http_set_length: Not setting data_encoding/remaining.");
5045 return (remaining);
5046 }
5047
5048 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING],
5049 "chunked"))
5050 {
5051 DEBUG_puts("1http_set_length: Setting data_encoding to "
5052 "HTTP_ENCODING_CHUNKED.");
5053 http->data_encoding = HTTP_ENCODING_CHUNKED;
5054 }
5055 else
5056 {
5057 DEBUG_puts("1http_set_length: Setting data_encoding to "
5058 "HTTP_ENCODING_LENGTH.");
5059 http->data_encoding = HTTP_ENCODING_LENGTH;
5060 }
5061
5062 DEBUG_printf(("1http_set_length: Setting data_remaining to " CUPS_LLFMT ".",
5063 CUPS_LLCAST remaining));
5064 http->data_remaining = remaining;
5065
5066 if (remaining <= INT_MAX)
5067 http->_data_remaining = remaining;
5068 else
5069 http->_data_remaining = INT_MAX;
5070 }
5071
5072 return (remaining);
5073 }
5074
5075 /*
5076 * 'http_set_timeout()' - Set the socket timeout values.
5077 */
5078
5079 static void
5080 http_set_timeout(int fd, /* I - File descriptor */
5081 double timeout) /* I - Timeout in seconds */
5082 {
5083 #ifdef WIN32
5084 DWORD tv = (DWORD)(timeout * 1000);
5085 /* Timeout in milliseconds */
5086
5087 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5088 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5089
5090 #else
5091 struct timeval tv; /* Timeout in secs and usecs */
5092
5093 tv.tv_sec = (int)timeout;
5094 tv.tv_usec = (int)(1000000 * fmod(timeout, 1.0));
5095
5096 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5097 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5098 #endif /* WIN32 */
5099 }
5100
5101
5102 /*
5103 * 'http_set_wait()' - Set the default wait value for reads.
5104 */
5105
5106 static void
5107 http_set_wait(http_t *http) /* I - Connection to server */
5108 {
5109 if (http->blocking)
5110 {
5111 http->wait_value = (int)(http->timeout_value * 1000);
5112
5113 if (http->wait_value <= 0)
5114 http->wait_value = 60000;
5115 }
5116 else
5117 http->wait_value = 10000;
5118 }
5119
5120
5121 #ifdef HAVE_SSL
5122 /*
5123 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
5124 */
5125
5126 static int /* O - 0 on success, -1 on failure */
5127 http_setup_ssl(http_t *http) /* I - Connection to server */
5128 {
5129 char hostname[256], /* Hostname */
5130 *hostptr; /* Pointer into hostname */
5131
5132 # ifdef HAVE_LIBSSL
5133 SSL_CTX *context; /* Context for encryption */
5134 BIO *bio; /* BIO data */
5135 const char *message = NULL;/* Error message */
5136 # elif defined(HAVE_GNUTLS)
5137 int status; /* Status of handshake */
5138 gnutls_certificate_client_credentials *credentials;
5139 /* TLS credentials */
5140 # elif defined(HAVE_CDSASSL)
5141 _cups_globals_t *cg = _cupsGlobals();
5142 /* Pointer to library globals */
5143 OSStatus error; /* Error code */
5144 const char *message = NULL;/* Error message */
5145 cups_array_t *credentials; /* Credentials array */
5146 cups_array_t *names; /* CUPS distinguished names */
5147 CFArrayRef dn_array; /* CF distinguished names array */
5148 CFIndex count; /* Number of credentials */
5149 CFDataRef data; /* Certificate data */
5150 int i; /* Looping var */
5151 http_credential_t *credential; /* Credential data */
5152 # elif defined(HAVE_SSPISSL)
5153 TCHAR username[256]; /* Username returned from GetUserName() */
5154 TCHAR commonName[256];/* Common name for certificate */
5155 DWORD dwSize; /* 32 bit size */
5156 # endif /* HAVE_LIBSSL */
5157
5158
5159 DEBUG_printf(("7http_setup_ssl(http=%p)", http));
5160
5161 /*
5162 * Get the hostname to use for SSL...
5163 */
5164
5165 if (httpAddrLocalhost(http->hostaddr))
5166 {
5167 strlcpy(hostname, "localhost", sizeof(hostname));
5168 }
5169 else
5170 {
5171 /*
5172 * Otherwise make sure the hostname we have does not end in a trailing dot.
5173 */
5174
5175 strlcpy(hostname, http->hostname, sizeof(hostname));
5176 if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
5177 *hostptr == '.')
5178 *hostptr = '\0';
5179 }
5180
5181 # ifdef HAVE_LIBSSL
5182 context = SSL_CTX_new(SSLv23_client_method());
5183
5184 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
5185
5186 bio = BIO_new(_httpBIOMethods());
5187 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
5188
5189 http->tls = SSL_new(context);
5190 SSL_set_bio(http->tls, bio, bio);
5191
5192 # ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
5193 SSL_set_tlsext_host_name(http->tls, hostname);
5194 # endif /* HAVE_SSL_SET_TLSEXT_HOST_NAME */
5195
5196 if (SSL_connect(http->tls) != 1)
5197 {
5198 unsigned long error; /* Error code */
5199
5200 while ((error = ERR_get_error()) != 0)
5201 {
5202 message = ERR_error_string(error, NULL);
5203 DEBUG_printf(("8http_setup_ssl: %s", message));
5204 }
5205
5206 SSL_CTX_free(context);
5207 SSL_free(http->tls);
5208 http->tls = NULL;
5209
5210 # ifdef WIN32
5211 http->error = WSAGetLastError();
5212 # else
5213 http->error = errno;
5214 # endif /* WIN32 */
5215 http->status = HTTP_ERROR;
5216
5217 if (!message)
5218 message = _("Unable to establish a secure connection to host.");
5219
5220 _cupsSetError(IPP_PKI_ERROR, message, 1);
5221
5222 return (-1);
5223 }
5224
5225 # elif defined(HAVE_GNUTLS)
5226 credentials = (gnutls_certificate_client_credentials *)
5227 malloc(sizeof(gnutls_certificate_client_credentials));
5228 if (credentials == NULL)
5229 {
5230 DEBUG_printf(("8http_setup_ssl: Unable to allocate credentials: %s",
5231 strerror(errno)));
5232 http->error = errno;
5233 http->status = HTTP_ERROR;
5234 _cupsSetHTTPError(HTTP_ERROR);
5235
5236 return (-1);
5237 }
5238
5239 gnutls_certificate_allocate_credentials(credentials);
5240
5241 gnutls_init(&http->tls, GNUTLS_CLIENT);
5242 gnutls_set_default_priority(http->tls);
5243 gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname,
5244 strlen(hostname));
5245 gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);
5246 gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr)http);
5247 gnutls_transport_set_pull_function(http->tls, _httpReadGNUTLS);
5248 gnutls_transport_set_push_function(http->tls, _httpWriteGNUTLS);
5249
5250 while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
5251 {
5252 DEBUG_printf(("8http_setup_ssl: gnutls_handshake returned %d (%s)",
5253 status, gnutls_strerror(status)));
5254
5255 if (gnutls_error_is_fatal(status))
5256 {
5257 http->error = EIO;
5258 http->status = HTTP_ERROR;
5259
5260 _cupsSetError(IPP_PKI_ERROR, gnutls_strerror(status), 0);
5261
5262 gnutls_deinit(http->tls);
5263 gnutls_certificate_free_credentials(*credentials);
5264 free(credentials);
5265 http->tls = NULL;
5266
5267 return (-1);
5268 }
5269 }
5270
5271 http->tls_credentials = credentials;
5272
5273 # elif defined(HAVE_CDSASSL)
5274 if ((http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide,
5275 kSSLStreamType)) == NULL)
5276 {
5277 DEBUG_puts("4http_setup_ssl: SSLCreateContext failed.");
5278 http->error = errno = ENOMEM;
5279 http->status = HTTP_ERROR;
5280 _cupsSetHTTPError(HTTP_ERROR);
5281
5282 return (-1);
5283 }
5284
5285 error = SSLSetConnection(http->tls, http);
5286 DEBUG_printf(("4http_setup_ssl: SSLSetConnection, error=%d", (int)error));
5287
5288 if (!error)
5289 {
5290 error = SSLSetIOFuncs(http->tls, _httpReadCDSA, _httpWriteCDSA);
5291 DEBUG_printf(("4http_setup_ssl: SSLSetIOFuncs, error=%d", (int)error));
5292 }
5293
5294 if (!error)
5295 {
5296 error = SSLSetSessionOption(http->tls, kSSLSessionOptionBreakOnServerAuth,
5297 true);
5298 DEBUG_printf(("4http_setup_ssl: SSLSetSessionOption, error=%d",
5299 (int)error));
5300 }
5301
5302 if (!error)
5303 {
5304 if (cg->client_cert_cb)
5305 {
5306 error = SSLSetSessionOption(http->tls,
5307 kSSLSessionOptionBreakOnCertRequested, true);
5308 DEBUG_printf(("4http_setup_ssl: kSSLSessionOptionBreakOnCertRequested, "
5309 "error=%d", (int)error));
5310 }
5311 else
5312 {
5313 error = http_set_credentials(http);
5314 DEBUG_printf(("4http_setup_ssl: http_set_credentials, error=%d",
5315 (int)error));
5316 }
5317 }
5318
5319 /*
5320 * Let the server know which hostname/domain we are trying to connect to
5321 * in case it wants to serve up a certificate with a matching common name.
5322 */
5323
5324 if (!error)
5325 {
5326 error = SSLSetPeerDomainName(http->tls, hostname, strlen(hostname));
5327
5328 DEBUG_printf(("4http_setup_ssl: SSLSetPeerDomainName, error=%d",
5329 (int)error));
5330 }
5331
5332 if (!error)
5333 {
5334 int done = 0; /* Are we done yet? */
5335
5336 while (!error && !done)
5337 {
5338 error = SSLHandshake(http->tls);
5339
5340 DEBUG_printf(("4http_setup_ssl: SSLHandshake returned %d.", (int)error));
5341
5342 switch (error)
5343 {
5344 case noErr :
5345 done = 1;
5346 break;
5347
5348 case errSSLWouldBlock :
5349 error = noErr; /* Force a retry */
5350 usleep(1000); /* in 1 millisecond */
5351 break;
5352
5353 case errSSLServerAuthCompleted :
5354 error = 0;
5355 if (cg->server_cert_cb)
5356 {
5357 error = httpCopyCredentials(http, &credentials);
5358 if (!error)
5359 {
5360 error = (cg->server_cert_cb)(http, http->tls, credentials,
5361 cg->server_cert_data);
5362 httpFreeCredentials(credentials);
5363 }
5364
5365 DEBUG_printf(("4http_setup_ssl: Server certificate callback "
5366 "returned %d.", (int)error));
5367 }
5368 break;
5369
5370 case errSSLClientCertRequested :
5371 error = 0;
5372
5373 if (cg->client_cert_cb)
5374 {
5375 names = NULL;
5376 if (!(error = SSLCopyDistinguishedNames(http->tls, &dn_array)) &&
5377 dn_array)
5378 {
5379 if ((names = cupsArrayNew(NULL, NULL)) != NULL)
5380 {
5381 for (i = 0, count = CFArrayGetCount(dn_array); i < count; i++)
5382 {
5383 data = (CFDataRef)CFArrayGetValueAtIndex(dn_array, i);
5384
5385 if ((credential = malloc(sizeof(*credential))) != NULL)
5386 {
5387 credential->datalen = CFDataGetLength(data);
5388 if ((credential->data = malloc(credential->datalen)))
5389 {
5390 memcpy((void *)credential->data, CFDataGetBytePtr(data),
5391 credential->datalen);
5392 cupsArrayAdd(names, credential);
5393 }
5394 else
5395 free(credential);
5396 }
5397 }
5398 }
5399
5400 CFRelease(dn_array);
5401 }
5402
5403 if (!error)
5404 {
5405 error = (cg->client_cert_cb)(http, http->tls, names,
5406 cg->client_cert_data);
5407
5408 DEBUG_printf(("4http_setup_ssl: Client certificate callback "
5409 "returned %d.", (int)error));
5410 }
5411
5412 httpFreeCredentials(names);
5413 }
5414 break;
5415
5416 case errSSLUnknownRootCert :
5417 message = _("Unable to establish a secure connection to host "
5418 "(untrusted certificate).");
5419 break;
5420
5421 case errSSLNoRootCert :
5422 message = _("Unable to establish a secure connection to host "
5423 "(self-signed certificate).");
5424 break;
5425
5426 case errSSLCertExpired :
5427 message = _("Unable to establish a secure connection to host "
5428 "(expired certificate).");
5429 break;
5430
5431 case errSSLCertNotYetValid :
5432 message = _("Unable to establish a secure connection to host "
5433 "(certificate not yet valid).");
5434 break;
5435
5436 case errSSLHostNameMismatch :
5437 message = _("Unable to establish a secure connection to host "
5438 "(host name mismatch).");
5439 break;
5440
5441 case errSSLXCertChainInvalid :
5442 message = _("Unable to establish a secure connection to host "
5443 "(certificate chain invalid).");
5444 break;
5445
5446 case errSSLConnectionRefused :
5447 message = _("Unable to establish a secure connection to host "
5448 "(peer dropped connection before responding).");
5449 break;
5450
5451 default :
5452 break;
5453 }
5454 }
5455 }
5456
5457 if (error)
5458 {
5459 http->error = error;
5460 http->status = HTTP_ERROR;
5461 errno = ECONNREFUSED;
5462
5463 CFRelease(http->tls);
5464 http->tls = NULL;
5465
5466 /*
5467 * If an error string wasn't set by the callbacks use a generic one...
5468 */
5469
5470 if (!message)
5471 #ifdef HAVE_CSSMERRORSTRING
5472 message = cssmErrorString(error);
5473 #else
5474 message = _("Unable to establish a secure connection to host.");
5475 #endif /* HAVE_CSSMERRORSTRING */
5476
5477 _cupsSetError(IPP_PKI_ERROR, message, 1);
5478
5479 return (-1);
5480 }
5481
5482 # elif defined(HAVE_SSPISSL)
5483 http->tls = _sspiAlloc();
5484
5485 if (!http->tls)
5486 {
5487 _cupsSetHTTPError(HTTP_ERROR);
5488 return (-1);
5489 }
5490
5491 http->tls->sock = http->fd;
5492 dwSize = sizeof(username) / sizeof(TCHAR);
5493 GetUserName(username, &dwSize);
5494 _sntprintf_s(commonName, sizeof(commonName) / sizeof(TCHAR),
5495 sizeof(commonName) / sizeof(TCHAR), TEXT("CN=%s"), username);
5496
5497 if (!_sspiGetCredentials(http->tls_credentials, L"ClientContainer",
5498 commonName, FALSE))
5499 {
5500 _sspiFree(http->tls_credentials);
5501 http->tls_credentials = NULL;
5502
5503 http->error = EIO;
5504 http->status = HTTP_ERROR;
5505
5506 _cupsSetError(IPP_PKI_ERROR,
5507 _("Unable to establish a secure connection to host."), 1);
5508
5509 return (-1);
5510 }
5511
5512 _sspiSetAllowsAnyRoot(http->tls_credentials, TRUE);
5513 _sspiSetAllowsExpiredCerts(http->tls_credentials, TRUE);
5514
5515 if (!_sspiConnect(http->tls_credentials, hostname))
5516 {
5517 _sspiFree(http->tls_credentials);
5518 http->tls_credentials = NULL;
5519
5520 http->error = EIO;
5521 http->status = HTTP_ERROR;
5522
5523 _cupsSetError(IPP_PKI_ERROR,
5524 _("Unable to establish a secure connection to host."), 1);
5525
5526 return (-1);
5527 }
5528 # endif /* HAVE_CDSASSL */
5529
5530 return (0);
5531 }
5532
5533
5534 /*
5535 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
5536 */
5537
5538 static void
5539 http_shutdown_ssl(http_t *http) /* I - Connection to server */
5540 {
5541 # ifdef HAVE_LIBSSL
5542 SSL_CTX *context; /* Context for encryption */
5543
5544 context = SSL_get_SSL_CTX(http->tls);
5545
5546 SSL_shutdown(http->tls);
5547 SSL_CTX_free(context);
5548 SSL_free(http->tls);
5549
5550 # elif defined(HAVE_GNUTLS)
5551 gnutls_certificate_client_credentials *credentials;
5552 /* TLS credentials */
5553
5554 credentials = (gnutls_certificate_client_credentials *)(http->tls_credentials);
5555
5556 gnutls_bye(http->tls, GNUTLS_SHUT_RDWR);
5557 gnutls_deinit(http->tls);
5558 gnutls_certificate_free_credentials(*credentials);
5559 free(credentials);
5560
5561 # elif defined(HAVE_CDSASSL)
5562 while (SSLClose(http->tls) == errSSLWouldBlock)
5563 usleep(1000);
5564
5565 CFRelease(http->tls);
5566
5567 if (http->tls_credentials)
5568 CFRelease(http->tls_credentials);
5569
5570 # elif defined(HAVE_SSPISSL)
5571 _sspiFree(http->tls_credentials);
5572 # endif /* HAVE_LIBSSL */
5573
5574 http->tls = NULL;
5575 http->tls_credentials = NULL;
5576 }
5577 #endif /* HAVE_SSL */
5578
5579
5580 #ifdef HAVE_SSL
5581 /*
5582 * 'http_upgrade()' - Force upgrade to TLS encryption.
5583 */
5584
5585 static int /* O - Status of connection */
5586 http_upgrade(http_t *http) /* I - Connection to server */
5587 {
5588 int ret; /* Return value */
5589 http_t myhttp; /* Local copy of HTTP data */
5590
5591
5592 DEBUG_printf(("7http_upgrade(%p)", http));
5593
5594 /*
5595 * Flush the connection to make sure any previous "Upgrade" message
5596 * has been read.
5597 */
5598
5599 httpFlush(http);
5600
5601 /*
5602 * Copy the HTTP data to a local variable so we can do the OPTIONS
5603 * request without interfering with the existing request data...
5604 */
5605
5606 memcpy(&myhttp, http, sizeof(myhttp));
5607
5608 /*
5609 * Send an OPTIONS request to the server, requiring SSL or TLS
5610 * encryption on the link...
5611 */
5612
5613 http->field_authorization = NULL; /* Don't free the auth string */
5614
5615 httpClearFields(http);
5616 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
5617 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
5618
5619 if ((ret = httpOptions(http, "*")) == 0)
5620 {
5621 /*
5622 * Wait for the secure connection...
5623 */
5624
5625 while (httpUpdate(http) == HTTP_CONTINUE);
5626 }
5627
5628 /*
5629 * Restore the HTTP request data...
5630 */
5631
5632 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
5633 http->data_encoding = myhttp.data_encoding;
5634 http->data_remaining = myhttp.data_remaining;
5635 http->_data_remaining = myhttp._data_remaining;
5636 http->expect = myhttp.expect;
5637 http->field_authorization = myhttp.field_authorization;
5638 http->digest_tries = myhttp.digest_tries;
5639
5640 /*
5641 * See if we actually went secure...
5642 */
5643
5644 if (!http->tls)
5645 {
5646 /*
5647 * Server does not support HTTP upgrade...
5648 */
5649
5650 DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
5651
5652 # ifdef WIN32
5653 closesocket(http->fd);
5654 # else
5655 close(http->fd);
5656 # endif
5657
5658 http->fd = -1;
5659
5660 return (-1);
5661 }
5662 else
5663 return (ret);
5664 }
5665 #endif /* HAVE_SSL */
5666
5667
5668 /*
5669 * 'http_write()' - Write a buffer to a HTTP connection.
5670 */
5671
5672 static ssize_t /* O - Number of bytes written */
5673 http_write(http_t *http, /* I - Connection to server */
5674 const char *buffer, /* I - Buffer for data */
5675 size_t length) /* I - Number of bytes to write */
5676 {
5677 ssize_t tbytes, /* Total bytes sent */
5678 bytes; /* Bytes sent */
5679
5680
5681 DEBUG_printf(("2http_write(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
5682 buffer, CUPS_LLCAST length));
5683 http->error = 0;
5684 tbytes = 0;
5685
5686 while (length > 0)
5687 {
5688 DEBUG_printf(("3http_write: About to write %d bytes.", (int)length));
5689
5690 if (http->timeout_cb)
5691 {
5692 #ifdef HAVE_POLL
5693 struct pollfd pfd; /* Polled file descriptor */
5694 #else
5695 fd_set output_set; /* Output ready for write? */
5696 struct timeval timeout; /* Timeout value */
5697 #endif /* HAVE_POLL */
5698 int nfds; /* Result from select()/poll() */
5699
5700 do
5701 {
5702 #ifdef HAVE_POLL
5703 pfd.fd = http->fd;
5704 pfd.events = POLLOUT;
5705
5706 while ((nfds = poll(&pfd, 1, http->wait_value)) < 0 &&
5707 (errno == EINTR || errno == EAGAIN))
5708 /* do nothing */;
5709
5710 #else
5711 do
5712 {
5713 FD_ZERO(&output_set);
5714 FD_SET(http->fd, &output_set);
5715
5716 timeout.tv_sec = http->wait_value / 1000;
5717 timeout.tv_usec = 1000 * (http->wait_value % 1000);
5718
5719 nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout);
5720 }
5721 # ifdef WIN32
5722 while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
5723 WSAGetLastError() == WSAEWOULDBLOCK));
5724 # else
5725 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
5726 # endif /* WIN32 */
5727 #endif /* HAVE_POLL */
5728
5729 if (nfds < 0)
5730 {
5731 http->error = errno;
5732 return (-1);
5733 }
5734 else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data))
5735 {
5736 #ifdef WIN32
5737 http->error = WSAEWOULDBLOCK;
5738 #else
5739 http->error = EWOULDBLOCK;
5740 #endif /* WIN32 */
5741 return (-1);
5742 }
5743 }
5744 while (nfds <= 0);
5745 }
5746
5747 #ifdef HAVE_SSL
5748 if (http->tls)
5749 bytes = http_write_ssl(http, buffer, length);
5750 else
5751 #endif /* HAVE_SSL */
5752 bytes = send(http->fd, buffer, length, 0);
5753
5754 DEBUG_printf(("3http_write: Write of " CUPS_LLFMT " bytes returned "
5755 CUPS_LLFMT ".", CUPS_LLCAST length, CUPS_LLCAST bytes));
5756
5757 if (bytes < 0)
5758 {
5759 #ifdef WIN32
5760 if (WSAGetLastError() == WSAEINTR)
5761 continue;
5762 else if (WSAGetLastError() == WSAEWOULDBLOCK)
5763 {
5764 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
5765 continue;
5766
5767 http->error = WSAGetLastError();
5768 }
5769 else if (WSAGetLastError() != http->error &&
5770 WSAGetLastError() != WSAECONNRESET)
5771 {
5772 http->error = WSAGetLastError();
5773 continue;
5774 }
5775
5776 #else
5777 if (errno == EINTR)
5778 continue;
5779 else if (errno == EWOULDBLOCK || errno == EAGAIN)
5780 {
5781 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
5782 continue;
5783 else if (!http->timeout_cb && errno == EAGAIN)
5784 continue;
5785
5786 http->error = errno;
5787 }
5788 else if (errno != http->error && errno != ECONNRESET)
5789 {
5790 http->error = errno;
5791 continue;
5792 }
5793 #endif /* WIN32 */
5794
5795 DEBUG_printf(("3http_write: error writing data (%s).",
5796 strerror(http->error)));
5797
5798 return (-1);
5799 }
5800
5801 buffer += bytes;
5802 tbytes += bytes;
5803 length -= bytes;
5804 }
5805
5806 #ifdef DEBUG
5807 http_debug_hex("http_write", buffer - tbytes, tbytes);
5808 #endif /* DEBUG */
5809
5810 DEBUG_printf(("3http_write: Returning " CUPS_LLFMT ".", CUPS_LLCAST tbytes));
5811
5812 return (tbytes);
5813 }
5814
5815
5816 /*
5817 * 'http_write_chunk()' - Write a chunked buffer.
5818 */
5819
5820 static ssize_t /* O - Number bytes written */
5821 http_write_chunk(http_t *http, /* I - Connection to server */
5822 const char *buffer, /* I - Buffer to write */
5823 size_t length) /* I - Length of buffer */
5824 {
5825 char header[16]; /* Chunk header */
5826 ssize_t bytes; /* Bytes written */
5827
5828
5829 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
5830 http, buffer, CUPS_LLCAST length));
5831
5832 /*
5833 * Write the chunk header, data, and trailer.
5834 */
5835
5836 snprintf(header, sizeof(header), "%x\r\n", (unsigned)length);
5837 if (http_write(http, header, strlen(header)) < 0)
5838 {
5839 DEBUG_puts("8http_write_chunk: http_write of length failed.");
5840 return (-1);
5841 }
5842
5843 if ((bytes = http_write(http, buffer, length)) < 0)
5844 {
5845 DEBUG_puts("8http_write_chunk: http_write of buffer failed.");
5846 return (-1);
5847 }
5848
5849 if (http_write(http, "\r\n", 2) < 0)
5850 {
5851 DEBUG_puts("8http_write_chunk: http_write of CR LF failed.");
5852 return (-1);
5853 }
5854
5855 return (bytes);
5856 }
5857
5858
5859 #ifdef HAVE_SSL
5860 /*
5861 * 'http_write_ssl()' - Write to a SSL/TLS connection.
5862 */
5863
5864 static int /* O - Bytes written */
5865 http_write_ssl(http_t *http, /* I - Connection to server */
5866 const char *buf, /* I - Buffer holding data */
5867 int len) /* I - Length of buffer */
5868 {
5869 ssize_t result; /* Return value */
5870
5871
5872 DEBUG_printf(("2http_write_ssl(http=%p, buf=%p, len=%d)", http, buf, len));
5873
5874 # if defined(HAVE_LIBSSL)
5875 result = SSL_write((SSL *)(http->tls), buf, len);
5876
5877 # elif defined(HAVE_GNUTLS)
5878 result = gnutls_record_send(http->tls, buf, len);
5879
5880 if (result < 0 && !errno)
5881 {
5882 /*
5883 * Convert GNU TLS error to errno value...
5884 */
5885
5886 switch (result)
5887 {
5888 case GNUTLS_E_INTERRUPTED :
5889 errno = EINTR;
5890 break;
5891
5892 case GNUTLS_E_AGAIN :
5893 errno = EAGAIN;
5894 break;
5895
5896 default :
5897 errno = EPIPE;
5898 break;
5899 }
5900
5901 result = -1;
5902 }
5903
5904 # elif defined(HAVE_CDSASSL)
5905 OSStatus error; /* Error info */
5906 size_t processed; /* Number of bytes processed */
5907
5908
5909 error = SSLWrite(http->tls, buf, len, &processed);
5910
5911 switch (error)
5912 {
5913 case 0 :
5914 result = (int)processed;
5915 break;
5916
5917 case errSSLWouldBlock :
5918 if (processed)
5919 result = (int)processed;
5920 else
5921 {
5922 result = -1;
5923 errno = EINTR;
5924 }
5925 break;
5926
5927 case errSSLClosedGraceful :
5928 default :
5929 if (processed)
5930 result = (int)processed;
5931 else
5932 {
5933 result = -1;
5934 errno = EPIPE;
5935 }
5936 break;
5937 }
5938 # elif defined(HAVE_SSPISSL)
5939 return _sspiWrite((_sspi_struct_t *)http->tls, (void *)buf, len);
5940 # endif /* HAVE_LIBSSL */
5941
5942 DEBUG_printf(("3http_write_ssl: Returning %d.", (int)result));
5943
5944 return ((int)result);
5945 }
5946 #endif /* HAVE_SSL */
5947
5948
5949 /*
5950 * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
5951 */