]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Save work on cupsd - almost there...
[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 {
3954 if (!http->fields[HTTP_FIELD_CONNECTION][0])
3955 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
3956
3957 if (!http->fields[HTTP_FIELD_UPGRADE][0])
3958 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
3959 }
3960 #endif /* HAVE_SSL */
3961
3962 if (!http->server)
3963 httpSetField(http, HTTP_FIELD_SERVER,
3964 http->default_server ? http->default_server : CUPS_MINIMAL);
3965
3966 /*
3967 * Set the Accept-Encoding field if it isn't already...
3968 */
3969
3970 if (!http->accept_encoding)
3971 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
3972 http->default_accept_encoding ? http->default_accept_encoding :
3973 #ifdef HAVE_LIBZ
3974 "gzip, deflate, identity");
3975 #else
3976 "identity");
3977 #endif /* HAVE_LIBZ */
3978
3979 /*
3980 * Send the response header...
3981 */
3982
3983 old_encoding = http->data_encoding;
3984 old_remaining = http->data_remaining;
3985 http->data_encoding = HTTP_ENCODING_FIELDS;
3986
3987 if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100,
3988 http->version % 100, (int)status, httpStatus(status)) < 0)
3989 {
3990 http->status = HTTP_STATUS_ERROR;
3991 return (-1);
3992 }
3993
3994 if (status != HTTP_STATUS_CONTINUE)
3995 {
3996 /*
3997 * 100 Continue doesn't have the rest of the response headers...
3998 */
3999
4000 int i; /* Looping var */
4001 const char *value; /* Field value */
4002
4003 for (i = 0; i < HTTP_FIELD_MAX; i ++)
4004 {
4005 if ((value = httpGetField(http, i)) != NULL && *value)
4006 {
4007 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1)
4008 {
4009 http->status = HTTP_STATUS_ERROR;
4010 return (-1);
4011 }
4012 }
4013 }
4014
4015 if (http->cookie)
4016 {
4017 if (httpPrintf(http, "Set-Cookie: %s path=/%s\r\n", http->cookie,
4018 http->tls ? " secure" : "") < 1)
4019 {
4020 http->status = HTTP_STATUS_ERROR;
4021 return (-1);
4022 }
4023 }
4024 }
4025
4026 if (httpWrite2(http, "\r\n", 2) < 2)
4027 {
4028 http->status = HTTP_STATUS_ERROR;
4029 return (-1);
4030 }
4031
4032 if (httpFlushWrite(http) < 0)
4033 {
4034 http->status = HTTP_STATUS_ERROR;
4035 return (-1);
4036 }
4037
4038 if (status == HTTP_STATUS_CONTINUE)
4039 {
4040 /*
4041 * Restore the old data_encoding and data_length values...
4042 */
4043
4044 http->data_encoding = old_encoding;
4045 http->data_remaining = old_remaining;
4046
4047 if (old_remaining <= INT_MAX)
4048 http->_data_remaining = (int)old_remaining;
4049 else
4050 http->_data_remaining = INT_MAX;
4051 }
4052 else if (http->state == HTTP_STATE_OPTIONS ||
4053 http->state == HTTP_STATE_HEAD ||
4054 http->state == HTTP_STATE_PUT ||
4055 http->state == HTTP_STATE_TRACE ||
4056 http->state == HTTP_STATE_CONNECT ||
4057 http->state == HTTP_STATE_STATUS)
4058 {
4059 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, "
4060 "was %s.", httpStateString(http->state)));
4061 http->state = HTTP_STATE_WAITING;
4062 }
4063 else
4064 {
4065 /*
4066 * Force data_encoding and data_length to be set according to the response
4067 * headers...
4068 */
4069
4070 http_set_length(http);
4071
4072 #ifdef HAVE_LIBZ
4073 /*
4074 * Then start any content encoding...
4075 */
4076
4077 DEBUG_puts("1httpWriteResponse: Calling http_content_coding_start.");
4078 http_content_coding_start(http,
4079 httpGetField(http, HTTP_FIELD_CONTENT_ENCODING));
4080 #endif /* HAVE_LIBZ */
4081 }
4082
4083 return (0);
4084 }
4085
4086
4087 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
4088 /*
4089 * 'http_bio_ctrl()' - Control the HTTP connection.
4090 */
4091
4092 static long /* O - Result/data */
4093 http_bio_ctrl(BIO *h, /* I - BIO data */
4094 int cmd, /* I - Control command */
4095 long arg1, /* I - First argument */
4096 void *arg2) /* I - Second argument */
4097 {
4098 switch (cmd)
4099 {
4100 default :
4101 return (0);
4102
4103 case BIO_CTRL_RESET :
4104 h->ptr = NULL;
4105 return (0);
4106
4107 case BIO_C_SET_FILE_PTR :
4108 h->ptr = arg2;
4109 h->init = 1;
4110 return (1);
4111
4112 case BIO_C_GET_FILE_PTR :
4113 if (arg2)
4114 {
4115 *((void **)arg2) = h->ptr;
4116 return (1);
4117 }
4118 else
4119 return (0);
4120
4121 case BIO_CTRL_DUP :
4122 case BIO_CTRL_FLUSH :
4123 return (1);
4124 }
4125 }
4126
4127
4128 /*
4129 * 'http_bio_free()' - Free OpenSSL data.
4130 */
4131
4132 static int /* O - 1 on success, 0 on failure */
4133 http_bio_free(BIO *h) /* I - BIO data */
4134 {
4135 if (!h)
4136 return (0);
4137
4138 if (h->shutdown)
4139 {
4140 h->init = 0;
4141 h->flags = 0;
4142 }
4143
4144 return (1);
4145 }
4146
4147
4148 /*
4149 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
4150 */
4151
4152 static int /* O - 1 on success, 0 on failure */
4153 http_bio_new(BIO *h) /* I - BIO data */
4154 {
4155 if (!h)
4156 return (0);
4157
4158 h->init = 0;
4159 h->num = 0;
4160 h->ptr = NULL;
4161 h->flags = 0;
4162
4163 return (1);
4164 }
4165
4166
4167 /*
4168 * 'http_bio_puts()' - Send a string for OpenSSL.
4169 */
4170
4171 static int /* O - Bytes written */
4172 http_bio_puts(BIO *h, /* I - BIO data */
4173 const char *str) /* I - String to write */
4174 {
4175 #ifdef WIN32
4176 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
4177 #else
4178 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
4179 #endif /* WIN32 */
4180 }
4181
4182
4183 /*
4184 * 'http_bio_read()' - Read data for OpenSSL.
4185 */
4186
4187 static int /* O - Bytes read */
4188 http_bio_read(BIO *h, /* I - BIO data */
4189 char *buf, /* I - Buffer */
4190 int size) /* I - Number of bytes to read */
4191 {
4192 http_t *http; /* HTTP connection */
4193
4194
4195 http = (http_t *)h->ptr;
4196
4197 if (!http->blocking)
4198 {
4199 /*
4200 * Make sure we have data before we read...
4201 */
4202
4203 while (!_httpWait(http, http->wait_value, 0))
4204 {
4205 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4206 continue;
4207
4208 #ifdef WIN32
4209 http->error = WSAETIMEDOUT;
4210 #else
4211 http->error = ETIMEDOUT;
4212 #endif /* WIN32 */
4213
4214 return (-1);
4215 }
4216 }
4217
4218 return (recv(http->fd, buf, size, 0));
4219 }
4220
4221
4222 /*
4223 * 'http_bio_write()' - Write data for OpenSSL.
4224 */
4225
4226 static int /* O - Bytes written */
4227 http_bio_write(BIO *h, /* I - BIO data */
4228 const char *buf, /* I - Buffer to write */
4229 int num) /* I - Number of bytes to write */
4230 {
4231 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
4232 }
4233 #endif /* HAVE_SSL && HAVE_LIBSSL */
4234
4235
4236 #ifdef HAVE_LIBZ
4237 /*
4238 * 'http_content_coding_finish()' - Finish doing any content encoding.
4239 */
4240
4241 static void
4242 http_content_coding_finish(
4243 http_t *http) /* I - HTTP connection */
4244 {
4245 int zerr; /* Compression status */
4246
4247
4248 switch (http->coding)
4249 {
4250 case _HTTP_CODING_DEFLATE :
4251 case _HTTP_CODING_GZIP :
4252 do
4253 {
4254 http->stream.next_out = (Bytef *)http->wbuffer + http->wused;
4255 http->stream.avail_out = sizeof(http->wbuffer) - http->wused;
4256
4257 zerr = deflate(&(http->stream), Z_FINISH);
4258
4259 http->wused = sizeof(http->wbuffer) - http->stream.avail_out;
4260 if (http->wused == sizeof(http->wbuffer))
4261 httpFlushWrite(http);
4262 }
4263 while (zerr == Z_OK);
4264
4265 deflateEnd(&(http->stream));
4266
4267 if (http->wused)
4268 httpFlushWrite(http);
4269 break;
4270
4271 case _HTTP_CODING_INFLATE :
4272 case _HTTP_CODING_GUNZIP :
4273 inflateEnd(&(http->stream));
4274 free(http->dbuffer);
4275 http->dbuffer = NULL;
4276 break;
4277
4278 default :
4279 break;
4280 }
4281
4282 http->coding = _HTTP_CODING_IDENTITY;
4283 }
4284
4285
4286 /*
4287 * 'http_content_coding_start()' - Start doing content encoding.
4288 */
4289
4290 static void
4291 http_content_coding_start(
4292 http_t *http, /* I - HTTP connection */
4293 const char *value) /* I - Value of Content-Encoding */
4294 {
4295 int zerr; /* Error/status */
4296 _http_coding_t coding; /* Content coding value */
4297
4298
4299 DEBUG_printf(("http_content_coding_start(http=%p, value=\"%s\")", http,
4300 value));
4301
4302 if (http->coding != _HTTP_CODING_IDENTITY)
4303 {
4304 DEBUG_printf(("1http_content_coding_start: http->coding already %d.",
4305 http->coding));
4306 return;
4307 }
4308 else if (!strcmp(value, "x-gzip") || !strcmp(value, "gzip"))
4309 {
4310 if (http->state == HTTP_STATE_GET_SEND ||
4311 http->state == HTTP_STATE_POST_SEND)
4312 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_GZIP :
4313 _HTTP_CODING_GUNZIP;
4314 else if (http->state == HTTP_STATE_POST_RECV ||
4315 http->state == HTTP_STATE_PUT_RECV)
4316 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_GZIP :
4317 _HTTP_CODING_GUNZIP;
4318 else
4319 {
4320 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4321 return;
4322 }
4323 }
4324 else if (!strcmp(value, "x-deflate") || !strcmp(value, "deflate"))
4325 {
4326 if (http->state == HTTP_STATE_GET_SEND ||
4327 http->state == HTTP_STATE_POST_SEND)
4328 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_DEFLATE :
4329 _HTTP_CODING_INFLATE;
4330 else if (http->state == HTTP_STATE_POST_RECV ||
4331 http->state == HTTP_STATE_PUT_RECV)
4332 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_DEFLATE :
4333 _HTTP_CODING_INFLATE;
4334 else
4335 {
4336 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4337 return;
4338 }
4339 }
4340 else
4341 {
4342 DEBUG_puts("1http_content_coding_start: Not doing content coding.");
4343 return;
4344 }
4345
4346 memset(&(http->stream), 0, sizeof(http->stream));
4347
4348 switch (coding)
4349 {
4350 case _HTTP_CODING_DEFLATE :
4351 case _HTTP_CODING_GZIP :
4352 if (http->wused)
4353 httpFlushWrite(http);
4354
4355 /*
4356 * Window size for compression is 11 bits - optimal based on PWG Raster
4357 * sample files on pwg.org. -11 is raw deflate, 27 is gzip, per ZLIB
4358 * documentation.
4359 */
4360
4361 if ((zerr = deflateInit2(&(http->stream), Z_DEFAULT_COMPRESSION,
4362 Z_DEFLATED,
4363 coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7,
4364 Z_DEFAULT_STRATEGY)) < Z_OK)
4365 {
4366 http->status = HTTP_STATUS_ERROR;
4367 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
4368 return;
4369 }
4370 break;
4371
4372 case _HTTP_CODING_INFLATE :
4373 case _HTTP_CODING_GUNZIP :
4374 if ((http->dbuffer = malloc(HTTP_MAX_BUFFER)) == NULL)
4375 {
4376 http->status = HTTP_STATUS_ERROR;
4377 http->error = errno;
4378 return;
4379 }
4380
4381 /*
4382 * Window size for decompression is up to 15 bits (maximum supported).
4383 * -15 is raw inflate, 31 is gunzip, per ZLIB documentation.
4384 */
4385
4386 if ((zerr = inflateInit2(&(http->stream),
4387 coding == _HTTP_CODING_INFLATE ? -15 : 31))
4388 < Z_OK)
4389 {
4390 free(http->dbuffer);
4391 http->dbuffer = NULL;
4392 http->status = HTTP_STATUS_ERROR;
4393 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
4394 return;
4395 }
4396
4397 http->stream.avail_in = 0;
4398 http->stream.next_in = http->dbuffer;
4399 break;
4400
4401 default :
4402 break;
4403 }
4404
4405 http->coding = coding;
4406
4407 DEBUG_printf(("1http_content_coding_start: http->coding now %d.",
4408 http->coding));
4409 }
4410 #endif /* HAVE_LIBZ */
4411
4412
4413 /*
4414 * 'http_create()' - Create an unconnected HTTP connection.
4415 */
4416
4417 static http_t * /* O - HTTP connection */
4418 http_create(
4419 const char *host, /* I - Hostname */
4420 int port, /* I - Port number */
4421 http_addrlist_t *addrlist, /* I - Address list or NULL */
4422 int family, /* I - Address family or AF_UNSPEC */
4423 http_encryption_t encryption, /* I - Encryption to use */
4424 int blocking, /* I - 1 for blocking mode */
4425 _http_mode_t mode) /* I - _HTTP_MODE_CLIENT or _SERVER */
4426 {
4427 http_t *http; /* New HTTP connection */
4428 char service[255]; /* Service name */
4429 http_addrlist_t *myaddrlist = NULL; /* My address list */
4430
4431
4432 DEBUG_printf(("4http_create(host=\"%s\", port=%d, addrlist=%p, family=%d, "
4433 "encryption=%d, blocking=%d, mode=%d)", host, port, addrlist,
4434 family, encryption, blocking, mode));
4435
4436 if (!host && mode == _HTTP_MODE_CLIENT)
4437 return (NULL);
4438
4439 httpInitialize();
4440
4441 /*
4442 * Lookup the host...
4443 */
4444
4445 if (addrlist)
4446 {
4447 myaddrlist = httpAddrCopyList(addrlist);
4448 }
4449 else
4450 {
4451 snprintf(service, sizeof(service), "%d", port);
4452
4453 myaddrlist = httpAddrGetList(host, family, service);
4454 }
4455
4456 if (!myaddrlist)
4457 return (NULL);
4458
4459 /*
4460 * Allocate memory for the structure...
4461 */
4462
4463 if ((http = calloc(sizeof(http_t), 1)) == NULL)
4464 {
4465 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
4466 httpAddrFreeList(addrlist);
4467 return (NULL);
4468 }
4469
4470 /*
4471 * Initialize the HTTP data...
4472 */
4473
4474 http->mode = mode;
4475 http->activity = time(NULL);
4476 http->addrlist = myaddrlist;
4477 http->blocking = blocking;
4478 http->fd = -1;
4479 #ifdef HAVE_GSSAPI
4480 http->gssctx = GSS_C_NO_CONTEXT;
4481 http->gssname = GSS_C_NO_NAME;
4482 #endif /* HAVE_GSSAPI */
4483 http->status = HTTP_STATUS_CONTINUE;
4484 http->version = HTTP_VERSION_1_1;
4485
4486 if (host)
4487 strlcpy(http->hostname, host, sizeof(http->hostname));
4488
4489 if (port == 443) /* Always use encryption for https */
4490 http->encryption = HTTP_ENCRYPTION_ALWAYS;
4491 else
4492 http->encryption = encryption;
4493
4494 http_set_wait(http);
4495
4496 /*
4497 * Return the new structure...
4498 */
4499
4500 return (http);
4501 }
4502
4503 /* For OS X 10.8 and earlier */
4504 http_t *_httpCreate(const char *host, int port, http_addrlist_t *addrlist,
4505 http_encryption_t encryption, int family)
4506 { return (http_create(host, port, addrlist, family, encryption, 1,
4507 _HTTP_MODE_CLIENT)); }
4508
4509
4510 #ifdef DEBUG
4511 /*
4512 * 'http_debug_hex()' - Do a hex dump of a buffer.
4513 */
4514
4515 static void
4516 http_debug_hex(const char *prefix, /* I - Prefix for line */
4517 const char *buffer, /* I - Buffer to dump */
4518 int bytes) /* I - Bytes to dump */
4519 {
4520 int i, j, /* Looping vars */
4521 ch; /* Current character */
4522 char line[255], /* Line buffer */
4523 *start, /* Start of line after prefix */
4524 *ptr; /* Pointer into line */
4525
4526
4527 if (_cups_debug_fd < 0 || _cups_debug_level < 6)
4528 return;
4529
4530 DEBUG_printf(("6%s: %d bytes:", prefix, bytes));
4531
4532 snprintf(line, sizeof(line), "6%s: ", prefix);
4533 start = line + strlen(line);
4534
4535 for (i = 0; i < bytes; i += 16)
4536 {
4537 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
4538 sprintf(ptr, "%02X", buffer[i + j] & 255);
4539
4540 while (j < 16)
4541 {
4542 memcpy(ptr, " ", 3);
4543 ptr += 2;
4544 j ++;
4545 }
4546
4547 memcpy(ptr, " ", 3);
4548 ptr += 2;
4549
4550 for (j = 0; j < 16 && (i + j) < bytes; j ++)
4551 {
4552 ch = buffer[i + j] & 255;
4553
4554 if (ch < ' ' || ch >= 127)
4555 ch = '.';
4556
4557 *ptr++ = ch;
4558 }
4559
4560 *ptr = '\0';
4561 DEBUG_puts(line);
4562 }
4563 }
4564 #endif /* DEBUG */
4565
4566
4567 /*
4568 * 'http_read()' - Read a buffer from a HTTP connection.
4569 *
4570 * This function does the low-level read from the socket, retrying and timing
4571 * out as needed.
4572 */
4573
4574 static ssize_t /* O - Number of bytes read or -1 on error */
4575 http_read(http_t *http, /* I - HTTP connection */
4576 char *buffer, /* I - Buffer */
4577 size_t length) /* I - Maximum bytes to read */
4578 {
4579 ssize_t bytes; /* Bytes read */
4580
4581
4582 DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
4583 buffer, CUPS_LLCAST length));
4584
4585 if (!http->blocking)
4586 {
4587 while (!httpWait(http, http->wait_value))
4588 {
4589 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4590 continue;
4591
4592 DEBUG_puts("2http_read: Timeout.");
4593 return (0);
4594 }
4595 }
4596
4597 DEBUG_printf(("2http_read: Reading %d bytes into buffer.", (int)length));
4598
4599 do
4600 {
4601 #ifdef HAVE_SSL
4602 if (http->tls)
4603 bytes = http_read_ssl(http, buffer, length);
4604 else
4605 #endif /* HAVE_SSL */
4606 bytes = recv(http->fd, buffer, length, 0);
4607
4608 if (bytes < 0)
4609 {
4610 #ifdef WIN32
4611 if (WSAGetLastError() != WSAEINTR)
4612 {
4613 http->error = WSAGetLastError();
4614 return (-1);
4615 }
4616 else if (WSAGetLastError() == WSAEWOULDBLOCK)
4617 {
4618 if (!http->timeout_cb ||
4619 !(*http->timeout_cb)(http, http->timeout_data))
4620 {
4621 http->error = WSAEWOULDBLOCK;
4622 return (-1);
4623 }
4624 }
4625 #else
4626 DEBUG_printf(("2http_read: %s", strerror(errno)));
4627
4628 if (errno == EWOULDBLOCK || errno == EAGAIN)
4629 {
4630 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
4631 {
4632 http->error = errno;
4633 return (-1);
4634 }
4635 else if (!http->timeout_cb && errno != EAGAIN)
4636 {
4637 http->error = errno;
4638 return (-1);
4639 }
4640 }
4641 else if (errno != EINTR)
4642 {
4643 http->error = errno;
4644 return (-1);
4645 }
4646 #endif /* WIN32 */
4647 }
4648 }
4649 while (bytes < 0);
4650
4651 DEBUG_printf(("2http_read: Read " CUPS_LLFMT " bytes into buffer.",
4652 CUPS_LLCAST bytes));
4653 #ifdef DEBUG
4654 if (bytes > 0)
4655 http_debug_hex("http_read", buffer, (int)bytes);
4656 #endif /* DEBUG */
4657
4658 if (bytes < 0)
4659 {
4660 #ifdef WIN32
4661 if (WSAGetLastError() == WSAEINTR)
4662 bytes = 0;
4663 else
4664 http->error = WSAGetLastError();
4665 #else
4666 if (errno == EINTR || (errno == EAGAIN && !http->timeout_cb))
4667 bytes = 0;
4668 else
4669 http->error = errno;
4670 #endif /* WIN32 */
4671 }
4672 else if (bytes == 0)
4673 {
4674 http->error = EPIPE;
4675 return (0);
4676 }
4677
4678 return (bytes);
4679 }
4680
4681
4682 /*
4683 * 'http_read_buffered()' - Do a buffered read from a HTTP connection.
4684 *
4685 * This function reads data from the HTTP buffer or from the socket, as needed.
4686 */
4687
4688 static ssize_t /* O - Number of bytes read or -1 on error */
4689 http_read_buffered(http_t *http, /* I - HTTP connection */
4690 char *buffer, /* I - Buffer */
4691 size_t length) /* I - Maximum bytes to read */
4692 {
4693 ssize_t bytes; /* Bytes read */
4694
4695
4696 DEBUG_printf(("http_read_buffered(http=%p, buffer=%p, length=" CUPS_LLFMT
4697 ") used=%d",
4698 http, buffer, CUPS_LLCAST length, http->used));
4699
4700 if (http->used > 0)
4701 {
4702 if (length > (size_t)http->used)
4703 bytes = (size_t)http->used;
4704 else
4705 bytes = length;
4706
4707 DEBUG_printf(("2http_read: Grabbing %d bytes from input buffer.",
4708 (int)bytes));
4709
4710 memcpy(buffer, http->buffer, bytes);
4711 http->used -= (int)bytes;
4712
4713 if (http->used > 0)
4714 memmove(http->buffer, http->buffer + bytes, http->used);
4715 }
4716 else
4717 bytes = http_read(http, buffer, length);
4718
4719 return (bytes);
4720 }
4721
4722
4723 /*
4724 * 'http_read_chunk()' - Read a chunk from a HTTP connection.
4725 *
4726 * This function reads and validates the chunk length, then does a buffered read
4727 * returning the number of bytes placed in the buffer.
4728 */
4729
4730 static ssize_t /* O - Number of bytes read or -1 on error */
4731 http_read_chunk(http_t *http, /* I - HTTP connection */
4732 char *buffer, /* I - Buffer */
4733 size_t length) /* I - Maximum bytes to read */
4734 {
4735 DEBUG_printf(("http_read_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
4736 http, buffer, CUPS_LLCAST length));
4737
4738 if (http->data_remaining <= 0)
4739 {
4740 char len[32]; /* Length string */
4741
4742 if (!httpGets(len, sizeof(len), http))
4743 {
4744 DEBUG_puts("1http_read_chunk: Could not get chunk length.");
4745 return (0);
4746 }
4747
4748 if (!len[0])
4749 {
4750 DEBUG_puts("1http_read_chunk: Blank chunk length, trying again...");
4751 if (!httpGets(len, sizeof(len), http))
4752 {
4753 DEBUG_puts("1http_read_chunk: Could not get chunk length.");
4754 return (0);
4755 }
4756 }
4757
4758 http->data_remaining = strtoll(len, NULL, 16);
4759
4760 if (http->data_remaining < 0)
4761 {
4762 DEBUG_printf(("1http_read_chunk: Negative chunk length \"%s\" ("
4763 CUPS_LLFMT ")", len, CUPS_LLCAST http->data_remaining));
4764 return (0);
4765 }
4766
4767 DEBUG_printf(("2http_read_chunk: Got chunk length \"%s\" (" CUPS_LLFMT ")",
4768 len, CUPS_LLCAST http->data_remaining));
4769
4770 if (http->data_remaining == 0)
4771 {
4772 /*
4773 * 0-length chunk, grab trailing blank line...
4774 */
4775
4776 httpGets(len, sizeof(len), http);
4777 }
4778 }
4779
4780 DEBUG_printf(("2http_read_chunk: data_remaining=" CUPS_LLFMT,
4781 CUPS_LLCAST http->data_remaining));
4782
4783 if (http->data_remaining <= 0)
4784 return (0);
4785 else if (length > (size_t)http->data_remaining)
4786 length = (size_t)http->data_remaining;
4787
4788 return (http_read_buffered(http, buffer, length));
4789 }
4790
4791
4792 #ifdef HAVE_SSL
4793 /*
4794 * 'http_read_ssl()' - Read from a SSL/TLS connection.
4795 */
4796
4797 static int /* O - Bytes read */
4798 http_read_ssl(http_t *http, /* I - HTTP connection */
4799 char *buf, /* I - Buffer to store data */
4800 int len) /* I - Length of buffer */
4801 {
4802 # if defined(HAVE_LIBSSL)
4803 return (SSL_read((SSL *)(http->tls), buf, len));
4804
4805 # elif defined(HAVE_GNUTLS)
4806 ssize_t result; /* Return value */
4807
4808
4809 result = gnutls_record_recv(http->tls, buf, len);
4810
4811 if (result < 0 && !errno)
4812 {
4813 /*
4814 * Convert GNU TLS error to errno value...
4815 */
4816
4817 switch (result)
4818 {
4819 case GNUTLS_E_INTERRUPTED :
4820 errno = EINTR;
4821 break;
4822
4823 case GNUTLS_E_AGAIN :
4824 errno = EAGAIN;
4825 break;
4826
4827 default :
4828 errno = EPIPE;
4829 break;
4830 }
4831
4832 result = -1;
4833 }
4834
4835 return ((int)result);
4836
4837 # elif defined(HAVE_CDSASSL)
4838 int result; /* Return value */
4839 OSStatus error; /* Error info */
4840 size_t processed; /* Number of bytes processed */
4841
4842
4843 error = SSLRead(http->tls, buf, len, &processed);
4844 DEBUG_printf(("6http_read_ssl: error=%d, processed=%d", (int)error,
4845 (int)processed));
4846 switch (error)
4847 {
4848 case 0 :
4849 result = (int)processed;
4850 break;
4851
4852 case errSSLWouldBlock :
4853 if (processed)
4854 result = (int)processed;
4855 else
4856 {
4857 result = -1;
4858 errno = EINTR;
4859 }
4860 break;
4861
4862 case errSSLClosedGraceful :
4863 default :
4864 if (processed)
4865 result = (int)processed;
4866 else
4867 {
4868 result = -1;
4869 errno = EPIPE;
4870 }
4871 break;
4872 }
4873
4874 return (result);
4875
4876 # elif defined(HAVE_SSPISSL)
4877 return _sspiRead((_sspi_struct_t*) http->tls, buf, len);
4878 # endif /* HAVE_LIBSSL */
4879 }
4880 #endif /* HAVE_SSL */
4881
4882
4883 /*
4884 * 'http_send()' - Send a request with all fields and the trailing blank line.
4885 */
4886
4887 static int /* O - 0 on success, non-zero on error */
4888 http_send(http_t *http, /* I - HTTP connection */
4889 http_state_t request, /* I - Request code */
4890 const char *uri) /* I - URI */
4891 {
4892 int i; /* Looping var */
4893 char buf[1024]; /* Encoded URI buffer */
4894 const char *value; /* Field value */
4895 static const char * const codes[] = /* Request code strings */
4896 {
4897 NULL,
4898 "OPTIONS",
4899 "GET",
4900 NULL,
4901 "HEAD",
4902 "POST",
4903 NULL,
4904 NULL,
4905 "PUT",
4906 NULL,
4907 "DELETE",
4908 "TRACE",
4909 "CLOSE",
4910 NULL,
4911 NULL
4912 };
4913
4914
4915 DEBUG_printf(("4http_send(http=%p, request=HTTP_%s, uri=\"%s\")",
4916 http, codes[request], uri));
4917
4918 if (http == NULL || uri == NULL)
4919 return (-1);
4920
4921 /*
4922 * Set the User-Agent field if it isn't already...
4923 */
4924
4925 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
4926 {
4927 if (http->default_user_agent)
4928 httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_user_agent);
4929 else
4930 httpSetField(http, HTTP_FIELD_USER_AGENT, cupsUserAgent());
4931 }
4932
4933 /*
4934 * Set the Accept-Encoding field if it isn't already...
4935 */
4936
4937 if (!http->accept_encoding && http->default_accept_encoding)
4938 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
4939 http->default_accept_encoding);
4940
4941 /*
4942 * Encode the URI as needed...
4943 */
4944
4945 _httpEncodeURI(buf, uri, sizeof(buf));
4946
4947 /*
4948 * See if we had an error the last time around; if so, reconnect...
4949 */
4950
4951 if (http->fd < 0 || http->status == HTTP_STATUS_ERROR ||
4952 http->status >= HTTP_STATUS_BAD_REQUEST)
4953 {
4954 DEBUG_printf(("5http_send: Reconnecting, fd=%d, status=%d, tls_upgrade=%d",
4955 http->fd, http->status, http->tls_upgrade));
4956
4957 if (httpReconnect2(http, 30000, NULL))
4958 return (-1);
4959 }
4960
4961 /*
4962 * Flush any written data that is pending...
4963 */
4964
4965 if (http->wused)
4966 {
4967 if (httpFlushWrite(http) < 0)
4968 if (httpReconnect2(http, 30000, NULL))
4969 return (-1);
4970 }
4971
4972 /*
4973 * Send the request header...
4974 */
4975
4976 http->state = request;
4977 http->data_encoding = HTTP_ENCODING_FIELDS;
4978
4979 if (request == HTTP_STATE_POST || request == HTTP_STATE_PUT)
4980 http->state ++;
4981
4982 http->status = HTTP_STATUS_CONTINUE;
4983
4984 #ifdef HAVE_SSL
4985 if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls)
4986 {
4987 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
4988 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
4989 }
4990 #endif /* HAVE_SSL */
4991
4992 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
4993 {
4994 http->status = HTTP_STATUS_ERROR;
4995 return (-1);
4996 }
4997
4998 for (i = 0; i < HTTP_FIELD_MAX; i ++)
4999 if ((value = httpGetField(http, i)) != NULL && *value)
5000 {
5001 DEBUG_printf(("5http_send: %s: %s", http_fields[i], value));
5002
5003 if (i == HTTP_FIELD_HOST)
5004 {
5005 if (httpPrintf(http, "Host: %s:%d\r\n", value,
5006 httpAddrPort(http->hostaddr)) < 1)
5007 {
5008 http->status = HTTP_STATUS_ERROR;
5009 return (-1);
5010 }
5011 }
5012 else if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1)
5013 {
5014 http->status = HTTP_STATUS_ERROR;
5015 return (-1);
5016 }
5017 }
5018
5019 if (http->cookie)
5020 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
5021 {
5022 http->status = HTTP_STATUS_ERROR;
5023 return (-1);
5024 }
5025
5026 DEBUG_printf(("5http_send: expect=%d, mode=%d, state=%d", http->expect,
5027 http->mode, http->state));
5028
5029 if (http->expect == HTTP_STATUS_CONTINUE && http->mode == _HTTP_MODE_CLIENT &&
5030 (http->state == HTTP_STATE_POST_RECV ||
5031 http->state == HTTP_STATE_PUT_RECV))
5032 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
5033 {
5034 http->status = HTTP_STATUS_ERROR;
5035 return (-1);
5036 }
5037
5038 if (httpPrintf(http, "\r\n") < 1)
5039 {
5040 http->status = HTTP_STATUS_ERROR;
5041 return (-1);
5042 }
5043
5044 if (httpFlushWrite(http) < 0)
5045 return (-1);
5046
5047 http_set_length(http);
5048 httpClearFields(http);
5049
5050 /*
5051 * The Kerberos and AuthRef authentication strings can only be used once...
5052 */
5053
5054 if (http->field_authorization && http->authstring &&
5055 (!strncmp(http->authstring, "Negotiate", 9) ||
5056 !strncmp(http->authstring, "AuthRef", 7)))
5057 {
5058 http->_authstring[0] = '\0';
5059
5060 if (http->authstring != http->_authstring)
5061 free(http->authstring);
5062
5063 http->authstring = http->_authstring;
5064 }
5065
5066 return (0);
5067 }
5068
5069
5070 #ifdef HAVE_SSL
5071 # if defined(HAVE_CDSASSL)
5072 /*
5073 * 'http_set_credentials()' - Set the SSL/TLS credentials.
5074 */
5075
5076 static int /* O - Status of connection */
5077 http_set_credentials(http_t *http) /* I - HTTP connection */
5078 {
5079 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
5080 OSStatus error = 0; /* Error code */
5081 http_tls_credentials_t credentials = NULL;
5082 /* TLS credentials */
5083
5084
5085 DEBUG_printf(("7http_set_credentials(%p)", http));
5086
5087 /*
5088 * Prefer connection specific credentials...
5089 */
5090
5091 if ((credentials = http->tls_credentials) == NULL)
5092 credentials = cg->tls_credentials;
5093
5094 if (credentials)
5095 {
5096 error = SSLSetCertificate(http->tls, credentials);
5097 DEBUG_printf(("4http_set_credentials: SSLSetCertificate, error=%d",
5098 (int)error));
5099 }
5100 else
5101 DEBUG_puts("4http_set_credentials: No credentials to set.");
5102
5103 return (error);
5104 }
5105 # endif /* HAVE_CDSASSL */
5106 #endif /* HAVE_SSL */
5107
5108
5109 /*
5110 * 'http_set_length()' - Set the data_encoding and data_remaining values.
5111 */
5112
5113 static off_t /* O - Remainder or -1 on error */
5114 http_set_length(http_t *http) /* I - Connection */
5115 {
5116 off_t remaining; /* Remainder */
5117
5118
5119 DEBUG_printf(("http_set_length(http=%p) mode=%d state=%s", http, http->mode,
5120 httpStateString(http->state)));
5121
5122 if ((remaining = httpGetLength2(http)) >= 0)
5123 {
5124 if (http->mode == _HTTP_MODE_SERVER &&
5125 http->state != HTTP_STATE_GET_SEND &&
5126 http->state != HTTP_STATE_PUT &&
5127 http->state != HTTP_STATE_POST &&
5128 http->state != HTTP_STATE_POST_SEND)
5129 {
5130 DEBUG_puts("1http_set_length: Not setting data_encoding/remaining.");
5131 return (remaining);
5132 }
5133
5134 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING],
5135 "chunked"))
5136 {
5137 DEBUG_puts("1http_set_length: Setting data_encoding to "
5138 "HTTP_ENCODING_CHUNKED.");
5139 http->data_encoding = HTTP_ENCODING_CHUNKED;
5140 }
5141 else
5142 {
5143 DEBUG_puts("1http_set_length: Setting data_encoding to "
5144 "HTTP_ENCODING_LENGTH.");
5145 http->data_encoding = HTTP_ENCODING_LENGTH;
5146 }
5147
5148 DEBUG_printf(("1http_set_length: Setting data_remaining to " CUPS_LLFMT ".",
5149 CUPS_LLCAST remaining));
5150 http->data_remaining = remaining;
5151
5152 if (remaining <= INT_MAX)
5153 http->_data_remaining = remaining;
5154 else
5155 http->_data_remaining = INT_MAX;
5156 }
5157
5158 return (remaining);
5159 }
5160
5161 /*
5162 * 'http_set_timeout()' - Set the socket timeout values.
5163 */
5164
5165 static void
5166 http_set_timeout(int fd, /* I - File descriptor */
5167 double timeout) /* I - Timeout in seconds */
5168 {
5169 #ifdef WIN32
5170 DWORD tv = (DWORD)(timeout * 1000);
5171 /* Timeout in milliseconds */
5172
5173 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5174 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5175
5176 #else
5177 struct timeval tv; /* Timeout in secs and usecs */
5178
5179 tv.tv_sec = (int)timeout;
5180 tv.tv_usec = (int)(1000000 * fmod(timeout, 1.0));
5181
5182 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5183 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv));
5184 #endif /* WIN32 */
5185 }
5186
5187
5188 /*
5189 * 'http_set_wait()' - Set the default wait value for reads.
5190 */
5191
5192 static void
5193 http_set_wait(http_t *http) /* I - HTTP connection */
5194 {
5195 if (http->blocking)
5196 {
5197 http->wait_value = (int)(http->timeout_value * 1000);
5198
5199 if (http->wait_value <= 0)
5200 http->wait_value = 60000;
5201 }
5202 else
5203 http->wait_value = 10000;
5204 }
5205
5206
5207 #ifdef HAVE_SSL
5208 /*
5209 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
5210 */
5211
5212 static int /* O - 0 on success, -1 on failure */
5213 http_setup_ssl(http_t *http) /* I - HTTP connection */
5214 {
5215 char hostname[256], /* Hostname */
5216 *hostptr; /* Pointer into hostname */
5217
5218 # ifdef HAVE_LIBSSL
5219 SSL_CTX *context; /* Context for encryption */
5220 BIO *bio; /* BIO data */
5221 const char *message = NULL;/* Error message */
5222 # elif defined(HAVE_GNUTLS)
5223 int status; /* Status of handshake */
5224 gnutls_certificate_client_credentials *credentials;
5225 /* TLS credentials */
5226 # elif defined(HAVE_CDSASSL)
5227 _cups_globals_t *cg = _cupsGlobals();
5228 /* Pointer to library globals */
5229 OSStatus error; /* Error code */
5230 const char *message = NULL;/* Error message */
5231 cups_array_t *credentials; /* Credentials array */
5232 cups_array_t *names; /* CUPS distinguished names */
5233 CFArrayRef dn_array; /* CF distinguished names array */
5234 CFIndex count; /* Number of credentials */
5235 CFDataRef data; /* Certificate data */
5236 int i; /* Looping var */
5237 http_credential_t *credential; /* Credential data */
5238 # elif defined(HAVE_SSPISSL)
5239 TCHAR username[256]; /* Username returned from GetUserName() */
5240 TCHAR commonName[256];/* Common name for certificate */
5241 DWORD dwSize; /* 32 bit size */
5242 # endif /* HAVE_LIBSSL */
5243
5244
5245 DEBUG_printf(("7http_setup_ssl(http=%p)", http));
5246
5247 /*
5248 * Get the hostname to use for SSL...
5249 */
5250
5251 if (httpAddrLocalhost(http->hostaddr))
5252 {
5253 strlcpy(hostname, "localhost", sizeof(hostname));
5254 }
5255 else
5256 {
5257 /*
5258 * Otherwise make sure the hostname we have does not end in a trailing dot.
5259 */
5260
5261 strlcpy(hostname, http->hostname, sizeof(hostname));
5262 if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
5263 *hostptr == '.')
5264 *hostptr = '\0';
5265 }
5266
5267 # ifdef HAVE_LIBSSL
5268 context = SSL_CTX_new(SSLv23_client_method());
5269
5270 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
5271
5272 bio = BIO_new(_httpBIOMethods());
5273 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
5274
5275 http->tls = SSL_new(context);
5276 SSL_set_bio(http->tls, bio, bio);
5277
5278 # ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
5279 SSL_set_tlsext_host_name(http->tls, hostname);
5280 # endif /* HAVE_SSL_SET_TLSEXT_HOST_NAME */
5281
5282 if (SSL_connect(http->tls) != 1)
5283 {
5284 unsigned long error; /* Error code */
5285
5286 while ((error = ERR_get_error()) != 0)
5287 {
5288 message = ERR_error_string(error, NULL);
5289 DEBUG_printf(("8http_setup_ssl: %s", message));
5290 }
5291
5292 SSL_CTX_free(context);
5293 SSL_free(http->tls);
5294 http->tls = NULL;
5295
5296 # ifdef WIN32
5297 http->error = WSAGetLastError();
5298 # else
5299 http->error = errno;
5300 # endif /* WIN32 */
5301 http->status = HTTP_STATUS_ERROR;
5302
5303 if (!message)
5304 message = _("Unable to establish a secure connection to host.");
5305
5306 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, message, 1);
5307
5308 return (-1);
5309 }
5310
5311 # elif defined(HAVE_GNUTLS)
5312 credentials = (gnutls_certificate_client_credentials *)
5313 malloc(sizeof(gnutls_certificate_client_credentials));
5314 if (credentials == NULL)
5315 {
5316 DEBUG_printf(("8http_setup_ssl: Unable to allocate credentials: %s",
5317 strerror(errno)));
5318 http->error = errno;
5319 http->status = HTTP_STATUS_ERROR;
5320 _cupsSetHTTPError(HTTP_STATUS_ERROR);
5321
5322 return (-1);
5323 }
5324
5325 gnutls_certificate_allocate_credentials(credentials);
5326
5327 gnutls_init(&http->tls, GNUTLS_CLIENT);
5328 gnutls_set_default_priority(http->tls);
5329 gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname,
5330 strlen(hostname));
5331 gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);
5332 gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr)http);
5333 gnutls_transport_set_pull_function(http->tls, _httpReadGNUTLS);
5334 gnutls_transport_set_push_function(http->tls, _httpWriteGNUTLS);
5335
5336 while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
5337 {
5338 DEBUG_printf(("8http_setup_ssl: gnutls_handshake returned %d (%s)",
5339 status, gnutls_strerror(status)));
5340
5341 if (gnutls_error_is_fatal(status))
5342 {
5343 http->error = EIO;
5344 http->status = HTTP_STATUS_ERROR;
5345
5346 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0);
5347
5348 gnutls_deinit(http->tls);
5349 gnutls_certificate_free_credentials(*credentials);
5350 free(credentials);
5351 http->tls = NULL;
5352
5353 return (-1);
5354 }
5355 }
5356
5357 http->tls_credentials = credentials;
5358
5359 # elif defined(HAVE_CDSASSL)
5360 if ((http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide,
5361 kSSLStreamType)) == NULL)
5362 {
5363 DEBUG_puts("4http_setup_ssl: SSLCreateContext failed.");
5364 http->error = errno = ENOMEM;
5365 http->status = HTTP_STATUS_ERROR;
5366 _cupsSetHTTPError(HTTP_STATUS_ERROR);
5367
5368 return (-1);
5369 }
5370
5371 error = SSLSetConnection(http->tls, http);
5372 DEBUG_printf(("4http_setup_ssl: SSLSetConnection, error=%d", (int)error));
5373
5374 if (!error)
5375 {
5376 error = SSLSetIOFuncs(http->tls, _httpReadCDSA, _httpWriteCDSA);
5377 DEBUG_printf(("4http_setup_ssl: SSLSetIOFuncs, error=%d", (int)error));
5378 }
5379
5380 if (!error)
5381 {
5382 error = SSLSetSessionOption(http->tls, kSSLSessionOptionBreakOnServerAuth,
5383 true);
5384 DEBUG_printf(("4http_setup_ssl: SSLSetSessionOption, error=%d",
5385 (int)error));
5386 }
5387
5388 if (!error)
5389 {
5390 if (cg->client_cert_cb)
5391 {
5392 error = SSLSetSessionOption(http->tls,
5393 kSSLSessionOptionBreakOnCertRequested, true);
5394 DEBUG_printf(("4http_setup_ssl: kSSLSessionOptionBreakOnCertRequested, "
5395 "error=%d", (int)error));
5396 }
5397 else
5398 {
5399 error = http_set_credentials(http);
5400 DEBUG_printf(("4http_setup_ssl: http_set_credentials, error=%d",
5401 (int)error));
5402 }
5403 }
5404
5405 /*
5406 * Let the server know which hostname/domain we are trying to connect to
5407 * in case it wants to serve up a certificate with a matching common name.
5408 */
5409
5410 if (!error)
5411 {
5412 error = SSLSetPeerDomainName(http->tls, hostname, strlen(hostname));
5413
5414 DEBUG_printf(("4http_setup_ssl: SSLSetPeerDomainName, error=%d",
5415 (int)error));
5416 }
5417
5418 if (!error)
5419 {
5420 int done = 0; /* Are we done yet? */
5421
5422 while (!error && !done)
5423 {
5424 error = SSLHandshake(http->tls);
5425
5426 DEBUG_printf(("4http_setup_ssl: SSLHandshake returned %d.", (int)error));
5427
5428 switch (error)
5429 {
5430 case noErr :
5431 done = 1;
5432 break;
5433
5434 case errSSLWouldBlock :
5435 error = noErr; /* Force a retry */
5436 usleep(1000); /* in 1 millisecond */
5437 break;
5438
5439 case errSSLServerAuthCompleted :
5440 error = 0;
5441 if (cg->server_cert_cb)
5442 {
5443 error = httpCopyCredentials(http, &credentials);
5444 if (!error)
5445 {
5446 error = (cg->server_cert_cb)(http, http->tls, credentials,
5447 cg->server_cert_data);
5448 httpFreeCredentials(credentials);
5449 }
5450
5451 DEBUG_printf(("4http_setup_ssl: Server certificate callback "
5452 "returned %d.", (int)error));
5453 }
5454 break;
5455
5456 case errSSLClientCertRequested :
5457 error = 0;
5458
5459 if (cg->client_cert_cb)
5460 {
5461 names = NULL;
5462 if (!(error = SSLCopyDistinguishedNames(http->tls, &dn_array)) &&
5463 dn_array)
5464 {
5465 if ((names = cupsArrayNew(NULL, NULL)) != NULL)
5466 {
5467 for (i = 0, count = CFArrayGetCount(dn_array); i < count; i++)
5468 {
5469 data = (CFDataRef)CFArrayGetValueAtIndex(dn_array, i);
5470
5471 if ((credential = malloc(sizeof(*credential))) != NULL)
5472 {
5473 credential->datalen = CFDataGetLength(data);
5474 if ((credential->data = malloc(credential->datalen)))
5475 {
5476 memcpy((void *)credential->data, CFDataGetBytePtr(data),
5477 credential->datalen);
5478 cupsArrayAdd(names, credential);
5479 }
5480 else
5481 free(credential);
5482 }
5483 }
5484 }
5485
5486 CFRelease(dn_array);
5487 }
5488
5489 if (!error)
5490 {
5491 error = (cg->client_cert_cb)(http, http->tls, names,
5492 cg->client_cert_data);
5493
5494 DEBUG_printf(("4http_setup_ssl: Client certificate callback "
5495 "returned %d.", (int)error));
5496 }
5497
5498 httpFreeCredentials(names);
5499 }
5500 break;
5501
5502 case errSSLUnknownRootCert :
5503 message = _("Unable to establish a secure connection to host "
5504 "(untrusted certificate).");
5505 break;
5506
5507 case errSSLNoRootCert :
5508 message = _("Unable to establish a secure connection to host "
5509 "(self-signed certificate).");
5510 break;
5511
5512 case errSSLCertExpired :
5513 message = _("Unable to establish a secure connection to host "
5514 "(expired certificate).");
5515 break;
5516
5517 case errSSLCertNotYetValid :
5518 message = _("Unable to establish a secure connection to host "
5519 "(certificate not yet valid).");
5520 break;
5521
5522 case errSSLHostNameMismatch :
5523 message = _("Unable to establish a secure connection to host "
5524 "(host name mismatch).");
5525 break;
5526
5527 case errSSLXCertChainInvalid :
5528 message = _("Unable to establish a secure connection to host "
5529 "(certificate chain invalid).");
5530 break;
5531
5532 case errSSLConnectionRefused :
5533 message = _("Unable to establish a secure connection to host "
5534 "(peer dropped connection before responding).");
5535 break;
5536
5537 default :
5538 break;
5539 }
5540 }
5541 }
5542
5543 if (error)
5544 {
5545 http->error = error;
5546 http->status = HTTP_STATUS_ERROR;
5547 errno = ECONNREFUSED;
5548
5549 CFRelease(http->tls);
5550 http->tls = NULL;
5551
5552 /*
5553 * If an error string wasn't set by the callbacks use a generic one...
5554 */
5555
5556 if (!message)
5557 #ifdef HAVE_CSSMERRORSTRING
5558 message = cssmErrorString(error);
5559 #else
5560 message = _("Unable to establish a secure connection to host.");
5561 #endif /* HAVE_CSSMERRORSTRING */
5562
5563 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, message, 1);
5564
5565 return (-1);
5566 }
5567
5568 # elif defined(HAVE_SSPISSL)
5569 http->tls = _sspiAlloc();
5570
5571 if (!http->tls)
5572 {
5573 _cupsSetHTTPError(HTTP_STATUS_ERROR);
5574 return (-1);
5575 }
5576
5577 http->tls->sock = http->fd;
5578 dwSize = sizeof(username) / sizeof(TCHAR);
5579 GetUserName(username, &dwSize);
5580 _sntprintf_s(commonName, sizeof(commonName) / sizeof(TCHAR),
5581 sizeof(commonName) / sizeof(TCHAR), TEXT("CN=%s"), username);
5582
5583 if (!_sspiGetCredentials(http->tls_credentials, L"ClientContainer",
5584 commonName, FALSE))
5585 {
5586 _sspiFree(http->tls_credentials);
5587 http->tls_credentials = NULL;
5588
5589 http->error = EIO;
5590 http->status = HTTP_STATUS_ERROR;
5591
5592 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI,
5593 _("Unable to establish a secure connection to host."), 1);
5594
5595 return (-1);
5596 }
5597
5598 _sspiSetAllowsAnyRoot(http->tls_credentials, TRUE);
5599 _sspiSetAllowsExpiredCerts(http->tls_credentials, TRUE);
5600
5601 if (!_sspiConnect(http->tls_credentials, hostname))
5602 {
5603 _sspiFree(http->tls_credentials);
5604 http->tls_credentials = NULL;
5605
5606 http->error = EIO;
5607 http->status = HTTP_STATUS_ERROR;
5608
5609 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI,
5610 _("Unable to establish a secure connection to host."), 1);
5611
5612 return (-1);
5613 }
5614 # endif /* HAVE_CDSASSL */
5615
5616 return (0);
5617 }
5618
5619
5620 /*
5621 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
5622 */
5623
5624 static void
5625 http_shutdown_ssl(http_t *http) /* I - HTTP connection */
5626 {
5627 # ifdef HAVE_LIBSSL
5628 SSL_CTX *context; /* Context for encryption */
5629
5630 context = SSL_get_SSL_CTX(http->tls);
5631
5632 SSL_shutdown(http->tls);
5633 SSL_CTX_free(context);
5634 SSL_free(http->tls);
5635
5636 # elif defined(HAVE_GNUTLS)
5637 gnutls_certificate_client_credentials *credentials;
5638 /* TLS credentials */
5639
5640 credentials = (gnutls_certificate_client_credentials *)(http->tls_credentials);
5641
5642 gnutls_bye(http->tls, GNUTLS_SHUT_RDWR);
5643 gnutls_deinit(http->tls);
5644 gnutls_certificate_free_credentials(*credentials);
5645 free(credentials);
5646
5647 # elif defined(HAVE_CDSASSL)
5648 while (SSLClose(http->tls) == errSSLWouldBlock)
5649 usleep(1000);
5650
5651 CFRelease(http->tls);
5652
5653 if (http->tls_credentials)
5654 CFRelease(http->tls_credentials);
5655
5656 # elif defined(HAVE_SSPISSL)
5657 _sspiFree(http->tls_credentials);
5658 # endif /* HAVE_LIBSSL */
5659
5660 http->tls = NULL;
5661 http->tls_credentials = NULL;
5662 }
5663 #endif /* HAVE_SSL */
5664
5665
5666 #ifdef HAVE_SSL
5667 /*
5668 * 'http_upgrade()' - Force upgrade to TLS encryption.
5669 */
5670
5671 static int /* O - Status of connection */
5672 http_upgrade(http_t *http) /* I - HTTP connection */
5673 {
5674 int ret; /* Return value */
5675 http_t myhttp; /* Local copy of HTTP data */
5676
5677
5678 DEBUG_printf(("7http_upgrade(%p)", http));
5679
5680 /*
5681 * Flush the connection to make sure any previous "Upgrade" message
5682 * has been read.
5683 */
5684
5685 httpFlush(http);
5686
5687 /*
5688 * Copy the HTTP data to a local variable so we can do the OPTIONS
5689 * request without interfering with the existing request data...
5690 */
5691
5692 memcpy(&myhttp, http, sizeof(myhttp));
5693
5694 /*
5695 * Send an OPTIONS request to the server, requiring SSL or TLS
5696 * encryption on the link...
5697 */
5698
5699 http->tls_upgrade = 1;
5700 http->field_authorization = NULL; /* Don't free the auth string */
5701
5702 httpClearFields(http);
5703 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
5704 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
5705
5706 if ((ret = httpOptions(http, "*")) == 0)
5707 {
5708 /*
5709 * Wait for the secure connection...
5710 */
5711
5712 while (httpUpdate(http) == HTTP_STATUS_CONTINUE);
5713 }
5714
5715 /*
5716 * Restore the HTTP request data...
5717 */
5718
5719 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
5720 http->data_encoding = myhttp.data_encoding;
5721 http->data_remaining = myhttp.data_remaining;
5722 http->_data_remaining = myhttp._data_remaining;
5723 http->expect = myhttp.expect;
5724 http->field_authorization = myhttp.field_authorization;
5725 http->digest_tries = myhttp.digest_tries;
5726 http->tls_upgrade = 0;
5727
5728 /*
5729 * See if we actually went secure...
5730 */
5731
5732 if (!http->tls)
5733 {
5734 /*
5735 * Server does not support HTTP upgrade...
5736 */
5737
5738 DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
5739
5740 # ifdef WIN32
5741 closesocket(http->fd);
5742 # else
5743 close(http->fd);
5744 # endif
5745
5746 http->fd = -1;
5747
5748 return (-1);
5749 }
5750 else
5751 return (ret);
5752 }
5753 #endif /* HAVE_SSL */
5754
5755
5756 /*
5757 * 'http_write()' - Write a buffer to a HTTP connection.
5758 */
5759
5760 static ssize_t /* O - Number of bytes written */
5761 http_write(http_t *http, /* I - HTTP connection */
5762 const char *buffer, /* I - Buffer for data */
5763 size_t length) /* I - Number of bytes to write */
5764 {
5765 ssize_t tbytes, /* Total bytes sent */
5766 bytes; /* Bytes sent */
5767
5768
5769 DEBUG_printf(("2http_write(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
5770 buffer, CUPS_LLCAST length));
5771 http->error = 0;
5772 tbytes = 0;
5773
5774 while (length > 0)
5775 {
5776 DEBUG_printf(("3http_write: About to write %d bytes.", (int)length));
5777
5778 if (http->timeout_cb)
5779 {
5780 #ifdef HAVE_POLL
5781 struct pollfd pfd; /* Polled file descriptor */
5782 #else
5783 fd_set output_set; /* Output ready for write? */
5784 struct timeval timeout; /* Timeout value */
5785 #endif /* HAVE_POLL */
5786 int nfds; /* Result from select()/poll() */
5787
5788 do
5789 {
5790 #ifdef HAVE_POLL
5791 pfd.fd = http->fd;
5792 pfd.events = POLLOUT;
5793
5794 while ((nfds = poll(&pfd, 1, http->wait_value)) < 0 &&
5795 (errno == EINTR || errno == EAGAIN))
5796 /* do nothing */;
5797
5798 #else
5799 do
5800 {
5801 FD_ZERO(&output_set);
5802 FD_SET(http->fd, &output_set);
5803
5804 timeout.tv_sec = http->wait_value / 1000;
5805 timeout.tv_usec = 1000 * (http->wait_value % 1000);
5806
5807 nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout);
5808 }
5809 # ifdef WIN32
5810 while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
5811 WSAGetLastError() == WSAEWOULDBLOCK));
5812 # else
5813 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
5814 # endif /* WIN32 */
5815 #endif /* HAVE_POLL */
5816
5817 if (nfds < 0)
5818 {
5819 http->error = errno;
5820 return (-1);
5821 }
5822 else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data))
5823 {
5824 #ifdef WIN32
5825 http->error = WSAEWOULDBLOCK;
5826 #else
5827 http->error = EWOULDBLOCK;
5828 #endif /* WIN32 */
5829 return (-1);
5830 }
5831 }
5832 while (nfds <= 0);
5833 }
5834
5835 #ifdef HAVE_SSL
5836 if (http->tls)
5837 bytes = http_write_ssl(http, buffer, length);
5838 else
5839 #endif /* HAVE_SSL */
5840 bytes = send(http->fd, buffer, length, 0);
5841
5842 DEBUG_printf(("3http_write: Write of " CUPS_LLFMT " bytes returned "
5843 CUPS_LLFMT ".", CUPS_LLCAST length, CUPS_LLCAST bytes));
5844
5845 if (bytes < 0)
5846 {
5847 #ifdef WIN32
5848 if (WSAGetLastError() == WSAEINTR)
5849 continue;
5850 else if (WSAGetLastError() == WSAEWOULDBLOCK)
5851 {
5852 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
5853 continue;
5854
5855 http->error = WSAGetLastError();
5856 }
5857 else if (WSAGetLastError() != http->error &&
5858 WSAGetLastError() != WSAECONNRESET)
5859 {
5860 http->error = WSAGetLastError();
5861 continue;
5862 }
5863
5864 #else
5865 if (errno == EINTR)
5866 continue;
5867 else if (errno == EWOULDBLOCK || errno == EAGAIN)
5868 {
5869 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
5870 continue;
5871 else if (!http->timeout_cb && errno == EAGAIN)
5872 continue;
5873
5874 http->error = errno;
5875 }
5876 else if (errno != http->error && errno != ECONNRESET)
5877 {
5878 http->error = errno;
5879 continue;
5880 }
5881 #endif /* WIN32 */
5882
5883 DEBUG_printf(("3http_write: error writing data (%s).",
5884 strerror(http->error)));
5885
5886 return (-1);
5887 }
5888
5889 buffer += bytes;
5890 tbytes += bytes;
5891 length -= bytes;
5892 }
5893
5894 #ifdef DEBUG
5895 http_debug_hex("http_write", buffer - tbytes, tbytes);
5896 #endif /* DEBUG */
5897
5898 DEBUG_printf(("3http_write: Returning " CUPS_LLFMT ".", CUPS_LLCAST tbytes));
5899
5900 return (tbytes);
5901 }
5902
5903
5904 /*
5905 * 'http_write_chunk()' - Write a chunked buffer.
5906 */
5907
5908 static ssize_t /* O - Number bytes written */
5909 http_write_chunk(http_t *http, /* I - HTTP connection */
5910 const char *buffer, /* I - Buffer to write */
5911 size_t length) /* I - Length of buffer */
5912 {
5913 char header[16]; /* Chunk header */
5914 ssize_t bytes; /* Bytes written */
5915
5916
5917 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
5918 http, buffer, CUPS_LLCAST length));
5919
5920 /*
5921 * Write the chunk header, data, and trailer.
5922 */
5923
5924 snprintf(header, sizeof(header), "%x\r\n", (unsigned)length);
5925 if (http_write(http, header, strlen(header)) < 0)
5926 {
5927 DEBUG_puts("8http_write_chunk: http_write of length failed.");
5928 return (-1);
5929 }
5930
5931 if ((bytes = http_write(http, buffer, length)) < 0)
5932 {
5933 DEBUG_puts("8http_write_chunk: http_write of buffer failed.");
5934 return (-1);
5935 }
5936
5937 if (http_write(http, "\r\n", 2) < 0)
5938 {
5939 DEBUG_puts("8http_write_chunk: http_write of CR LF failed.");
5940 return (-1);
5941 }
5942
5943 return (bytes);
5944 }
5945
5946
5947 #ifdef HAVE_SSL
5948 /*
5949 * 'http_write_ssl()' - Write to a SSL/TLS connection.
5950 */
5951
5952 static int /* O - Bytes written */
5953 http_write_ssl(http_t *http, /* I - HTTP connection */
5954 const char *buf, /* I - Buffer holding data */
5955 int len) /* I - Length of buffer */
5956 {
5957 ssize_t result; /* Return value */
5958
5959
5960 DEBUG_printf(("2http_write_ssl(http=%p, buf=%p, len=%d)", http, buf, len));
5961
5962 # if defined(HAVE_LIBSSL)
5963 result = SSL_write((SSL *)(http->tls), buf, len);
5964
5965 # elif defined(HAVE_GNUTLS)
5966 result = gnutls_record_send(http->tls, buf, len);
5967
5968 if (result < 0 && !errno)
5969 {
5970 /*
5971 * Convert GNU TLS error to errno value...
5972 */
5973
5974 switch (result)
5975 {
5976 case GNUTLS_E_INTERRUPTED :
5977 errno = EINTR;
5978 break;
5979
5980 case GNUTLS_E_AGAIN :
5981 errno = EAGAIN;
5982 break;
5983
5984 default :
5985 errno = EPIPE;
5986 break;
5987 }
5988
5989 result = -1;
5990 }
5991
5992 # elif defined(HAVE_CDSASSL)
5993 OSStatus error; /* Error info */
5994 size_t processed; /* Number of bytes processed */
5995
5996
5997 error = SSLWrite(http->tls, buf, len, &processed);
5998
5999 switch (error)
6000 {
6001 case 0 :
6002 result = (int)processed;
6003 break;
6004
6005 case errSSLWouldBlock :
6006 if (processed)
6007 result = (int)processed;
6008 else
6009 {
6010 result = -1;
6011 errno = EINTR;
6012 }
6013 break;
6014
6015 case errSSLClosedGraceful :
6016 default :
6017 if (processed)
6018 result = (int)processed;
6019 else
6020 {
6021 result = -1;
6022 errno = EPIPE;
6023 }
6024 break;
6025 }
6026 # elif defined(HAVE_SSPISSL)
6027 return _sspiWrite((_sspi_struct_t *)http->tls, (void *)buf, len);
6028 # endif /* HAVE_LIBSSL */
6029
6030 DEBUG_printf(("3http_write_ssl: Returning %d.", (int)result));
6031
6032 return ((int)result);
6033 }
6034 #endif /* HAVE_SSL */
6035
6036
6037 /*
6038 * End of "$Id$".
6039 */