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