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