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