]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Merge changes from CUPS 1.4svn-r8492.
[thirdparty/cups.git] / cups / http.c
1 /*
2 * "$Id: http.c 7850 2008-08-20 00:07:25Z mike $"
3 *
4 * HTTP routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007-2009 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 * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP connections.
23 * httpBlocking() - Set blocking/non-blocking behavior on a connection.
24 * httpCheck() - Check to see if there is a pending response from the
25 * server.
26 * httpClearCookie() - Clear the cookie value(s).
27 * httpClearFields() - Clear HTTP request fields.
28 * httpClose() - Close an HTTP connection...
29 * httpConnect() - Connect to a HTTP server.
30 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
31 * _httpCreate() - Create an unconnected HTTP connection.
32 * httpDelete() - Send a DELETE request to the server.
33 * httpEncryption() - Set the required encryption on the link.
34 * httpError() - Get the last error on a connection.
35 * httpFlush() - Flush data from a HTTP connection.
36 * httpFlushWrite() - Flush data in write buffer.
37 * httpGet() - Send a GET request to the server.
38 * httpGetAuthString() - Get the current authorization string.
39 * httpGetBlocking() - Get the blocking/non-block state of a connection.
40 * httpGetCookie() - Get any cookie data from the response.
41 * httpGetFd() - Get the file descriptor associated with a
42 * connection.
43 * httpGetField() - Get a field value from a request/response.
44 * httpGetLength() - Get the amount of data remaining from the
45 * content-length or transfer-encoding fields.
46 * httpGetLength2() - Get the amount of data remaining from the
47 * content-length or transfer-encoding fields.
48 * httpGetStatus() - Get the status of the last HTTP request.
49 * httpGetSubField() - Get a sub-field value.
50 * httpGetSubField2() - Get a sub-field value.
51 * httpGets() - Get a line of text from a HTTP connection.
52 * httpHead() - Send a HEAD request to the server.
53 * httpInitialize() - Initialize the HTTP interface library and set the
54 * default HTTP proxy (if any).
55 * httpOptions() - Send an OPTIONS request to the server.
56 * httpPost() - Send a POST request to the server.
57 * httpPrintf() - Print a formatted string to a HTTP connection.
58 * httpPut() - Send a PUT request to the server.
59 * httpRead() - Read data from a HTTP connection.
60 * httpRead2() - Read data from a HTTP connection.
61 * _httpReadCDSA() - Read function for the CDSA library.
62 * _httpReadGNUTLS() - Read function for the GNU TLS library.
63 * httpReconnect() - Reconnect to a HTTP server.
64 * httpSetAuthString() - Set the current authorization string.
65 * httpSetCookie() - Set the cookie value(s)...
66 * httpSetExpect() - Set the Expect: header in a request.
67 * httpSetField() - Set the value of an HTTP header.
68 * httpSetLength() - Set the content-length and content-encoding.
69 * httpTrace() - Send an TRACE request to the server.
70 * httpUpdate() - Update the current HTTP state for incoming data.
71 * _httpWait() - Wait for data available on a connection (no flush).
72 * httpWait() - Wait for data available on a connection.
73 * httpWrite() - Write data to a HTTP connection.
74 * httpWrite2() - Write data to a HTTP connection.
75 * _httpWriteCDSA() - Write function for the CDSA library.
76 * _httpWriteGNUTLS() - Write function for the GNU TLS library.
77 * http_bio_ctrl() - Control the HTTP connection.
78 * http_bio_free() - Free OpenSSL data.
79 * http_bio_new() - Initialize an OpenSSL BIO structure.
80 * http_bio_puts() - Send a string for OpenSSL.
81 * http_bio_read() - Read data for OpenSSL.
82 * http_bio_write() - Write data for OpenSSL.
83 * http_debug_hex() - Do a hex dump of a buffer.
84 * http_field() - Return the field index for a field name.
85 * http_read_ssl() - Read from a SSL/TLS connection.
86 * http_send() - Send a request with all fields and the trailing
87 * blank line.
88 * http_setup_ssl() - Set up SSL/TLS support on a connection.
89 * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
90 * http_upgrade() - Force upgrade to TLS encryption.
91 * http_write() - Write a buffer to a HTTP connection.
92 * http_write_chunk() - Write a chunked buffer.
93 * http_write_ssl() - Write to a SSL/TLS connection.
94 */
95
96 /*
97 * Include necessary headers...
98 */
99
100 #include "http-private.h"
101 #include "globals.h"
102 #include "debug.h"
103 #include <stdlib.h>
104 #include <fcntl.h>
105 #include <errno.h>
106 #ifndef WIN32
107 # include <signal.h>
108 # include <sys/time.h>
109 # include <sys/resource.h>
110 #endif /* !WIN32 */
111 #ifdef HAVE_POLL
112 # include <sys/poll.h>
113 #endif /* HAVE_POLL */
114
115
116 /*
117 * Some operating systems have done away with the Fxxxx constants for
118 * the fcntl() call; this works around that "feature"...
119 */
120
121 #ifndef FNONBLK
122 # define FNONBLK O_NONBLOCK
123 #endif /* !FNONBLK */
124
125
126 /*
127 * Local functions...
128 */
129
130 #ifdef DEBUG
131 static void http_debug_hex(const char *prefix, const char *buffer,
132 int bytes);
133 #endif /* DEBUG */
134 static http_field_t http_field(const char *name);
135 static int http_send(http_t *http, http_state_t request,
136 const char *uri);
137 static int http_write(http_t *http, const char *buffer,
138 int length);
139 static int http_write_chunk(http_t *http, const char *buffer,
140 int length);
141 #ifdef HAVE_SSL
142 static int http_read_ssl(http_t *http, char *buf, int len);
143 static int http_setup_ssl(http_t *http);
144 static void http_shutdown_ssl(http_t *http);
145 static int http_upgrade(http_t *http);
146 static int http_write_ssl(http_t *http, const char *buf, int len);
147 #endif /* HAVE_SSL */
148
149
150 /*
151 * Local globals...
152 */
153
154 static const char * const http_fields[] =
155 {
156 "Accept-Language",
157 "Accept-Ranges",
158 "Authorization",
159 "Connection",
160 "Content-Encoding",
161 "Content-Language",
162 "Content-Length",
163 "Content-Location",
164 "Content-MD5",
165 "Content-Range",
166 "Content-Type",
167 "Content-Version",
168 "Date",
169 "Host",
170 "If-Modified-Since",
171 "If-Unmodified-since",
172 "Keep-Alive",
173 "Last-Modified",
174 "Link",
175 "Location",
176 "Range",
177 "Referer",
178 "Retry-After",
179 "Transfer-Encoding",
180 "Upgrade",
181 "User-Agent",
182 "WWW-Authenticate"
183 };
184
185
186 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
187 /*
188 * BIO methods for OpenSSL...
189 */
190
191 static int http_bio_write(BIO *h, const char *buf, int num);
192 static int http_bio_read(BIO *h, char *buf, int size);
193 static int http_bio_puts(BIO *h, const char *str);
194 static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
195 static int http_bio_new(BIO *h);
196 static int http_bio_free(BIO *data);
197
198 static BIO_METHOD http_bio_methods =
199 {
200 BIO_TYPE_SOCKET,
201 "http",
202 http_bio_write,
203 http_bio_read,
204 http_bio_puts,
205 NULL, /* http_bio_gets, */
206 http_bio_ctrl,
207 http_bio_new,
208 http_bio_free,
209 NULL,
210 };
211
212
213 /*
214 * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections.
215 */
216
217 BIO_METHOD * /* O - BIO methods for OpenSSL */
218 _httpBIOMethods(void)
219 {
220 return (&http_bio_methods);
221 }
222 #endif /* HAVE_SSL && HAVE_LIBSSL */
223
224
225 /*
226 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
227 */
228
229 void
230 httpBlocking(http_t *http, /* I - Connection to server */
231 int b) /* I - 1 = blocking, 0 = non-blocking */
232 {
233 if (http)
234 http->blocking = b;
235 }
236
237
238 /*
239 * 'httpCheck()' - Check to see if there is a pending response from the server.
240 */
241
242 int /* O - 0 = no data, 1 = data available */
243 httpCheck(http_t *http) /* I - Connection to server */
244 {
245 return (httpWait(http, 0));
246 }
247
248
249 /*
250 * 'httpClearCookie()' - Clear the cookie value(s).
251 *
252 * @since CUPS 1.1.19/Mac OS X 10.3@
253 */
254
255 void
256 httpClearCookie(http_t *http) /* I - Connection to server */
257 {
258 if (!http)
259 return;
260
261 if (http->cookie)
262 {
263 free(http->cookie);
264 http->cookie = NULL;
265 }
266 }
267
268
269 /*
270 * 'httpClearFields()' - Clear HTTP request fields.
271 */
272
273 void
274 httpClearFields(http_t *http) /* I - Connection to server */
275 {
276 if (http)
277 {
278 memset(http->fields, 0, sizeof(http->fields));
279 if (http->hostname[0] == '/')
280 httpSetField(http, HTTP_FIELD_HOST, "localhost");
281 else
282 httpSetField(http, HTTP_FIELD_HOST, http->hostname);
283
284 if (http->field_authorization)
285 {
286 free(http->field_authorization);
287 http->field_authorization = NULL;
288 }
289
290 http->expect = (http_status_t)0;
291 }
292 }
293
294
295 /*
296 * 'httpClose()' - Close an HTTP connection...
297 */
298
299 void
300 httpClose(http_t *http) /* I - Connection to server */
301 {
302 #ifdef HAVE_GSSAPI
303 OM_uint32 minor_status; /* Minor status code */
304 #endif /* HAVE_GSSAPI */
305
306
307 DEBUG_printf(("httpClose(http=%p)\n", http));
308
309 if (!http)
310 return;
311
312 httpAddrFreeList(http->addrlist);
313
314 if (http->cookie)
315 free(http->cookie);
316
317 #ifdef HAVE_SSL
318 if (http->tls)
319 http_shutdown_ssl(http);
320 #endif /* HAVE_SSL */
321
322 #ifdef WIN32
323 closesocket(http->fd);
324 #else
325 close(http->fd);
326 #endif /* WIN32 */
327
328 #ifdef HAVE_GSSAPI
329 if (http->gssctx != GSS_C_NO_CONTEXT)
330 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
331
332 if (http->gssname != GSS_C_NO_NAME)
333 gss_release_name(&minor_status, &http->gssname);
334 #endif /* HAVE_GSSAPI */
335
336 #ifdef HAVE_AUTHORIZATION_H
337 if (http->auth_ref)
338 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
339 #endif /* HAVE_AUTHORIZATION_H */
340
341 httpClearFields(http);
342
343 if (http->authstring && http->authstring != http->_authstring)
344 free(http->authstring);
345
346 free(http);
347 }
348
349
350 /*
351 * 'httpConnect()' - Connect to a HTTP server.
352 *
353 * This function is deprecated - use @link httpConnectEncrypt@ instead.
354 *
355 * @deprecated@
356 */
357
358 http_t * /* O - New HTTP connection */
359 httpConnect(const char *host, /* I - Host to connect to */
360 int port) /* I - Port number */
361 {
362 return (httpConnectEncrypt(host, port, HTTP_ENCRYPT_IF_REQUESTED));
363 }
364
365
366 /*
367 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
368 */
369
370 http_t * /* O - New HTTP connection */
371 httpConnectEncrypt(
372 const char *host, /* I - Host to connect to */
373 int port, /* I - Port number */
374 http_encryption_t encryption) /* I - Type of encryption to use */
375 {
376 http_t *http; /* New HTTP connection */
377
378
379 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)\n",
380 host, port, encryption));
381
382 /*
383 * Create the HTTP structure...
384 */
385
386 if ((http = _httpCreate(host, port, encryption)) == NULL)
387 return (NULL);
388
389 /*
390 * Connect to the remote system...
391 */
392
393 if (!httpReconnect(http))
394 return (http);
395
396 /*
397 * Could not connect to any known address - bail out!
398 */
399
400 httpAddrFreeList(http->addrlist);
401
402 free(http);
403
404 return (NULL);
405 }
406
407
408 /*
409 * '_httpCreate()' - Create an unconnected HTTP connection.
410 */
411
412 http_t * /* O - HTTP connection */
413 _httpCreate(
414 const char *host, /* I - Hostname */
415 int port, /* I - Port number */
416 http_encryption_t encryption) /* I - Encryption to use */
417 {
418 http_t *http; /* New HTTP connection */
419 http_addrlist_t *addrlist; /* Host address data */
420 char service[255]; /* Service name */
421
422
423 DEBUG_printf(("_httpCreate(host=\"%s\", port=%d, encryption=%d)\n",
424 host, port, encryption));
425
426 if (!host)
427 return (NULL);
428
429 httpInitialize();
430
431 /*
432 * Lookup the host...
433 */
434
435 sprintf(service, "%d", port);
436
437 if ((addrlist = httpAddrGetList(host, AF_UNSPEC, service)) == NULL)
438 return (NULL);
439
440 /*
441 * Allocate memory for the structure...
442 */
443
444 if ((http = calloc(sizeof(http_t), 1)) == NULL)
445 {
446 httpAddrFreeList(addrlist);
447 return (NULL);
448 }
449
450 /*
451 * Initialize the HTTP data...
452 */
453
454 http->activity = time(NULL);
455 http->addrlist = addrlist;
456 http->blocking = 1;
457 http->fd = -1;
458 #ifdef HAVE_GSSAPI
459 http->gssctx = GSS_C_NO_CONTEXT;
460 http->gssname = GSS_C_NO_NAME;
461 #endif /* HAVE_GSSAPI */
462 http->version = HTTP_1_1;
463
464 strlcpy(http->hostname, host, sizeof(http->hostname));
465
466 if (port == 443) /* Always use encryption for https */
467 http->encryption = HTTP_ENCRYPT_ALWAYS;
468 else
469 http->encryption = encryption;
470
471 /*
472 * Return the new structure...
473 */
474
475 return (http);
476 }
477
478
479 /*
480 * 'httpDelete()' - Send a DELETE request to the server.
481 */
482
483 int /* O - Status of call (0 = success) */
484 httpDelete(http_t *http, /* I - Connection to server */
485 const char *uri) /* I - URI to delete */
486 {
487 return (http_send(http, HTTP_DELETE, uri));
488 }
489
490
491 /*
492 * 'httpEncryption()' - Set the required encryption on the link.
493 */
494
495 int /* O - -1 on error, 0 on success */
496 httpEncryption(http_t *http, /* I - Connection to server */
497 http_encryption_t e) /* I - New encryption preference */
498 {
499 DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e));
500
501 #ifdef HAVE_SSL
502 if (!http)
503 return (0);
504
505 http->encryption = e;
506
507 if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
508 (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
509 return (httpReconnect(http));
510 else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
511 return (http_upgrade(http));
512 else
513 return (0);
514 #else
515 if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
516 return (-1);
517 else
518 return (0);
519 #endif /* HAVE_SSL */
520 }
521
522
523 /*
524 * 'httpError()' - Get the last error on a connection.
525 */
526
527 int /* O - Error code (errno) value */
528 httpError(http_t *http) /* I - Connection to server */
529 {
530 if (http)
531 return (http->error);
532 else
533 return (EINVAL);
534 }
535
536
537 /*
538 * 'httpFlush()' - Flush data from a HTTP connection.
539 */
540
541 void
542 httpFlush(http_t *http) /* I - Connection to server */
543 {
544 char buffer[8192]; /* Junk buffer */
545 int blocking; /* To block or not to block */
546
547
548 DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state));
549
550 /*
551 * Temporarily set non-blocking mode so we don't get stuck in httpRead()...
552 */
553
554 blocking = http->blocking;
555 http->blocking = 0;
556
557 /*
558 * Read any data we can...
559 */
560
561 while (httpRead2(http, buffer, sizeof(buffer)) > 0);
562
563 /*
564 * Restore blocking and reset the connection if we didn't get all of
565 * the remaining data...
566 */
567
568 http->blocking = blocking;
569
570 if (http->state != HTTP_WAITING && http->fd >= 0)
571 {
572 /*
573 * Didn't get the data back, so close the current connection.
574 */
575
576 http->state = HTTP_WAITING;
577
578 #ifdef HAVE_SSL
579 if (http->tls)
580 http_shutdown_ssl(http);
581 #endif /* HAVE_SSL */
582
583 #ifdef WIN32
584 closesocket(http->fd);
585 #else
586 close(http->fd);
587 #endif /* WIN32 */
588
589 http->fd = -1;
590 }
591 }
592
593
594 /*
595 * 'httpFlushWrite()' - Flush data in write buffer.
596 *
597 * @since CUPS 1.2/Mac OS X 10.5@
598 */
599
600 int /* O - Bytes written or -1 on error */
601 httpFlushWrite(http_t *http) /* I - Connection to server */
602 {
603 int bytes; /* Bytes written */
604
605
606 DEBUG_printf(("httpFlushWrite(http=%p)\n", http));
607
608 if (!http || !http->wused)
609 return (0);
610
611 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
612 bytes = http_write_chunk(http, http->wbuffer, http->wused);
613 else
614 bytes = http_write(http, http->wbuffer, http->wused);
615
616 http->wused = 0;
617
618 return (bytes);
619 }
620
621
622 /*
623 * 'httpGet()' - Send a GET request to the server.
624 */
625
626 int /* O - Status of call (0 = success) */
627 httpGet(http_t *http, /* I - Connection to server */
628 const char *uri) /* I - URI to get */
629 {
630 return (http_send(http, HTTP_GET, uri));
631 }
632
633
634 /*
635 * 'httpGetAuthString()' - Get the current authorization string.
636 *
637 * The authorization string is set by cupsDoAuthentication() and
638 * httpSetAuthString(). Use httpGetAuthString() to retrieve the
639 * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION
640 * value.
641 *
642 * @since CUPS 1.3/Mac OS X 10.5@
643 */
644
645 char * /* O - Authorization string */
646 httpGetAuthString(http_t *http) /* I - Connection to server */
647 {
648 if (http)
649 return (http->authstring);
650 else
651 return (NULL);
652 }
653
654
655 /*
656 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection.
657 *
658 * @since CUPS 1.2/Mac OS X 10.5@
659 */
660
661 int /* O - 1 if blocking, 0 if non-blocking */
662 httpGetBlocking(http_t *http) /* I - Connection to server */
663 {
664 return (http ? http->blocking : 0);
665 }
666
667
668 /*
669 * 'httpGetCookie()' - Get any cookie data from the response.
670 *
671 * @since CUPS 1.1.19/Mac OS X 10.3@
672 */
673
674 const char * /* O - Cookie data or NULL */
675 httpGetCookie(http_t *http) /* I - HTTP connecion */
676 {
677 return (http ? http->cookie : NULL);
678 }
679
680
681 /*
682 * 'httpGetFd()' - Get the file descriptor associated with a connection.
683 *
684 * @since CUPS 1.2/Mac OS X 10.5@
685 */
686
687 int /* O - File descriptor or -1 if none */
688 httpGetFd(http_t *http) /* I - Connection to server */
689 {
690 return (http ? http->fd : -1);
691 }
692
693
694 /*
695 * 'httpGetField()' - Get a field value from a request/response.
696 */
697
698 const char * /* O - Field value */
699 httpGetField(http_t *http, /* I - Connection to server */
700 http_field_t field) /* I - Field to get */
701 {
702 if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
703 return (NULL);
704 else if (field == HTTP_FIELD_AUTHORIZATION &&
705 http->field_authorization)
706 {
707 /*
708 * Special case for WWW-Authenticate: as its contents can be
709 * longer than HTTP_MAX_VALUE...
710 */
711
712 return (http->field_authorization);
713 }
714 else
715 return (http->fields[field]);
716 }
717
718
719 /*
720 * 'httpGetLength()' - Get the amount of data remaining from the
721 * content-length or transfer-encoding fields.
722 *
723 * This function is deprecated and will not return lengths larger than
724 * 2^31 - 1; use httpGetLength2() instead.
725 *
726 * @deprecated@
727 */
728
729 int /* O - Content length */
730 httpGetLength(http_t *http) /* I - Connection to server */
731 {
732 /*
733 * Get the read content length and return the 32-bit value.
734 */
735
736 if (http)
737 {
738 httpGetLength2(http);
739
740 return (http->_data_remaining);
741 }
742 else
743 return (-1);
744 }
745
746
747 /*
748 * 'httpGetLength2()' - Get the amount of data remaining from the
749 * content-length or transfer-encoding fields.
750 *
751 * This function returns the complete content length, even for
752 * content larger than 2^31 - 1.
753 *
754 * @since CUPS 1.2/Mac OS X 10.5@
755 */
756
757 off_t /* O - Content length */
758 httpGetLength2(http_t *http) /* I - Connection to server */
759 {
760 DEBUG_printf(("httpGetLength2(http=%p), state=%d\n", http, http->state));
761
762 if (!http)
763 return (-1);
764
765 if (!strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"))
766 {
767 DEBUG_puts("httpGetLength2: chunked request!");
768
769 http->data_encoding = HTTP_ENCODE_CHUNKED;
770 http->data_remaining = 0;
771 }
772 else
773 {
774 http->data_encoding = HTTP_ENCODE_LENGTH;
775
776 /*
777 * The following is a hack for HTTP servers that don't send a
778 * content-length or transfer-encoding field...
779 *
780 * If there is no content-length then the connection must close
781 * after the transfer is complete...
782 */
783
784 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0])
785 {
786 /*
787 * Default content length is 0 for errors and 2^31-1 for other
788 * successful requests...
789 */
790
791 if (http->status >= HTTP_MULTIPLE_CHOICES)
792 http->data_remaining = 0;
793 else
794 http->data_remaining = 2147483647;
795 }
796 else
797 http->data_remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH],
798 NULL, 10);
799
800 DEBUG_printf(("httpGetLength2: content_length=" CUPS_LLFMT "\n",
801 CUPS_LLCAST http->data_remaining));
802 }
803
804 if (http->data_remaining <= INT_MAX)
805 http->_data_remaining = (int)http->data_remaining;
806 else
807 http->_data_remaining = INT_MAX;
808
809 return (http->data_remaining);
810 }
811
812
813 /*
814 * 'httpGetStatus()' - Get the status of the last HTTP request.
815 *
816 * @since CUPS 1.2/Mac OS X 10.5@
817 */
818
819 http_status_t /* O - HTTP status */
820 httpGetStatus(http_t *http) /* I - Connection to server */
821 {
822 return (http ? http->status : HTTP_ERROR);
823 }
824
825
826 /*
827 * 'httpGetSubField()' - Get a sub-field value.
828 *
829 * @deprecated@
830 */
831
832 char * /* O - Value or NULL */
833 httpGetSubField(http_t *http, /* I - Connection to server */
834 http_field_t field, /* I - Field index */
835 const char *name, /* I - Name of sub-field */
836 char *value) /* O - Value string */
837 {
838 return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE));
839 }
840
841
842 /*
843 * 'httpGetSubField2()' - Get a sub-field value.
844 *
845 * @since CUPS 1.2/Mac OS X 10.5@
846 */
847
848 char * /* O - Value or NULL */
849 httpGetSubField2(http_t *http, /* I - Connection to server */
850 http_field_t field, /* I - Field index */
851 const char *name, /* I - Name of sub-field */
852 char *value, /* O - Value string */
853 int valuelen) /* I - Size of value buffer */
854 {
855 const char *fptr; /* Pointer into field */
856 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
857 *ptr, /* Pointer into string buffer */
858 *end; /* End of value buffer */
859
860 DEBUG_printf(("httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, valuelen=%d)\n",
861 http, field, name, value, valuelen));
862
863 if (!http || !name || !value || valuelen < 2 ||
864 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
865 return (NULL);
866
867 end = value + valuelen - 1;
868
869 for (fptr = http->fields[field]; *fptr;)
870 {
871 /*
872 * Skip leading whitespace...
873 */
874
875 while (isspace(*fptr & 255))
876 fptr ++;
877
878 if (*fptr == ',')
879 {
880 fptr ++;
881 continue;
882 }
883
884 /*
885 * Get the sub-field name...
886 */
887
888 for (ptr = temp;
889 *fptr && *fptr != '=' && !isspace(*fptr & 255) &&
890 ptr < (temp + sizeof(temp) - 1);
891 *ptr++ = *fptr++);
892
893 *ptr = '\0';
894
895 DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp));
896
897 /*
898 * Skip trailing chars up to the '='...
899 */
900
901 while (isspace(*fptr & 255))
902 fptr ++;
903
904 if (!*fptr)
905 break;
906
907 if (*fptr != '=')
908 continue;
909
910 /*
911 * Skip = and leading whitespace...
912 */
913
914 fptr ++;
915
916 while (isspace(*fptr & 255))
917 fptr ++;
918
919 if (*fptr == '\"')
920 {
921 /*
922 * Read quoted string...
923 */
924
925 for (ptr = value, fptr ++;
926 *fptr && *fptr != '\"' && ptr < end;
927 *ptr++ = *fptr++);
928
929 *ptr = '\0';
930
931 while (*fptr && *fptr != '\"')
932 fptr ++;
933
934 if (*fptr)
935 fptr ++;
936 }
937 else
938 {
939 /*
940 * Read unquoted string...
941 */
942
943 for (ptr = value;
944 *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < end;
945 *ptr++ = *fptr++);
946
947 *ptr = '\0';
948
949 while (*fptr && !isspace(*fptr & 255) && *fptr != ',')
950 fptr ++;
951 }
952
953 DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value));
954
955 /*
956 * See if this is the one...
957 */
958
959 if (!strcmp(name, temp))
960 return (value);
961 }
962
963 value[0] = '\0';
964
965 return (NULL);
966 }
967
968
969 /*
970 * 'httpGets()' - Get a line of text from a HTTP connection.
971 */
972
973 char * /* O - Line or NULL */
974 httpGets(char *line, /* I - Line to read into */
975 int length, /* I - Max length of buffer */
976 http_t *http) /* I - Connection to server */
977 {
978 char *lineptr, /* Pointer into line */
979 *lineend, /* End of line */
980 *bufptr, /* Pointer into input buffer */
981 *bufend; /* Pointer to end of buffer */
982 int bytes, /* Number of bytes read */
983 eol; /* End-of-line? */
984
985
986 DEBUG_printf(("httpGets(line=%p, length=%d, http=%p)\n", line, length, http));
987
988 if (http == NULL || line == NULL)
989 return (NULL);
990
991 /*
992 * Read a line from the buffer...
993 */
994
995 lineptr = line;
996 lineend = line + length - 1;
997 eol = 0;
998
999 while (lineptr < lineend)
1000 {
1001 /*
1002 * Pre-load the buffer as needed...
1003 */
1004
1005 #ifdef WIN32
1006 WSASetLastError(0);
1007 #else
1008 errno = 0;
1009 #endif /* WIN32 */
1010
1011 while (http->used == 0)
1012 {
1013 /*
1014 * No newline; see if there is more data to be read...
1015 */
1016
1017 if (!http->blocking && !_httpWait(http, 10000, 1))
1018 {
1019 DEBUG_puts("httpGets: Timed out!");
1020 #ifdef WIN32
1021 http->error = WSAETIMEDOUT;
1022 #else
1023 http->error = ETIMEDOUT;
1024 #endif /* WIN32 */
1025 return (NULL);
1026 }
1027
1028 #ifdef HAVE_SSL
1029 if (http->tls)
1030 bytes = http_read_ssl(http, http->buffer + http->used,
1031 HTTP_MAX_BUFFER - http->used);
1032 else
1033 #endif /* HAVE_SSL */
1034 bytes = recv(http->fd, http->buffer + http->used,
1035 HTTP_MAX_BUFFER - http->used, 0);
1036
1037 DEBUG_printf(("httpGets: read %d bytes...\n", bytes));
1038
1039 if (bytes < 0)
1040 {
1041 /*
1042 * Nope, can't get a line this time...
1043 */
1044
1045 #ifdef WIN32
1046 if (WSAGetLastError() != http->error)
1047 {
1048 http->error = WSAGetLastError();
1049 continue;
1050 }
1051
1052 DEBUG_printf(("httpGets: recv() error %d!\n", WSAGetLastError()));
1053 #else
1054 DEBUG_printf(("httpGets: recv() error %d!\n", errno));
1055
1056 if (errno == EINTR)
1057 continue;
1058 else if (errno != http->error)
1059 {
1060 http->error = errno;
1061 continue;
1062 }
1063 #endif /* WIN32 */
1064
1065 return (NULL);
1066 }
1067 else if (bytes == 0)
1068 {
1069 http->error = EPIPE;
1070
1071 return (NULL);
1072 }
1073
1074 /*
1075 * Yup, update the amount used...
1076 */
1077
1078 http->used += bytes;
1079 }
1080
1081 /*
1082 * Now copy as much of the current line as possible...
1083 */
1084
1085 for (bufptr = http->buffer, bufend = http->buffer + http->used;
1086 lineptr < lineend && bufptr < bufend;)
1087 {
1088 if (*bufptr == 0x0a)
1089 {
1090 eol = 1;
1091 bufptr ++;
1092 break;
1093 }
1094 else if (*bufptr == 0x0d)
1095 bufptr ++;
1096 else
1097 *lineptr++ = *bufptr++;
1098 }
1099
1100 http->used -= (int)(bufptr - http->buffer);
1101 if (http->used > 0)
1102 memmove(http->buffer, bufptr, http->used);
1103
1104 if (eol)
1105 {
1106 /*
1107 * End of line...
1108 */
1109
1110 http->activity = time(NULL);
1111
1112 *lineptr = '\0';
1113
1114 DEBUG_printf(("httpGets: Returning \"%s\"\n", line));
1115
1116 return (line);
1117 }
1118 }
1119
1120 DEBUG_puts("httpGets: No new line available!");
1121
1122 return (NULL);
1123 }
1124
1125
1126 /*
1127 * 'httpHead()' - Send a HEAD request to the server.
1128 */
1129
1130 int /* O - Status of call (0 = success) */
1131 httpHead(http_t *http, /* I - Connection to server */
1132 const char *uri) /* I - URI for head */
1133 {
1134 return (http_send(http, HTTP_HEAD, uri));
1135 }
1136
1137
1138 /*
1139 * 'httpInitialize()' - Initialize the HTTP interface library and set the
1140 * default HTTP proxy (if any).
1141 */
1142
1143 void
1144 httpInitialize(void)
1145 {
1146 #ifdef HAVE_LIBSSL
1147 # ifndef WIN32
1148 struct timeval curtime; /* Current time in microseconds */
1149 # endif /* !WIN32 */
1150 int i; /* Looping var */
1151 unsigned char data[1024]; /* Seed data */
1152 #endif /* HAVE_LIBSSL */
1153
1154 #ifdef WIN32
1155 WSADATA winsockdata; /* WinSock data */
1156 static int initialized = 0; /* Has WinSock been initialized? */
1157
1158
1159 if (!initialized)
1160 WSAStartup(MAKEWORD(1,1), &winsockdata);
1161 #elif !defined(SO_NOSIGPIPE)
1162 /*
1163 * Ignore SIGPIPE signals...
1164 */
1165
1166 # ifdef HAVE_SIGSET
1167 sigset(SIGPIPE, SIG_IGN);
1168 # elif defined(HAVE_SIGACTION)
1169 struct sigaction action; /* POSIX sigaction data */
1170
1171
1172 memset(&action, 0, sizeof(action));
1173 action.sa_handler = SIG_IGN;
1174 sigaction(SIGPIPE, &action, NULL);
1175 # else
1176 signal(SIGPIPE, SIG_IGN);
1177 # endif /* !SO_NOSIGPIPE */
1178 #endif /* WIN32 */
1179
1180 #ifdef HAVE_GNUTLS
1181 gnutls_global_init();
1182 #endif /* HAVE_GNUTLS */
1183
1184 #ifdef HAVE_LIBSSL
1185 SSL_load_error_strings();
1186 SSL_library_init();
1187
1188 /*
1189 * Using the current time is a dubious random seed, but on some systems
1190 * it is the best we can do (on others, this seed isn't even used...)
1191 */
1192
1193 # ifdef WIN32
1194 # else
1195 gettimeofday(&curtime, NULL);
1196 srand(curtime.tv_sec + curtime.tv_usec);
1197 # endif /* WIN32 */
1198
1199 for (i = 0; i < sizeof(data); i ++)
1200 data[i] = rand();
1201
1202 RAND_seed(data, sizeof(data));
1203 #endif /* HAVE_LIBSSL */
1204 }
1205
1206
1207 /*
1208 * 'httpOptions()' - Send an OPTIONS request to the server.
1209 */
1210
1211 int /* O - Status of call (0 = success) */
1212 httpOptions(http_t *http, /* I - Connection to server */
1213 const char *uri) /* I - URI for options */
1214 {
1215 return (http_send(http, HTTP_OPTIONS, uri));
1216 }
1217
1218
1219 /*
1220 * 'httpPost()' - Send a POST request to the server.
1221 */
1222
1223 int /* O - Status of call (0 = success) */
1224 httpPost(http_t *http, /* I - Connection to server */
1225 const char *uri) /* I - URI for post */
1226 {
1227 return (http_send(http, HTTP_POST, uri));
1228 }
1229
1230
1231 /*
1232 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
1233 *
1234 * @private@
1235 */
1236
1237 int /* O - Number of bytes written */
1238 httpPrintf(http_t *http, /* I - Connection to server */
1239 const char *format, /* I - printf-style format string */
1240 ...) /* I - Additional args as needed */
1241 {
1242 int bytes; /* Number of bytes to write */
1243 char buf[16384]; /* Buffer for formatted string */
1244 va_list ap; /* Variable argument pointer */
1245
1246
1247 DEBUG_printf(("httpPrintf(http=%p, format=\"%s\", ...)\n", http, format));
1248
1249 va_start(ap, format);
1250 bytes = vsnprintf(buf, sizeof(buf), format, ap);
1251 va_end(ap);
1252
1253 DEBUG_printf(("httpPrintf: %s", buf));
1254
1255 if (http->data_encoding == HTTP_ENCODE_FIELDS)
1256 return (httpWrite2(http, buf, bytes));
1257 else
1258 {
1259 if (http->wused)
1260 {
1261 DEBUG_puts(" flushing existing data...");
1262
1263 if (httpFlushWrite(http) < 0)
1264 return (-1);
1265 }
1266
1267 return (http_write(http, buf, bytes));
1268 }
1269 }
1270
1271
1272 /*
1273 * 'httpPut()' - Send a PUT request to the server.
1274 */
1275
1276 int /* O - Status of call (0 = success) */
1277 httpPut(http_t *http, /* I - Connection to server */
1278 const char *uri) /* I - URI to put */
1279 {
1280 return (http_send(http, HTTP_PUT, uri));
1281 }
1282
1283
1284 /*
1285 * 'httpRead()' - Read data from a HTTP connection.
1286 *
1287 * This function is deprecated. Use the httpRead2() function which can
1288 * read more than 2GB of data.
1289 *
1290 * @deprecated@
1291 */
1292
1293 int /* O - Number of bytes read */
1294 httpRead(http_t *http, /* I - Connection to server */
1295 char *buffer, /* I - Buffer for data */
1296 int length) /* I - Maximum number of bytes */
1297 {
1298 return ((int)httpRead2(http, buffer, length));
1299 }
1300
1301
1302 /*
1303 * 'httpRead2()' - Read data from a HTTP connection.
1304 *
1305 * @since CUPS 1.2/Mac OS X 10.5@
1306 */
1307
1308 ssize_t /* O - Number of bytes read */
1309 httpRead2(http_t *http, /* I - Connection to server */
1310 char *buffer, /* I - Buffer for data */
1311 size_t length) /* I - Maximum number of bytes */
1312 {
1313 ssize_t bytes; /* Bytes read */
1314 char len[32]; /* Length string */
1315
1316
1317 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT ")\n",
1318 http, buffer, CUPS_LLCAST length));
1319
1320 if (http == NULL || buffer == NULL)
1321 return (-1);
1322
1323 http->activity = time(NULL);
1324
1325 if (length <= 0)
1326 return (0);
1327
1328 if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
1329 http->data_remaining <= 0)
1330 {
1331 DEBUG_puts("httpRead2: Getting chunk length...");
1332
1333 if (httpGets(len, sizeof(len), http) == NULL)
1334 {
1335 DEBUG_puts("httpRead2: Could not get length!");
1336 return (0);
1337 }
1338
1339 http->data_remaining = strtoll(len, NULL, 16);
1340 if (http->data_remaining < 0)
1341 {
1342 DEBUG_puts("httpRead2: Negative chunk length!");
1343 return (0);
1344 }
1345 }
1346
1347 DEBUG_printf(("httpRead2: data_remaining=" CUPS_LLFMT "\n",
1348 CUPS_LLCAST http->data_remaining));
1349
1350 if (http->data_remaining <= 0)
1351 {
1352 /*
1353 * A zero-length chunk ends a transfer; unless we are reading POST
1354 * data, go idle...
1355 */
1356
1357 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1358 httpGets(len, sizeof(len), http);
1359
1360 if (http->state == HTTP_POST_RECV)
1361 http->state ++;
1362 else
1363 http->state = HTTP_WAITING;
1364
1365 /*
1366 * Prevent future reads for this request...
1367 */
1368
1369 http->data_encoding = HTTP_ENCODE_LENGTH;
1370
1371 return (0);
1372 }
1373 else if (length > (size_t)http->data_remaining)
1374 length = (size_t)http->data_remaining;
1375
1376 if (http->used == 0 && length <= 256)
1377 {
1378 /*
1379 * Buffer small reads for better performance...
1380 */
1381
1382 if (!http->blocking && !httpWait(http, 10000))
1383 return (0);
1384
1385 if (http->data_remaining > sizeof(http->buffer))
1386 bytes = sizeof(http->buffer);
1387 else
1388 bytes = http->data_remaining;
1389
1390 #ifdef HAVE_SSL
1391 if (http->tls)
1392 bytes = http_read_ssl(http, http->buffer, bytes);
1393 else
1394 #endif /* HAVE_SSL */
1395 {
1396 DEBUG_printf(("httpRead2: reading %d bytes from socket into buffer...\n",
1397 (int)bytes));
1398
1399 bytes = recv(http->fd, http->buffer, bytes, 0);
1400
1401 DEBUG_printf(("httpRead2: read %d bytes from socket into buffer...\n",
1402 (int)bytes));
1403 }
1404
1405 if (bytes > 0)
1406 http->used = bytes;
1407 else if (bytes < 0)
1408 {
1409 #ifdef WIN32
1410 http->error = WSAGetLastError();
1411 return (-1);
1412 #else
1413 if (errno != EINTR)
1414 {
1415 http->error = errno;
1416 return (-1);
1417 }
1418 #endif /* WIN32 */
1419 }
1420 else
1421 {
1422 http->error = EPIPE;
1423 return (0);
1424 }
1425 }
1426
1427 if (http->used > 0)
1428 {
1429 if (length > (size_t)http->used)
1430 length = (size_t)http->used;
1431
1432 bytes = (ssize_t)length;
1433
1434 DEBUG_printf(("httpRead2: grabbing %d bytes from input buffer...\n",
1435 (int)bytes));
1436
1437 memcpy(buffer, http->buffer, length);
1438 http->used -= (int)length;
1439
1440 if (http->used > 0)
1441 memmove(http->buffer, http->buffer + length, http->used);
1442 }
1443 #ifdef HAVE_SSL
1444 else if (http->tls)
1445 {
1446 if (!http->blocking && !httpWait(http, 10000))
1447 return (0);
1448
1449 bytes = (ssize_t)http_read_ssl(http, buffer, (int)length);
1450 }
1451 #endif /* HAVE_SSL */
1452 else
1453 {
1454 if (!http->blocking && !httpWait(http, 10000))
1455 return (0);
1456
1457 DEBUG_printf(("httpRead2: reading " CUPS_LLFMT " bytes from socket...\n",
1458 CUPS_LLCAST length));
1459
1460 #ifdef WIN32
1461 bytes = (ssize_t)recv(http->fd, buffer, (int)length, 0);
1462 #else
1463 while ((bytes = recv(http->fd, buffer, length, 0)) < 0)
1464 if (errno != EINTR && errno != EAGAIN)
1465 break;
1466 #endif /* WIN32 */
1467
1468 DEBUG_printf(("httpRead2: read " CUPS_LLFMT " bytes from socket...\n",
1469 CUPS_LLCAST bytes));
1470 }
1471
1472 if (bytes > 0)
1473 {
1474 http->data_remaining -= bytes;
1475
1476 if (http->data_remaining <= INT_MAX)
1477 http->_data_remaining = (int)http->data_remaining;
1478 else
1479 http->_data_remaining = INT_MAX;
1480 }
1481 else if (bytes < 0)
1482 {
1483 #ifdef WIN32
1484 http->error = WSAGetLastError();
1485 #else
1486 if (errno == EINTR || errno == EAGAIN)
1487 bytes = 0;
1488 else
1489 http->error = errno;
1490 #endif /* WIN32 */
1491 }
1492 else
1493 {
1494 http->error = EPIPE;
1495 return (0);
1496 }
1497
1498 if (http->data_remaining == 0)
1499 {
1500 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1501 httpGets(len, sizeof(len), http);
1502
1503 if (http->data_encoding != HTTP_ENCODE_CHUNKED)
1504 {
1505 if (http->state == HTTP_POST_RECV)
1506 http->state ++;
1507 else
1508 http->state = HTTP_WAITING;
1509 }
1510 }
1511
1512 #ifdef DEBUG
1513 http_debug_hex("httpRead2", buffer, (int)bytes);
1514 #endif /* DEBUG */
1515
1516 return (bytes);
1517 }
1518
1519
1520 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
1521 /*
1522 * '_httpReadCDSA()' - Read function for the CDSA library.
1523 */
1524
1525 OSStatus /* O - -1 on error, 0 on success */
1526 _httpReadCDSA(
1527 SSLConnectionRef connection, /* I - SSL/TLS connection */
1528 void *data, /* I - Data buffer */
1529 size_t *dataLength) /* IO - Number of bytes */
1530 {
1531 OSStatus result; /* Return value */
1532 ssize_t bytes; /* Number of bytes read */
1533 http_t *http; /* HTTP connection */
1534
1535
1536 http = (http_t *)connection;
1537
1538 if (!http->blocking)
1539 {
1540 /*
1541 * Make sure we have data before we read...
1542 */
1543
1544 if (!_httpWait(http, 10000, 0))
1545 {
1546 http->error = ETIMEDOUT;
1547 return (-1);
1548 }
1549 }
1550
1551 do
1552 {
1553 bytes = recv(http->fd, data, *dataLength, 0);
1554 }
1555 while (bytes == -1 && errno == EINTR);
1556
1557 if (bytes == *dataLength)
1558 {
1559 result = 0;
1560 }
1561 else if (bytes > 0)
1562 {
1563 *dataLength = bytes;
1564 result = errSSLWouldBlock;
1565 }
1566 else
1567 {
1568 *dataLength = 0;
1569
1570 if (bytes == 0)
1571 result = errSSLClosedGraceful;
1572 else if (errno == EAGAIN)
1573 result = errSSLWouldBlock;
1574 else
1575 result = errSSLClosedAbort;
1576 }
1577
1578 return (result);
1579 }
1580 #endif /* HAVE_SSL && HAVE_CDSASSL */
1581
1582
1583 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
1584 /*
1585 * '_httpReadGNUTLS()' - Read function for the GNU TLS library.
1586 */
1587
1588 ssize_t /* O - Number of bytes read or -1 on error */
1589 _httpReadGNUTLS(
1590 gnutls_transport_ptr ptr, /* I - Connection to server */
1591 void *data, /* I - Buffer */
1592 size_t length) /* I - Number of bytes to read */
1593 {
1594 http_t *http; /* HTTP connection */
1595
1596
1597 http = (http_t *)ptr;
1598
1599 if (!http->blocking)
1600 {
1601 /*
1602 * Make sure we have data before we read...
1603 */
1604
1605 if (!_httpWait(http, 10000, 0))
1606 {
1607 http->error = ETIMEDOUT;
1608 return (-1);
1609 }
1610 }
1611
1612 return (recv(http->fd, data, length, 0));
1613 }
1614 #endif /* HAVE_SSL && HAVE_GNUTLS */
1615
1616
1617 /*
1618 * 'httpReconnect()' - Reconnect to a HTTP server.
1619 */
1620
1621 int /* O - 0 on success, non-zero on failure */
1622 httpReconnect(http_t *http) /* I - Connection to server */
1623 {
1624 http_addrlist_t *addr; /* Connected address */
1625 #ifdef DEBUG
1626 http_addrlist_t *current; /* Current address */
1627 char temp[256]; /* Temporary address string */
1628 #endif /* DEBUG */
1629
1630
1631 DEBUG_printf(("httpReconnect(http=%p)\n", http));
1632
1633 if (!http)
1634 return (-1);
1635
1636 #ifdef HAVE_SSL
1637 if (http->tls)
1638 {
1639 DEBUG_puts("httpReconnect: Shutting down SSL/TLS...");
1640 http_shutdown_ssl(http);
1641 }
1642 #endif /* HAVE_SSL */
1643
1644 /*
1645 * Close any previously open socket...
1646 */
1647
1648 if (http->fd >= 0)
1649 {
1650 DEBUG_printf(("httpReconnect: Closing socket %d...\n", http->fd));
1651
1652 #ifdef WIN32
1653 closesocket(http->fd);
1654 #else
1655 close(http->fd);
1656 #endif /* WIN32 */
1657
1658 usleep(100000);
1659
1660 http->fd = -1;
1661 }
1662
1663 /*
1664 * Connect to the server...
1665 */
1666
1667 #ifdef DEBUG
1668 for (current = http->addrlist; current; current = current->next)
1669 DEBUG_printf(("httpReconnect: Address %s:%d\n",
1670 httpAddrString(&(current->addr), temp, sizeof(temp)),
1671 _httpAddrPort(&(current->addr))));
1672 #endif /* DEBUG */
1673
1674 if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL)
1675 {
1676 /*
1677 * Unable to connect...
1678 */
1679
1680 #ifdef WIN32
1681 http->error = WSAGetLastError();
1682 #else
1683 http->error = errno;
1684 #endif /* WIN32 */
1685 http->status = HTTP_ERROR;
1686
1687 DEBUG_printf(("httpReconnect: httpAddrConnect failed: %s\n",
1688 strerror(http->error)));
1689
1690 return (-1);
1691 }
1692
1693 DEBUG_printf(("httpReconnect: New socket=%d\n", http->fd));
1694
1695 http->hostaddr = &(addr->addr);
1696 http->error = 0;
1697 http->status = HTTP_CONTINUE;
1698
1699 #ifdef HAVE_SSL
1700 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
1701 {
1702 /*
1703 * Always do encryption via SSL.
1704 */
1705
1706 if (http_setup_ssl(http) != 0)
1707 {
1708 # ifdef WIN32
1709 closesocket(http->fd);
1710 # else
1711 close(http->fd);
1712 # endif /* WIN32 */
1713
1714 return (-1);
1715 }
1716 }
1717 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
1718 return (http_upgrade(http));
1719 #endif /* HAVE_SSL */
1720
1721 DEBUG_printf(("httpReconnect: Connected to %s:%d...\n",
1722 httpAddrString(http->hostaddr, temp, sizeof(temp)),
1723 _httpAddrPort(http->hostaddr)));
1724
1725 return (0);
1726 }
1727
1728
1729 /*
1730 * 'httpSetAuthString()' - Set the current authorization string.
1731 *
1732 * This function just stores a copy of the current authorization string in
1733 * the HTTP connection object. You must still call httpSetField() to set
1734 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
1735 * httpHead(), httpOptions(), httpPost, or httpPut().
1736 *
1737 * @since CUPS 1.3/Mac OS X 10.5@
1738 */
1739
1740 void
1741 httpSetAuthString(http_t *http, /* I - Connection to server */
1742 const char *scheme, /* I - Auth scheme (NULL to clear it) */
1743 const char *data) /* I - Auth data (NULL for none) */
1744 {
1745 /*
1746 * Range check input...
1747 */
1748
1749 if (!http)
1750 return;
1751
1752 if (http->authstring && http->authstring != http->_authstring)
1753 free(http->authstring);
1754
1755 http->authstring = http->_authstring;
1756
1757 if (scheme)
1758 {
1759 /*
1760 * Set the current authorization string...
1761 */
1762
1763 int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1;
1764 char *temp;
1765
1766 if (len > (int)sizeof(http->_authstring))
1767 {
1768 if ((temp = malloc(len)) == NULL)
1769 len = sizeof(http->_authstring);
1770 else
1771 http->authstring = temp;
1772 }
1773
1774 if (data)
1775 snprintf(http->authstring, len, "%s %s", scheme, data);
1776 else
1777 strlcpy(http->authstring, scheme, len);
1778 }
1779 else
1780 {
1781 /*
1782 * Clear the current authorization string...
1783 */
1784
1785 http->_authstring[0] = '\0';
1786 }
1787 }
1788
1789
1790 /*
1791 * 'httpSetCookie()' - Set the cookie value(s)...
1792 *
1793 * @since CUPS 1.1.19/Mac OS X 10.3@
1794 */
1795
1796 void
1797 httpSetCookie(http_t *http, /* I - Connection */
1798 const char *cookie) /* I - Cookie string */
1799 {
1800 if (!http)
1801 return;
1802
1803 if (http->cookie)
1804 free(http->cookie);
1805
1806 if (cookie)
1807 http->cookie = strdup(cookie);
1808 else
1809 http->cookie = NULL;
1810 }
1811
1812
1813 /*
1814 * 'httpSetExpect()' - Set the Expect: header in a request.
1815 *
1816 * Currently only HTTP_CONTINUE is supported for the "expect" argument.
1817 *
1818 * @since CUPS 1.2/Mac OS X 10.5@
1819 */
1820
1821 void
1822 httpSetExpect(http_t *http, /* I - Connection to server */
1823 http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */
1824 {
1825 if (http)
1826 http->expect = expect;
1827 }
1828
1829
1830 /*
1831 * 'httpSetField()' - Set the value of an HTTP header.
1832 */
1833
1834 void
1835 httpSetField(http_t *http, /* I - Connection to server */
1836 http_field_t field, /* I - Field index */
1837 const char *value) /* I - Value */
1838 {
1839 if (http == NULL ||
1840 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
1841 field > HTTP_FIELD_WWW_AUTHENTICATE ||
1842 value == NULL)
1843 return;
1844
1845 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
1846
1847 /*
1848 * Special case for Authorization: as its contents can be
1849 * longer than HTTP_MAX_VALUE
1850 */
1851
1852 if (field == HTTP_FIELD_AUTHORIZATION)
1853 {
1854 if (http->field_authorization)
1855 free(http->field_authorization);
1856
1857 http->field_authorization = strdup(value);
1858 }
1859 }
1860
1861
1862 /*
1863 * 'httpSetLength()' - Set the content-length and content-encoding.
1864 *
1865 * @since CUPS 1.2/Mac OS X 10.5@
1866 */
1867
1868 void
1869 httpSetLength(http_t *http, /* I - Connection to server */
1870 size_t length) /* I - Length (0 for chunked) */
1871 {
1872 if (!http)
1873 return;
1874
1875 if (!length)
1876 {
1877 strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked");
1878 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
1879 }
1880 else
1881 {
1882 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
1883 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
1884 CUPS_LLFMT, CUPS_LLCAST length);
1885 }
1886 }
1887
1888
1889 /*
1890 * 'httpTrace()' - Send an TRACE request to the server.
1891 */
1892
1893 int /* O - Status of call (0 = success) */
1894 httpTrace(http_t *http, /* I - Connection to server */
1895 const char *uri) /* I - URI for trace */
1896 {
1897 return (http_send(http, HTTP_TRACE, uri));
1898 }
1899
1900
1901 /*
1902 * 'httpUpdate()' - Update the current HTTP state for incoming data.
1903 */
1904
1905 http_status_t /* O - HTTP status */
1906 httpUpdate(http_t *http) /* I - Connection to server */
1907 {
1908 char line[32768], /* Line from connection... */
1909 *value; /* Pointer to value on line */
1910 http_field_t field; /* Field index */
1911 int major, minor, /* HTTP version numbers */
1912 status; /* Request status */
1913
1914
1915 DEBUG_printf(("httpUpdate(http=%p), state=%d\n", http, http->state));
1916
1917 /*
1918 * Flush pending data, if any...
1919 */
1920
1921 if (http->wused)
1922 {
1923 DEBUG_puts(" flushing buffer...");
1924
1925 if (httpFlushWrite(http) < 0)
1926 return (HTTP_ERROR);
1927 }
1928
1929 /*
1930 * If we haven't issued any commands, then there is nothing to "update"...
1931 */
1932
1933 if (http->state == HTTP_WAITING)
1934 return (HTTP_CONTINUE);
1935
1936 /*
1937 * Grab all of the lines we can from the connection...
1938 */
1939
1940 while (httpGets(line, sizeof(line), http) != NULL)
1941 {
1942 DEBUG_printf(("httpUpdate: Got \"%s\"\n", line));
1943
1944 if (line[0] == '\0')
1945 {
1946 /*
1947 * Blank line means the start of the data section (if any). Return
1948 * the result code, too...
1949 *
1950 * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
1951 * Instead, we just return HTTP_CONTINUE to the caller and keep on
1952 * tryin'...
1953 */
1954
1955 if (http->status == HTTP_CONTINUE)
1956 return (http->status);
1957
1958 if (http->status < HTTP_BAD_REQUEST)
1959 http->digest_tries = 0;
1960
1961 #ifdef HAVE_SSL
1962 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
1963 {
1964 if (http_setup_ssl(http) != 0)
1965 {
1966 # ifdef WIN32
1967 closesocket(http->fd);
1968 # else
1969 close(http->fd);
1970 # endif /* WIN32 */
1971
1972 return (HTTP_ERROR);
1973 }
1974
1975 return (HTTP_CONTINUE);
1976 }
1977 #endif /* HAVE_SSL */
1978
1979 httpGetLength2(http);
1980
1981 switch (http->state)
1982 {
1983 case HTTP_GET :
1984 case HTTP_POST :
1985 case HTTP_POST_RECV :
1986 case HTTP_PUT :
1987 http->state ++;
1988 case HTTP_POST_SEND :
1989 case HTTP_HEAD :
1990 break;
1991
1992 default :
1993 http->state = HTTP_WAITING;
1994 break;
1995 }
1996
1997 return (http->status);
1998 }
1999 else if (strncmp(line, "HTTP/", 5) == 0)
2000 {
2001 /*
2002 * Got the beginning of a response...
2003 */
2004
2005 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
2006 return (HTTP_ERROR);
2007
2008 http->version = (http_version_t)(major * 100 + minor);
2009 http->status = (http_status_t)status;
2010 }
2011 else if ((value = strchr(line, ':')) != NULL)
2012 {
2013 /*
2014 * Got a value...
2015 */
2016
2017 *value++ = '\0';
2018 while (isspace(*value & 255))
2019 value ++;
2020
2021 /*
2022 * Be tolerants of servers that send unknown attribute fields...
2023 */
2024
2025 if (!strcasecmp(line, "expect"))
2026 {
2027 /*
2028 * "Expect: 100-continue" or similar...
2029 */
2030
2031 http->expect = (http_status_t)atoi(value);
2032 }
2033 else if (!strcasecmp(line, "cookie"))
2034 {
2035 /*
2036 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
2037 */
2038
2039 httpSetCookie(http, value);
2040 }
2041 else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
2042 {
2043 DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line));
2044 continue;
2045 }
2046 else
2047 httpSetField(http, field, value);
2048 }
2049 else
2050 {
2051 http->status = HTTP_ERROR;
2052 return (HTTP_ERROR);
2053 }
2054 }
2055
2056 /*
2057 * See if there was an error...
2058 */
2059
2060 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
2061 return (http->status);
2062
2063 if (http->error)
2064 {
2065 DEBUG_printf(("httpUpdate: socket error %d - %s\n", http->error,
2066 strerror(http->error)));
2067 http->status = HTTP_ERROR;
2068 return (HTTP_ERROR);
2069 }
2070
2071 /*
2072 * If we haven't already returned, then there is nothing new...
2073 */
2074
2075 return (HTTP_CONTINUE);
2076 }
2077
2078
2079 /*
2080 * '_httpWait()' - Wait for data available on a connection (no flush).
2081 */
2082
2083 int /* O - 1 if data is available, 0 otherwise */
2084 _httpWait(http_t *http, /* I - Connection to server */
2085 int msec, /* I - Milliseconds to wait */
2086 int usessl) /* I - Use SSL context? */
2087 {
2088 #ifdef HAVE_POLL
2089 struct pollfd pfd; /* Polled file descriptor */
2090 #else
2091 fd_set input_set; /* select() input set */
2092 struct timeval timeout; /* Timeout */
2093 #endif /* HAVE_POLL */
2094 int nfds; /* Result from select()/poll() */
2095
2096
2097 DEBUG_printf(("_httpWait(http=%p, msec=%d, usessl=%d)\n", http, msec, usessl));
2098
2099 if (http->fd < 0)
2100 return (0);
2101
2102 /*
2103 * Check the SSL/TLS buffers for data first...
2104 */
2105
2106 #ifdef HAVE_SSL
2107 if (http->tls && usessl)
2108 {
2109 # ifdef HAVE_LIBSSL
2110 if (SSL_pending((SSL *)(http->tls)))
2111 return (1);
2112 # elif defined(HAVE_GNUTLS)
2113 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2114 return (1);
2115 # elif defined(HAVE_CDSASSL)
2116 size_t bytes; /* Bytes that are available */
2117
2118 if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) &&
2119 bytes > 0)
2120 return (1);
2121 # endif /* HAVE_LIBSSL */
2122 }
2123 #endif /* HAVE_SSL */
2124
2125 /*
2126 * Then try doing a select() or poll() to poll the socket...
2127 */
2128
2129 #ifdef HAVE_POLL
2130 pfd.fd = http->fd;
2131 pfd.events = POLLIN;
2132
2133 while ((nfds = poll(&pfd, 1, msec)) < 0 && errno == EINTR);
2134
2135 #else
2136 do
2137 {
2138 FD_ZERO(&input_set);
2139 FD_SET(http->fd, &input_set);
2140
2141 DEBUG_printf(("_httpWait: msec=%d, http->fd=%d\n", msec, http->fd));
2142
2143 if (msec >= 0)
2144 {
2145 timeout.tv_sec = msec / 1000;
2146 timeout.tv_usec = (msec % 1000) * 1000;
2147
2148 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
2149 }
2150 else
2151 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
2152
2153 DEBUG_printf(("_httpWait: select() returned %d...\n", nfds));
2154 }
2155 # ifdef WIN32
2156 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2157 # else
2158 while (nfds < 0 && errno == EINTR);
2159 # endif /* WIN32 */
2160 #endif /* HAVE_POLL */
2161
2162 DEBUG_printf(("_httpWait: returning with nfds=%d...\n", nfds));
2163
2164 return (nfds > 0);
2165 }
2166
2167
2168 /*
2169 * 'httpWait()' - Wait for data available on a connection.
2170 *
2171 * @since CUPS 1.1.19/Mac OS X 10.3@
2172 */
2173
2174 int /* O - 1 if data is available, 0 otherwise */
2175 httpWait(http_t *http, /* I - Connection to server */
2176 int msec) /* I - Milliseconds to wait */
2177 {
2178 /*
2179 * First see if there is data in the buffer...
2180 */
2181
2182 if (http == NULL)
2183 return (0);
2184
2185 if (http->used)
2186 return (1);
2187
2188 /*
2189 * Flush pending data, if any...
2190 */
2191
2192 if (http->wused)
2193 {
2194 if (httpFlushWrite(http) < 0)
2195 return (0);
2196 }
2197
2198 /*
2199 * If not, check the SSL/TLS buffers and do a select() on the connection...
2200 */
2201
2202 return (_httpWait(http, msec, 1));
2203 }
2204
2205
2206 /*
2207 * 'httpWrite()' - Write data to a HTTP connection.
2208 *
2209 * This function is deprecated. Use the httpWrite2() function which can
2210 * write more than 2GB of data.
2211 *
2212 * @deprecated@
2213 */
2214
2215 int /* O - Number of bytes written */
2216 httpWrite(http_t *http, /* I - Connection to server */
2217 const char *buffer, /* I - Buffer for data */
2218 int length) /* I - Number of bytes to write */
2219 {
2220 return ((int)httpWrite2(http, buffer, length));
2221 }
2222
2223
2224 /*
2225 * 'httpWrite2()' - Write data to a HTTP connection.
2226 *
2227 * @since CUPS 1.2/Mac OS X 10.5@
2228 */
2229
2230 ssize_t /* O - Number of bytes written */
2231 httpWrite2(http_t *http, /* I - Connection to server */
2232 const char *buffer, /* I - Buffer for data */
2233 size_t length) /* I - Number of bytes to write */
2234 {
2235 ssize_t bytes; /* Bytes written */
2236
2237
2238 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")\n", http,
2239 buffer, CUPS_LLCAST length));
2240
2241 /*
2242 * Range check input...
2243 */
2244
2245 if (http == NULL || buffer == NULL)
2246 return (-1);
2247
2248 /*
2249 * Mark activity on the connection...
2250 */
2251
2252 http->activity = time(NULL);
2253
2254 /*
2255 * Buffer small writes for better performance...
2256 */
2257
2258 if (length > 0)
2259 {
2260 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
2261 {
2262 DEBUG_printf(("httpWrite2: Flushing buffer (wused=%d, length="
2263 CUPS_LLFMT ")\n", http->wused, CUPS_LLCAST length));
2264
2265 httpFlushWrite(http);
2266 }
2267
2268 if ((length + http->wused) <= sizeof(http->wbuffer) &&
2269 length < sizeof(http->wbuffer))
2270 {
2271 /*
2272 * Write to buffer...
2273 */
2274
2275 DEBUG_printf(("httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...\n",
2276 CUPS_LLCAST length));
2277
2278 memcpy(http->wbuffer + http->wused, buffer, length);
2279 http->wused += (int)length;
2280 bytes = (ssize_t)length;
2281 }
2282 else
2283 {
2284 /*
2285 * Otherwise write the data directly...
2286 */
2287
2288 DEBUG_printf(("httpWrite2: Writing " CUPS_LLFMT " bytes to socket...\n",
2289 CUPS_LLCAST length));
2290
2291 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2292 bytes = (ssize_t)http_write_chunk(http, buffer, (int)length);
2293 else
2294 bytes = (ssize_t)http_write(http, buffer, (int)length);
2295
2296 DEBUG_printf(("httpWrite2: Wrote " CUPS_LLFMT " bytes...\n",
2297 CUPS_LLCAST bytes));
2298 }
2299
2300 if (http->data_encoding == HTTP_ENCODE_LENGTH)
2301 http->data_remaining -= bytes;
2302 }
2303 else
2304 bytes = 0;
2305
2306 /*
2307 * Handle end-of-request processing...
2308 */
2309
2310 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
2311 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
2312 {
2313 /*
2314 * Finished with the transfer; unless we are sending POST or PUT
2315 * data, go idle...
2316 */
2317
2318 DEBUG_puts("httpWrite: changing states...");
2319
2320 if (http->wused)
2321 httpFlushWrite(http);
2322
2323 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2324 {
2325 /*
2326 * Send a 0-length chunk at the end of the request...
2327 */
2328
2329 http_write(http, "0\r\n\r\n", 5);
2330
2331 /*
2332 * Reset the data state...
2333 */
2334
2335 http->data_encoding = HTTP_ENCODE_LENGTH;
2336 http->data_remaining = 0;
2337 }
2338
2339 if (http->state == HTTP_POST_RECV)
2340 http->state ++;
2341 else if (http->state == HTTP_PUT_RECV)
2342 http->state = HTTP_STATUS;
2343 else
2344 http->state = HTTP_WAITING;
2345 }
2346
2347 return (bytes);
2348 }
2349
2350
2351 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2352 /*
2353 * '_httpWriteCDSA()' - Write function for the CDSA library.
2354 */
2355
2356 OSStatus /* O - -1 on error, 0 on success */
2357 _httpWriteCDSA(
2358 SSLConnectionRef connection, /* I - SSL/TLS connection */
2359 const void *data, /* I - Data buffer */
2360 size_t *dataLength) /* IO - Number of bytes */
2361 {
2362 OSStatus result; /* Return value */
2363 ssize_t bytes; /* Number of bytes read */
2364 http_t *http; /* HTTP connection */
2365
2366
2367 http = (http_t *)connection;
2368
2369 do
2370 {
2371 bytes = write(http->fd, data, *dataLength);
2372 }
2373 while (bytes == -1 && errno == EINTR);
2374
2375 if (bytes == *dataLength)
2376 {
2377 result = 0;
2378 }
2379 else if (bytes >= 0)
2380 {
2381 *dataLength = bytes;
2382 result = errSSLWouldBlock;
2383 }
2384 else
2385 {
2386 *dataLength = 0;
2387
2388 if (errno == EAGAIN)
2389 result = errSSLWouldBlock;
2390 else
2391 result = errSSLClosedAbort;
2392 }
2393
2394 return (result);
2395 }
2396 #endif /* HAVE_SSL && HAVE_CDSASSL */
2397
2398
2399 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
2400 /*
2401 * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
2402 */
2403
2404 ssize_t /* O - Number of bytes written or -1 on error */
2405 _httpWriteGNUTLS(
2406 gnutls_transport_ptr ptr, /* I - Connection to server */
2407 const void *data, /* I - Data buffer */
2408 size_t length) /* I - Number of bytes to write */
2409 {
2410 return (send(((http_t *)ptr)->fd, data, length, 0));
2411 }
2412 #endif /* HAVE_SSL && HAVE_GNUTLS */
2413
2414
2415 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
2416 /*
2417 * 'http_bio_ctrl()' - Control the HTTP connection.
2418 */
2419
2420 static long /* O - Result/data */
2421 http_bio_ctrl(BIO *h, /* I - BIO data */
2422 int cmd, /* I - Control command */
2423 long arg1, /* I - First argument */
2424 void *arg2) /* I - Second argument */
2425 {
2426 switch (cmd)
2427 {
2428 default :
2429 return (0);
2430
2431 case BIO_CTRL_RESET :
2432 h->ptr = NULL;
2433 return (0);
2434
2435 case BIO_C_SET_FILE_PTR :
2436 h->ptr = arg2;
2437 h->init = 1;
2438 return (1);
2439
2440 case BIO_C_GET_FILE_PTR :
2441 if (arg2)
2442 {
2443 *((void **)arg2) = h->ptr;
2444 return (1);
2445 }
2446 else
2447 return (0);
2448
2449 case BIO_CTRL_DUP :
2450 case BIO_CTRL_FLUSH :
2451 return (1);
2452 }
2453 }
2454
2455
2456 /*
2457 * 'http_bio_free()' - Free OpenSSL data.
2458 */
2459
2460 static int /* O - 1 on success, 0 on failure */
2461 http_bio_free(BIO *h) /* I - BIO data */
2462 {
2463 if (!h)
2464 return (0);
2465
2466 if (h->shutdown)
2467 {
2468 h->init = 0;
2469 h->flags = 0;
2470 }
2471
2472 return (1);
2473 }
2474
2475
2476 /*
2477 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
2478 */
2479
2480 static int /* O - 1 on success, 0 on failure */
2481 http_bio_new(BIO *h) /* I - BIO data */
2482 {
2483 if (!h)
2484 return (0);
2485
2486 h->init = 0;
2487 h->num = 0;
2488 h->ptr = NULL;
2489 h->flags = 0;
2490
2491 return (1);
2492 }
2493
2494
2495 /*
2496 * 'http_bio_puts()' - Send a string for OpenSSL.
2497 */
2498
2499 static int /* O - Bytes written */
2500 http_bio_puts(BIO *h, /* I - BIO data */
2501 const char *str) /* I - String to write */
2502 {
2503 #ifdef WIN32
2504 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
2505 #else
2506 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
2507 #endif /* WIN32 */
2508 }
2509
2510
2511 /*
2512 * 'http_bio_read()' - Read data for OpenSSL.
2513 */
2514
2515 static int /* O - Bytes read */
2516 http_bio_read(BIO *h, /* I - BIO data */
2517 char *buf, /* I - Buffer */
2518 int size) /* I - Number of bytes to read */
2519 {
2520 http_t *http; /* HTTP connection */
2521
2522
2523 http = (http_t *)h->ptr;
2524
2525 if (!http->blocking)
2526 {
2527 /*
2528 * Make sure we have data before we read...
2529 */
2530
2531 if (!_httpWait(http, 10000, 0))
2532 {
2533 #ifdef WIN32
2534 http->error = WSAETIMEDOUT;
2535 #else
2536 http->error = ETIMEDOUT;
2537 #endif /* WIN32 */
2538
2539 return (-1);
2540 }
2541 }
2542
2543 return (recv(http->fd, buf, size, 0));
2544 }
2545
2546
2547 /*
2548 * 'http_bio_write()' - Write data for OpenSSL.
2549 */
2550
2551 static int /* O - Bytes written */
2552 http_bio_write(BIO *h, /* I - BIO data */
2553 const char *buf, /* I - Buffer to write */
2554 int num) /* I - Number of bytes to write */
2555 {
2556 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
2557 }
2558 #endif /* HAVE_SSL && HAVE_LIBSSL */
2559
2560
2561 #ifdef DEBUG
2562 /*
2563 * 'http_debug_hex()' - Do a hex dump of a buffer.
2564 */
2565
2566 static void
2567 http_debug_hex(const char *prefix, /* I - Prefix for line */
2568 const char *buffer, /* I - Buffer to dump */
2569 int bytes) /* I - Bytes to dump */
2570 {
2571 int i, j, /* Looping vars */
2572 ch; /* Current character */
2573 char line[255], /* Line buffer */
2574 *start, /* Start of line after prefix */
2575 *ptr; /* Pointer into line */
2576
2577
2578 if (_cups_debug_fd < 0)
2579 return;
2580
2581 DEBUG_printf(("%s: %d bytes:\n", prefix, bytes));
2582
2583 snprintf(line, sizeof(line), "%s: ", prefix);
2584 start = line + strlen(line);
2585
2586 for (i = 0; i < bytes; i += 16)
2587 {
2588 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
2589 sprintf(ptr, "%02X", buffer[i + j] & 255);
2590
2591 while (j < 16)
2592 {
2593 strcpy(ptr, " ");
2594 ptr += 2;
2595 j ++;
2596 }
2597
2598 strcpy(ptr, " ");
2599 ptr += 2;
2600
2601 for (j = 0; j < 16 && (i + j) < bytes; j ++)
2602 {
2603 ch = buffer[i + j] & 255;
2604
2605 if (ch < ' ' || ch >= 127)
2606 ch = '.';
2607
2608 *ptr++ = ch;
2609 }
2610
2611 *ptr = '\0';
2612 DEBUG_puts(line);
2613 }
2614 }
2615 #endif /* DEBUG */
2616
2617
2618 /*
2619 * 'http_field()' - Return the field index for a field name.
2620 */
2621
2622 static http_field_t /* O - Field index */
2623 http_field(const char *name) /* I - String name */
2624 {
2625 int i; /* Looping var */
2626
2627
2628 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2629 if (strcasecmp(name, http_fields[i]) == 0)
2630 return ((http_field_t)i);
2631
2632 return (HTTP_FIELD_UNKNOWN);
2633 }
2634
2635
2636 #ifdef HAVE_SSL
2637 /*
2638 * 'http_read_ssl()' - Read from a SSL/TLS connection.
2639 */
2640
2641 static int /* O - Bytes read */
2642 http_read_ssl(http_t *http, /* I - Connection to server */
2643 char *buf, /* I - Buffer to store data */
2644 int len) /* I - Length of buffer */
2645 {
2646 # if defined(HAVE_LIBSSL)
2647 return (SSL_read((SSL *)(http->tls), buf, len));
2648
2649 # elif defined(HAVE_GNUTLS)
2650 return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));
2651
2652 # elif defined(HAVE_CDSASSL)
2653 int result; /* Return value */
2654 OSStatus error; /* Error info */
2655 size_t processed; /* Number of bytes processed */
2656
2657
2658 error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed);
2659
2660 switch (error)
2661 {
2662 case 0 :
2663 result = (int)processed;
2664 break;
2665 case errSSLClosedGraceful :
2666 result = 0;
2667 break;
2668 case errSSLWouldBlock :
2669 if (processed)
2670 result = (int)processed;
2671 else
2672 {
2673 result = -1;
2674 errno = EINTR;
2675 }
2676 break;
2677 default :
2678 errno = EPIPE;
2679 result = -1;
2680 break;
2681 }
2682
2683 return (result);
2684 # endif /* HAVE_LIBSSL */
2685 }
2686 #endif /* HAVE_SSL */
2687
2688
2689 /*
2690 * 'http_send()' - Send a request with all fields and the trailing blank line.
2691 */
2692
2693 static int /* O - 0 on success, non-zero on error */
2694 http_send(http_t *http, /* I - Connection to server */
2695 http_state_t request, /* I - Request code */
2696 const char *uri) /* I - URI */
2697 {
2698 int i; /* Looping var */
2699 char buf[1024]; /* Encoded URI buffer */
2700 static const char * const codes[] =
2701 { /* Request code strings */
2702 NULL,
2703 "OPTIONS",
2704 "GET",
2705 NULL,
2706 "HEAD",
2707 "POST",
2708 NULL,
2709 NULL,
2710 "PUT",
2711 NULL,
2712 "DELETE",
2713 "TRACE",
2714 "CLOSE"
2715 };
2716
2717
2718 DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
2719 http, codes[request], uri));
2720
2721 if (http == NULL || uri == NULL)
2722 return (-1);
2723
2724 /*
2725 * Set the User-Agent field if it isn't already...
2726 */
2727
2728 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
2729 httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
2730
2731 /*
2732 * Encode the URI as needed...
2733 */
2734
2735 _httpEncodeURI(buf, uri, sizeof(buf));
2736
2737 /*
2738 * See if we had an error the last time around; if so, reconnect...
2739 */
2740
2741 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
2742 if (httpReconnect(http))
2743 return (-1);
2744
2745 /*
2746 * Flush any written data that is pending...
2747 */
2748
2749 if (http->wused)
2750 httpFlushWrite(http);
2751
2752 /*
2753 * Send the request header...
2754 */
2755
2756 http->state = request;
2757 http->data_encoding = HTTP_ENCODE_FIELDS;
2758
2759 if (request == HTTP_POST || request == HTTP_PUT)
2760 http->state ++;
2761
2762 http->status = HTTP_CONTINUE;
2763
2764 #ifdef HAVE_SSL
2765 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
2766 {
2767 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
2768 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
2769 }
2770 #endif /* HAVE_SSL */
2771
2772 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
2773 {
2774 http->status = HTTP_ERROR;
2775 return (-1);
2776 }
2777
2778 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2779 if (http->fields[i][0] != '\0')
2780 {
2781 DEBUG_printf(("http_send: %s: %s\n", http_fields[i],
2782 httpGetField(http, i)));
2783
2784 if (httpPrintf(http, "%s: %s\r\n", http_fields[i],
2785 httpGetField(http, i)) < 1)
2786 {
2787 http->status = HTTP_ERROR;
2788 return (-1);
2789 }
2790 }
2791
2792 if (http->cookie)
2793 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
2794 {
2795 http->status = HTTP_ERROR;
2796 return (-1);
2797 }
2798
2799 if (http->expect == HTTP_CONTINUE &&
2800 (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
2801 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
2802 {
2803 http->status = HTTP_ERROR;
2804 return (-1);
2805 }
2806
2807 if (httpPrintf(http, "\r\n") < 1)
2808 {
2809 http->status = HTTP_ERROR;
2810 return (-1);
2811 }
2812
2813 httpFlushWrite(http);
2814 httpGetLength2(http);
2815 httpClearFields(http);
2816
2817 /*
2818 * The Kerberos and AuthRef authentication strings can only be used once...
2819 */
2820
2821 if (http->field_authorization && http->authstring &&
2822 (!strncmp(http->authstring, "Negotiate", 9) ||
2823 !strncmp(http->authstring, "AuthRef", 7)))
2824 {
2825 http->_authstring[0] = '\0';
2826
2827 if (http->authstring != http->_authstring)
2828 free(http->authstring);
2829
2830 http->authstring = http->_authstring;
2831 }
2832
2833 return (0);
2834 }
2835
2836
2837 #ifdef HAVE_SSL
2838 /*
2839 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
2840 */
2841
2842 static int /* O - Status of connection */
2843 http_setup_ssl(http_t *http) /* I - Connection to server */
2844 {
2845 # ifdef HAVE_LIBSSL
2846 SSL_CTX *context; /* Context for encryption */
2847 SSL *conn; /* Connection for encryption */
2848 BIO *bio; /* BIO data */
2849 # elif defined(HAVE_GNUTLS)
2850 http_tls_t *conn; /* TLS session object */
2851 gnutls_certificate_client_credentials *credentials;
2852 /* TLS credentials */
2853 # elif defined(HAVE_CDSASSL)
2854 OSStatus error; /* Error code */
2855 http_tls_t *conn; /* CDSA connection information */
2856 # endif /* HAVE_LIBSSL */
2857
2858
2859 DEBUG_printf(("http_setup_ssl(http=%p)\n", http));
2860
2861 # ifdef HAVE_LIBSSL
2862 context = SSL_CTX_new(SSLv23_client_method());
2863
2864 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
2865
2866 bio = BIO_new(_httpBIOMethods());
2867 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
2868
2869 conn = SSL_new(context);
2870 SSL_set_bio(conn, bio, bio);
2871
2872 if (SSL_connect(conn) != 1)
2873 {
2874 # ifdef DEBUG
2875 unsigned long error; /* Error code */
2876
2877 while ((error = ERR_get_error()) != 0)
2878 printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));
2879 # endif /* DEBUG */
2880
2881 SSL_CTX_free(context);
2882 SSL_free(conn);
2883
2884 # ifdef WIN32
2885 http->error = WSAGetLastError();
2886 # else
2887 http->error = errno;
2888 # endif /* WIN32 */
2889 http->status = HTTP_ERROR;
2890
2891 return (HTTP_ERROR);
2892 }
2893
2894 # elif defined(HAVE_GNUTLS)
2895 if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
2896 {
2897 http->error = errno;
2898 http->status = HTTP_ERROR;
2899
2900 return (-1);
2901 }
2902
2903 credentials = (gnutls_certificate_client_credentials *)
2904 malloc(sizeof(gnutls_certificate_client_credentials));
2905 if (credentials == NULL)
2906 {
2907 free(conn);
2908
2909 http->error = errno;
2910 http->status = HTTP_ERROR;
2911
2912 return (-1);
2913 }
2914
2915 gnutls_certificate_allocate_credentials(credentials);
2916
2917 gnutls_init(&(conn->session), GNUTLS_CLIENT);
2918 gnutls_set_default_priority(conn->session);
2919 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
2920 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http);
2921 gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS);
2922 gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS);
2923
2924 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
2925 {
2926 http->error = errno;
2927 http->status = HTTP_ERROR;
2928
2929 return (-1);
2930 }
2931
2932 conn->credentials = credentials;
2933
2934 # elif defined(HAVE_CDSASSL)
2935 conn = (http_tls_t *)calloc(1, sizeof(http_tls_t));
2936
2937 if (conn == NULL)
2938 return (-1);
2939
2940 if ((error = SSLNewContext(false, &conn->session)))
2941 {
2942 http->error = error;
2943 http->status = HTTP_ERROR;
2944
2945 free(conn);
2946 return (-1);
2947 }
2948
2949 /*
2950 * Use a union to resolve warnings about int/pointer size mismatches...
2951 */
2952
2953 error = SSLSetConnection(conn->session, http);
2954
2955 if (!error)
2956 error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
2957
2958 if (!error)
2959 error = SSLSetAllowsExpiredCerts(conn->session, true);
2960
2961 if (!error)
2962 error = SSLSetAllowsAnyRoot(conn->session, true);
2963
2964 if (!error)
2965 error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);
2966
2967 if (!error)
2968 {
2969 while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
2970 usleep(1000);
2971 }
2972
2973 if (error)
2974 {
2975 http->error = error;
2976 http->status = HTTP_ERROR;
2977
2978 SSLDisposeContext(conn->session);
2979
2980 free(conn);
2981
2982 return (-1);
2983 }
2984 # endif /* HAVE_CDSASSL */
2985
2986 http->tls = conn;
2987 return (0);
2988 }
2989 #endif /* HAVE_SSL */
2990
2991
2992 #ifdef HAVE_SSL
2993 /*
2994 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
2995 */
2996
2997 static void
2998 http_shutdown_ssl(http_t *http) /* I - Connection to server */
2999 {
3000 # ifdef HAVE_LIBSSL
3001 SSL_CTX *context; /* Context for encryption */
3002 SSL *conn; /* Connection for encryption */
3003
3004
3005 conn = (SSL *)(http->tls);
3006 context = SSL_get_SSL_CTX(conn);
3007
3008 SSL_shutdown(conn);
3009 SSL_CTX_free(context);
3010 SSL_free(conn);
3011
3012 # elif defined(HAVE_GNUTLS)
3013 http_tls_t *conn; /* Encryption session */
3014 gnutls_certificate_client_credentials *credentials;
3015 /* TLS credentials */
3016
3017
3018 conn = (http_tls_t *)(http->tls);
3019 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
3020
3021 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
3022 gnutls_deinit(conn->session);
3023 gnutls_certificate_free_credentials(*credentials);
3024 free(credentials);
3025 free(conn);
3026
3027 # elif defined(HAVE_CDSASSL)
3028 http_tls_t *conn; /* CDSA connection information */
3029
3030
3031 conn = (http_tls_t *)(http->tls);
3032
3033 while (SSLClose(conn->session) == errSSLWouldBlock)
3034 usleep(1000);
3035
3036 SSLDisposeContext(conn->session);
3037
3038 if (conn->certsArray)
3039 CFRelease(conn->certsArray);
3040
3041 free(conn);
3042 # endif /* HAVE_LIBSSL */
3043
3044 http->tls = NULL;
3045 }
3046 #endif /* HAVE_SSL */
3047
3048
3049 #ifdef HAVE_SSL
3050 /*
3051 * 'http_upgrade()' - Force upgrade to TLS encryption.
3052 */
3053
3054 static int /* O - Status of connection */
3055 http_upgrade(http_t *http) /* I - Connection to server */
3056 {
3057 int ret; /* Return value */
3058 http_t myhttp; /* Local copy of HTTP data */
3059
3060
3061 DEBUG_printf(("http_upgrade(%p)\n", http));
3062
3063 /*
3064 * Copy the HTTP data to a local variable so we can do the OPTIONS
3065 * request without interfering with the existing request data...
3066 */
3067
3068 memcpy(&myhttp, http, sizeof(myhttp));
3069
3070 /*
3071 * Send an OPTIONS request to the server, requiring SSL or TLS
3072 * encryption on the link...
3073 */
3074
3075 http->field_authorization = NULL; /* Don't free the auth string */
3076
3077 httpClearFields(http);
3078 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
3079 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
3080
3081 if ((ret = httpOptions(http, "*")) == 0)
3082 {
3083 /*
3084 * Wait for the secure connection...
3085 */
3086
3087 while (httpUpdate(http) == HTTP_CONTINUE);
3088 }
3089
3090 httpFlush(http);
3091
3092 /*
3093 * Restore the HTTP request data...
3094 */
3095
3096 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
3097 http->data_encoding = myhttp.data_encoding;
3098 http->data_remaining = myhttp.data_remaining;
3099 http->_data_remaining = myhttp._data_remaining;
3100 http->expect = myhttp.expect;
3101 http->field_authorization = myhttp.field_authorization;
3102 http->digest_tries = myhttp.digest_tries;
3103
3104 /*
3105 * See if we actually went secure...
3106 */
3107
3108 if (!http->tls)
3109 {
3110 /*
3111 * Server does not support HTTP upgrade...
3112 */
3113
3114 DEBUG_puts("Server does not support HTTP upgrade!");
3115
3116 # ifdef WIN32
3117 closesocket(http->fd);
3118 # else
3119 close(http->fd);
3120 # endif
3121
3122 http->fd = -1;
3123
3124 return (-1);
3125 }
3126 else
3127 return (ret);
3128 }
3129 #endif /* HAVE_SSL */
3130
3131
3132 /*
3133 * 'http_write()' - Write a buffer to a HTTP connection.
3134 */
3135
3136 static int /* O - Number of bytes written */
3137 http_write(http_t *http, /* I - Connection to server */
3138 const char *buffer, /* I - Buffer for data */
3139 int length) /* I - Number of bytes to write */
3140 {
3141 int tbytes, /* Total bytes sent */
3142 bytes; /* Bytes sent */
3143
3144
3145 tbytes = 0;
3146
3147 while (length > 0)
3148 {
3149 #ifdef HAVE_SSL
3150 if (http->tls)
3151 bytes = http_write_ssl(http, buffer, length);
3152 else
3153 #endif /* HAVE_SSL */
3154 bytes = send(http->fd, buffer, length, 0);
3155
3156 if (bytes < 0)
3157 {
3158 #ifdef WIN32
3159 if (WSAGetLastError() != http->error)
3160 {
3161 http->error = WSAGetLastError();
3162 continue;
3163 }
3164 #else
3165 if (errno == EINTR)
3166 continue;
3167 else if (errno != http->error && errno != ECONNRESET)
3168 {
3169 http->error = errno;
3170 continue;
3171 }
3172 #endif /* WIN32 */
3173
3174 DEBUG_puts("http_write: error writing data...\n");
3175
3176 return (-1);
3177 }
3178
3179 buffer += bytes;
3180 tbytes += bytes;
3181 length -= bytes;
3182 }
3183
3184 #ifdef DEBUG
3185 http_debug_hex("http_write", buffer - tbytes, tbytes);
3186 #endif /* DEBUG */
3187
3188 return (tbytes);
3189 }
3190
3191
3192 /*
3193 * 'http_write_chunk()' - Write a chunked buffer.
3194 */
3195
3196 static int /* O - Number bytes written */
3197 http_write_chunk(http_t *http, /* I - Connection to server */
3198 const char *buffer, /* I - Buffer to write */
3199 int length) /* I - Length of buffer */
3200 {
3201 char header[255]; /* Chunk header */
3202 int bytes; /* Bytes written */
3203
3204 DEBUG_printf(("http_write_chunk(http=%p, buffer=%p, length=%d)\n",
3205 http, buffer, length));
3206
3207 /*
3208 * Write the chunk header, data, and trailer.
3209 */
3210
3211 sprintf(header, "%x\r\n", length);
3212 if (http_write(http, header, (int)strlen(header)) < 0)
3213 {
3214 DEBUG_puts(" http_write of length failed!");
3215 return (-1);
3216 }
3217
3218 if ((bytes = http_write(http, buffer, length)) < 0)
3219 {
3220 DEBUG_puts(" http_write of buffer failed!");
3221 return (-1);
3222 }
3223
3224 if (http_write(http, "\r\n", 2) < 0)
3225 {
3226 DEBUG_puts(" http_write of CR LF failed!");
3227 return (-1);
3228 }
3229
3230 return (bytes);
3231 }
3232
3233
3234 #ifdef HAVE_SSL
3235 /*
3236 * 'http_write_ssl()' - Write to a SSL/TLS connection.
3237 */
3238
3239 static int /* O - Bytes written */
3240 http_write_ssl(http_t *http, /* I - Connection to server */
3241 const char *buf, /* I - Buffer holding data */
3242 int len) /* I - Length of buffer */
3243 {
3244 # if defined(HAVE_LIBSSL)
3245 return (SSL_write((SSL *)(http->tls), buf, len));
3246
3247 # elif defined(HAVE_GNUTLS)
3248 return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
3249 # elif defined(HAVE_CDSASSL)
3250 int result; /* Return value */
3251 OSStatus error; /* Error info */
3252 size_t processed; /* Number of bytes processed */
3253
3254
3255 error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed);
3256
3257 switch (error)
3258 {
3259 case 0 :
3260 result = (int)processed;
3261 break;
3262 case errSSLClosedGraceful :
3263 result = 0;
3264 break;
3265 case errSSLWouldBlock :
3266 if (processed)
3267 result = (int)processed;
3268 else
3269 {
3270 result = -1;
3271 errno = EINTR;
3272 }
3273 break;
3274 default :
3275 errno = EPIPE;
3276 result = -1;
3277 break;
3278 }
3279
3280 return (result);
3281 # endif /* HAVE_LIBSSL */
3282 }
3283 #endif /* HAVE_SSL */
3284
3285
3286 /*
3287 * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
3288 */