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