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