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