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