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