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