]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Merge changes from CUPS 1.4svn-r8606.
[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 usleep(100000);
1689
1690 http->fd = -1;
1691 }
1692
1693 /*
1694 * Connect to the server...
1695 */
1696
1697 #ifdef DEBUG
1698 for (current = http->addrlist; current; current = current->next)
1699 DEBUG_printf(("2httpReconnect: Address %s:%d",
1700 httpAddrString(&(current->addr), temp, sizeof(temp)),
1701 _httpAddrPort(&(current->addr))));
1702 #endif /* DEBUG */
1703
1704 if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL)
1705 {
1706 /*
1707 * Unable to connect...
1708 */
1709
1710 #ifdef WIN32
1711 http->error = WSAGetLastError();
1712 #else
1713 http->error = errno;
1714 #endif /* WIN32 */
1715 http->status = HTTP_ERROR;
1716
1717 DEBUG_printf(("1httpReconnect: httpAddrConnect failed: %s",
1718 strerror(http->error)));
1719
1720 return (-1);
1721 }
1722
1723 DEBUG_printf(("2httpReconnect: New socket=%d", http->fd));
1724
1725 http->hostaddr = &(addr->addr);
1726 http->error = 0;
1727 http->status = HTTP_CONTINUE;
1728
1729 #ifdef HAVE_SSL
1730 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
1731 {
1732 /*
1733 * Always do encryption via SSL.
1734 */
1735
1736 if (http_setup_ssl(http) != 0)
1737 {
1738 # ifdef WIN32
1739 closesocket(http->fd);
1740 # else
1741 close(http->fd);
1742 # endif /* WIN32 */
1743
1744 return (-1);
1745 }
1746 }
1747 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
1748 return (http_upgrade(http));
1749 #endif /* HAVE_SSL */
1750
1751 DEBUG_printf(("1httpReconnect: Connected to %s:%d...",
1752 httpAddrString(http->hostaddr, temp, sizeof(temp)),
1753 _httpAddrPort(http->hostaddr)));
1754
1755 return (0);
1756 }
1757
1758
1759 /*
1760 * 'httpSetAuthString()' - Set the current authorization string.
1761 *
1762 * This function just stores a copy of the current authorization string in
1763 * the HTTP connection object. You must still call httpSetField() to set
1764 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
1765 * httpHead(), httpOptions(), httpPost, or httpPut().
1766 *
1767 * @since CUPS 1.3/Mac OS X 10.5@
1768 */
1769
1770 void
1771 httpSetAuthString(http_t *http, /* I - Connection to server */
1772 const char *scheme, /* I - Auth scheme (NULL to clear it) */
1773 const char *data) /* I - Auth data (NULL for none) */
1774 {
1775 /*
1776 * Range check input...
1777 */
1778
1779 if (!http)
1780 return;
1781
1782 if (http->authstring && http->authstring != http->_authstring)
1783 free(http->authstring);
1784
1785 http->authstring = http->_authstring;
1786
1787 if (scheme)
1788 {
1789 /*
1790 * Set the current authorization string...
1791 */
1792
1793 int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1;
1794 char *temp;
1795
1796 if (len > (int)sizeof(http->_authstring))
1797 {
1798 if ((temp = malloc(len)) == NULL)
1799 len = sizeof(http->_authstring);
1800 else
1801 http->authstring = temp;
1802 }
1803
1804 if (data)
1805 snprintf(http->authstring, len, "%s %s", scheme, data);
1806 else
1807 strlcpy(http->authstring, scheme, len);
1808 }
1809 else
1810 {
1811 /*
1812 * Clear the current authorization string...
1813 */
1814
1815 http->_authstring[0] = '\0';
1816 }
1817 }
1818
1819
1820 /*
1821 * 'httpSetCookie()' - Set the cookie value(s)...
1822 *
1823 * @since CUPS 1.1.19/Mac OS X 10.3@
1824 */
1825
1826 void
1827 httpSetCookie(http_t *http, /* I - Connection */
1828 const char *cookie) /* I - Cookie string */
1829 {
1830 if (!http)
1831 return;
1832
1833 if (http->cookie)
1834 free(http->cookie);
1835
1836 if (cookie)
1837 http->cookie = strdup(cookie);
1838 else
1839 http->cookie = NULL;
1840 }
1841
1842
1843 /*
1844 * 'httpSetExpect()' - Set the Expect: header in a request.
1845 *
1846 * Currently only HTTP_CONTINUE is supported for the "expect" argument.
1847 *
1848 * @since CUPS 1.2/Mac OS X 10.5@
1849 */
1850
1851 void
1852 httpSetExpect(http_t *http, /* I - Connection to server */
1853 http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */
1854 {
1855 if (http)
1856 http->expect = expect;
1857 }
1858
1859
1860 /*
1861 * 'httpSetField()' - Set the value of an HTTP header.
1862 */
1863
1864 void
1865 httpSetField(http_t *http, /* I - Connection to server */
1866 http_field_t field, /* I - Field index */
1867 const char *value) /* I - Value */
1868 {
1869 if (http == NULL ||
1870 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
1871 field > HTTP_FIELD_WWW_AUTHENTICATE ||
1872 value == NULL)
1873 return;
1874
1875 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
1876
1877 if (field == HTTP_FIELD_AUTHORIZATION)
1878 {
1879 /*
1880 * Special case for Authorization: as its contents can be
1881 * longer than HTTP_MAX_VALUE
1882 */
1883
1884 if (http->field_authorization)
1885 free(http->field_authorization);
1886
1887 http->field_authorization = strdup(value);
1888 }
1889 else if (field == HTTP_FIELD_HOST)
1890 {
1891 /*
1892 * Special-case for Host: as we don't want a trailing "." on the hostname and
1893 * need to bracket IPv6 numeric addresses.
1894 */
1895
1896 if (strchr(value, ':'))
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 char *ptr = http->fields[HTTP_FIELD_HOST];
1915 /* Pointer into Host: field */
1916
1917 if (*ptr)
1918 {
1919 ptr += strlen(ptr) - 1;
1920
1921 if (*ptr == '.')
1922 *ptr = '\0';
1923 }
1924 }
1925 }
1926 }
1927
1928
1929 /*
1930 * 'httpSetLength()' - Set the content-length and content-encoding.
1931 *
1932 * @since CUPS 1.2/Mac OS X 10.5@
1933 */
1934
1935 void
1936 httpSetLength(http_t *http, /* I - Connection to server */
1937 size_t length) /* I - Length (0 for chunked) */
1938 {
1939 if (!http)
1940 return;
1941
1942 if (!length)
1943 {
1944 strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked");
1945 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
1946 }
1947 else
1948 {
1949 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
1950 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
1951 CUPS_LLFMT, CUPS_LLCAST length);
1952 }
1953 }
1954
1955
1956 /*
1957 * 'httpTrace()' - Send an TRACE request to the server.
1958 */
1959
1960 int /* O - Status of call (0 = success) */
1961 httpTrace(http_t *http, /* I - Connection to server */
1962 const char *uri) /* I - URI for trace */
1963 {
1964 return (http_send(http, HTTP_TRACE, uri));
1965 }
1966
1967
1968 /*
1969 * 'httpUpdate()' - Update the current HTTP state for incoming data.
1970 */
1971
1972 http_status_t /* O - HTTP status */
1973 httpUpdate(http_t *http) /* I - Connection to server */
1974 {
1975 char line[32768], /* Line from connection... */
1976 *value; /* Pointer to value on line */
1977 http_field_t field; /* Field index */
1978 int major, minor, /* HTTP version numbers */
1979 status; /* Request status */
1980
1981
1982 DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
1983 http_states[http->state]));
1984
1985 /*
1986 * Flush pending data, if any...
1987 */
1988
1989 if (http->wused)
1990 {
1991 DEBUG_puts("2httpUpdate: flushing buffer...");
1992
1993 if (httpFlushWrite(http) < 0)
1994 return (HTTP_ERROR);
1995 }
1996
1997 /*
1998 * If we haven't issued any commands, then there is nothing to "update"...
1999 */
2000
2001 if (http->state == HTTP_WAITING)
2002 return (HTTP_CONTINUE);
2003
2004 /*
2005 * Grab all of the lines we can from the connection...
2006 */
2007
2008 while (httpGets(line, sizeof(line), http) != NULL)
2009 {
2010 DEBUG_printf(("2httpUpdate: Got \"%s\"", line));
2011
2012 if (line[0] == '\0')
2013 {
2014 /*
2015 * Blank line means the start of the data section (if any). Return
2016 * the result code, too...
2017 *
2018 * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
2019 * Instead, we just return HTTP_CONTINUE to the caller and keep on
2020 * tryin'...
2021 */
2022
2023 if (http->status == HTTP_CONTINUE)
2024 return (http->status);
2025
2026 if (http->status < HTTP_BAD_REQUEST)
2027 http->digest_tries = 0;
2028
2029 #ifdef HAVE_SSL
2030 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
2031 {
2032 if (http_setup_ssl(http) != 0)
2033 {
2034 # ifdef WIN32
2035 closesocket(http->fd);
2036 # else
2037 close(http->fd);
2038 # endif /* WIN32 */
2039
2040 return (HTTP_ERROR);
2041 }
2042
2043 return (HTTP_CONTINUE);
2044 }
2045 #endif /* HAVE_SSL */
2046
2047 httpGetLength2(http);
2048
2049 switch (http->state)
2050 {
2051 case HTTP_GET :
2052 case HTTP_POST :
2053 case HTTP_POST_RECV :
2054 case HTTP_PUT :
2055 http->state ++;
2056 case HTTP_POST_SEND :
2057 case HTTP_HEAD :
2058 break;
2059
2060 default :
2061 http->state = HTTP_WAITING;
2062 break;
2063 }
2064
2065 return (http->status);
2066 }
2067 else if (!strncmp(line, "HTTP/", 5))
2068 {
2069 /*
2070 * Got the beginning of a response...
2071 */
2072
2073 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
2074 return (HTTP_ERROR);
2075
2076 http->version = (http_version_t)(major * 100 + minor);
2077 http->status = (http_status_t)status;
2078 }
2079 else if ((value = strchr(line, ':')) != NULL)
2080 {
2081 /*
2082 * Got a value...
2083 */
2084
2085 *value++ = '\0';
2086 while (isspace(*value & 255))
2087 value ++;
2088
2089 /*
2090 * Be tolerants of servers that send unknown attribute fields...
2091 */
2092
2093 if (!strcasecmp(line, "expect"))
2094 {
2095 /*
2096 * "Expect: 100-continue" or similar...
2097 */
2098
2099 http->expect = (http_status_t)atoi(value);
2100 }
2101 else if (!strcasecmp(line, "cookie"))
2102 {
2103 /*
2104 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
2105 */
2106
2107 httpSetCookie(http, value);
2108 }
2109 else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
2110 {
2111 DEBUG_printf(("1httpUpdate: unknown field %s seen!", line));
2112 continue;
2113 }
2114 else
2115 httpSetField(http, field, value);
2116 }
2117 else
2118 {
2119 DEBUG_printf(("1httpUpdate: Bad response line \"%s\"!", line));
2120 http->status = HTTP_ERROR;
2121 return (HTTP_ERROR);
2122 }
2123 }
2124
2125 /*
2126 * See if there was an error...
2127 */
2128
2129 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
2130 {
2131 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status));
2132 return (http->status);
2133 }
2134
2135 if (http->error)
2136 {
2137 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error,
2138 strerror(http->error)));
2139 http->status = HTTP_ERROR;
2140 return (HTTP_ERROR);
2141 }
2142
2143 /*
2144 * If we haven't already returned, then there is nothing new...
2145 */
2146
2147 return (HTTP_CONTINUE);
2148 }
2149
2150
2151 /*
2152 * '_httpWait()' - Wait for data available on a connection (no flush).
2153 */
2154
2155 int /* O - 1 if data is available, 0 otherwise */
2156 _httpWait(http_t *http, /* I - Connection to server */
2157 int msec, /* I - Milliseconds to wait */
2158 int usessl) /* I - Use SSL context? */
2159 {
2160 #ifdef HAVE_POLL
2161 struct pollfd pfd; /* Polled file descriptor */
2162 #else
2163 fd_set input_set; /* select() input set */
2164 struct timeval timeout; /* Timeout */
2165 #endif /* HAVE_POLL */
2166 int nfds; /* Result from select()/poll() */
2167
2168
2169 DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl));
2170
2171 if (http->fd < 0)
2172 return (0);
2173
2174 /*
2175 * Check the SSL/TLS buffers for data first...
2176 */
2177
2178 #ifdef HAVE_SSL
2179 if (http->tls && usessl)
2180 {
2181 # ifdef HAVE_LIBSSL
2182 if (SSL_pending((SSL *)(http->tls)))
2183 return (1);
2184 # elif defined(HAVE_GNUTLS)
2185 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2186 return (1);
2187 # elif defined(HAVE_CDSASSL)
2188 size_t bytes; /* Bytes that are available */
2189
2190 if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) &&
2191 bytes > 0)
2192 return (1);
2193 # endif /* HAVE_LIBSSL */
2194 }
2195 #endif /* HAVE_SSL */
2196
2197 /*
2198 * Then try doing a select() or poll() to poll the socket...
2199 */
2200
2201 #ifdef HAVE_POLL
2202 pfd.fd = http->fd;
2203 pfd.events = POLLIN;
2204
2205 while ((nfds = poll(&pfd, 1, msec)) < 0 &&
2206 (errno == EINTR || errno == EAGAIN));
2207
2208 #else
2209 do
2210 {
2211 FD_ZERO(&input_set);
2212 FD_SET(http->fd, &input_set);
2213
2214 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd));
2215
2216 if (msec >= 0)
2217 {
2218 timeout.tv_sec = msec / 1000;
2219 timeout.tv_usec = (msec % 1000) * 1000;
2220
2221 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
2222 }
2223 else
2224 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
2225
2226 DEBUG_printf(("6_httpWait: select() returned %d...", nfds));
2227 }
2228 # ifdef WIN32
2229 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2230 # else
2231 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
2232 # endif /* WIN32 */
2233 #endif /* HAVE_POLL */
2234
2235 DEBUG_printf(("5_httpWait: returning with nfds=%d...", nfds));
2236
2237 return (nfds > 0);
2238 }
2239
2240
2241 /*
2242 * 'httpWait()' - Wait for data available on a connection.
2243 *
2244 * @since CUPS 1.1.19/Mac OS X 10.3@
2245 */
2246
2247 int /* O - 1 if data is available, 0 otherwise */
2248 httpWait(http_t *http, /* I - Connection to server */
2249 int msec) /* I - Milliseconds to wait */
2250 {
2251 /*
2252 * First see if there is data in the buffer...
2253 */
2254
2255 if (http == NULL)
2256 return (0);
2257
2258 if (http->used)
2259 return (1);
2260
2261 /*
2262 * Flush pending data, if any...
2263 */
2264
2265 if (http->wused)
2266 {
2267 if (httpFlushWrite(http) < 0)
2268 return (0);
2269 }
2270
2271 /*
2272 * If not, check the SSL/TLS buffers and do a select() on the connection...
2273 */
2274
2275 return (_httpWait(http, msec, 1));
2276 }
2277
2278
2279 /*
2280 * 'httpWrite()' - Write data to a HTTP connection.
2281 *
2282 * This function is deprecated. Use the httpWrite2() function which can
2283 * write more than 2GB of data.
2284 *
2285 * @deprecated@
2286 */
2287
2288 int /* O - Number of bytes written */
2289 httpWrite(http_t *http, /* I - Connection to server */
2290 const char *buffer, /* I - Buffer for data */
2291 int length) /* I - Number of bytes to write */
2292 {
2293 return ((int)httpWrite2(http, buffer, length));
2294 }
2295
2296
2297 /*
2298 * 'httpWrite2()' - Write data to a HTTP connection.
2299 *
2300 * @since CUPS 1.2/Mac OS X 10.5@
2301 */
2302
2303 ssize_t /* O - Number of bytes written */
2304 httpWrite2(http_t *http, /* I - Connection to server */
2305 const char *buffer, /* I - Buffer for data */
2306 size_t length) /* I - Number of bytes to write */
2307 {
2308 ssize_t bytes; /* Bytes written */
2309
2310
2311 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
2312 buffer, CUPS_LLCAST length));
2313
2314 /*
2315 * Range check input...
2316 */
2317
2318 if (http == NULL || buffer == NULL)
2319 return (-1);
2320
2321 /*
2322 * Mark activity on the connection...
2323 */
2324
2325 http->activity = time(NULL);
2326
2327 /*
2328 * Buffer small writes for better performance...
2329 */
2330
2331 if (length > 0)
2332 {
2333 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
2334 {
2335 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length="
2336 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length));
2337
2338 httpFlushWrite(http);
2339 }
2340
2341 if ((length + http->wused) <= sizeof(http->wbuffer) &&
2342 length < sizeof(http->wbuffer))
2343 {
2344 /*
2345 * Write to buffer...
2346 */
2347
2348 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...",
2349 CUPS_LLCAST length));
2350
2351 memcpy(http->wbuffer + http->wused, buffer, length);
2352 http->wused += (int)length;
2353 bytes = (ssize_t)length;
2354 }
2355 else
2356 {
2357 /*
2358 * Otherwise write the data directly...
2359 */
2360
2361 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...",
2362 CUPS_LLCAST length));
2363
2364 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2365 bytes = (ssize_t)http_write_chunk(http, buffer, (int)length);
2366 else
2367 bytes = (ssize_t)http_write(http, buffer, (int)length);
2368
2369 DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...",
2370 CUPS_LLCAST bytes));
2371 }
2372
2373 if (http->data_encoding == HTTP_ENCODE_LENGTH)
2374 http->data_remaining -= bytes;
2375 }
2376 else
2377 bytes = 0;
2378
2379 /*
2380 * Handle end-of-request processing...
2381 */
2382
2383 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
2384 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
2385 {
2386 /*
2387 * Finished with the transfer; unless we are sending POST or PUT
2388 * data, go idle...
2389 */
2390
2391 DEBUG_puts("2httpWrite: changing states...");
2392
2393 if (http->wused)
2394 httpFlushWrite(http);
2395
2396 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2397 {
2398 /*
2399 * Send a 0-length chunk at the end of the request...
2400 */
2401
2402 http_write(http, "0\r\n\r\n", 5);
2403
2404 /*
2405 * Reset the data state...
2406 */
2407
2408 http->data_encoding = HTTP_ENCODE_LENGTH;
2409 http->data_remaining = 0;
2410 }
2411
2412 if (http->state == HTTP_POST_RECV)
2413 http->state ++;
2414 else if (http->state == HTTP_PUT_RECV)
2415 http->state = HTTP_STATUS;
2416 else
2417 http->state = HTTP_WAITING;
2418 }
2419
2420 return (bytes);
2421 }
2422
2423
2424 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2425 /*
2426 * '_httpWriteCDSA()' - Write function for the CDSA library.
2427 */
2428
2429 OSStatus /* O - -1 on error, 0 on success */
2430 _httpWriteCDSA(
2431 SSLConnectionRef connection, /* I - SSL/TLS connection */
2432 const void *data, /* I - Data buffer */
2433 size_t *dataLength) /* IO - Number of bytes */
2434 {
2435 OSStatus result; /* Return value */
2436 ssize_t bytes; /* Number of bytes read */
2437 http_t *http; /* HTTP connection */
2438
2439
2440 http = (http_t *)connection;
2441
2442 do
2443 {
2444 bytes = write(http->fd, data, *dataLength);
2445 }
2446 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
2447
2448 if (bytes == *dataLength)
2449 {
2450 result = 0;
2451 }
2452 else if (bytes >= 0)
2453 {
2454 *dataLength = bytes;
2455 result = errSSLWouldBlock;
2456 }
2457 else
2458 {
2459 *dataLength = 0;
2460
2461 if (errno == EAGAIN)
2462 result = errSSLWouldBlock;
2463 else
2464 result = errSSLClosedAbort;
2465 }
2466
2467 return (result);
2468 }
2469 #endif /* HAVE_SSL && HAVE_CDSASSL */
2470
2471
2472 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
2473 /*
2474 * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
2475 */
2476
2477 ssize_t /* O - Number of bytes written or -1 on error */
2478 _httpWriteGNUTLS(
2479 gnutls_transport_ptr ptr, /* I - Connection to server */
2480 const void *data, /* I - Data buffer */
2481 size_t length) /* I - Number of bytes to write */
2482 {
2483 return (send(((http_t *)ptr)->fd, data, length, 0));
2484 }
2485 #endif /* HAVE_SSL && HAVE_GNUTLS */
2486
2487
2488 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
2489 /*
2490 * 'http_bio_ctrl()' - Control the HTTP connection.
2491 */
2492
2493 static long /* O - Result/data */
2494 http_bio_ctrl(BIO *h, /* I - BIO data */
2495 int cmd, /* I - Control command */
2496 long arg1, /* I - First argument */
2497 void *arg2) /* I - Second argument */
2498 {
2499 switch (cmd)
2500 {
2501 default :
2502 return (0);
2503
2504 case BIO_CTRL_RESET :
2505 h->ptr = NULL;
2506 return (0);
2507
2508 case BIO_C_SET_FILE_PTR :
2509 h->ptr = arg2;
2510 h->init = 1;
2511 return (1);
2512
2513 case BIO_C_GET_FILE_PTR :
2514 if (arg2)
2515 {
2516 *((void **)arg2) = h->ptr;
2517 return (1);
2518 }
2519 else
2520 return (0);
2521
2522 case BIO_CTRL_DUP :
2523 case BIO_CTRL_FLUSH :
2524 return (1);
2525 }
2526 }
2527
2528
2529 /*
2530 * 'http_bio_free()' - Free OpenSSL data.
2531 */
2532
2533 static int /* O - 1 on success, 0 on failure */
2534 http_bio_free(BIO *h) /* I - BIO data */
2535 {
2536 if (!h)
2537 return (0);
2538
2539 if (h->shutdown)
2540 {
2541 h->init = 0;
2542 h->flags = 0;
2543 }
2544
2545 return (1);
2546 }
2547
2548
2549 /*
2550 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
2551 */
2552
2553 static int /* O - 1 on success, 0 on failure */
2554 http_bio_new(BIO *h) /* I - BIO data */
2555 {
2556 if (!h)
2557 return (0);
2558
2559 h->init = 0;
2560 h->num = 0;
2561 h->ptr = NULL;
2562 h->flags = 0;
2563
2564 return (1);
2565 }
2566
2567
2568 /*
2569 * 'http_bio_puts()' - Send a string for OpenSSL.
2570 */
2571
2572 static int /* O - Bytes written */
2573 http_bio_puts(BIO *h, /* I - BIO data */
2574 const char *str) /* I - String to write */
2575 {
2576 #ifdef WIN32
2577 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
2578 #else
2579 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
2580 #endif /* WIN32 */
2581 }
2582
2583
2584 /*
2585 * 'http_bio_read()' - Read data for OpenSSL.
2586 */
2587
2588 static int /* O - Bytes read */
2589 http_bio_read(BIO *h, /* I - BIO data */
2590 char *buf, /* I - Buffer */
2591 int size) /* I - Number of bytes to read */
2592 {
2593 http_t *http; /* HTTP connection */
2594
2595
2596 http = (http_t *)h->ptr;
2597
2598 if (!http->blocking)
2599 {
2600 /*
2601 * Make sure we have data before we read...
2602 */
2603
2604 if (!_httpWait(http, 10000, 0))
2605 {
2606 #ifdef WIN32
2607 http->error = WSAETIMEDOUT;
2608 #else
2609 http->error = ETIMEDOUT;
2610 #endif /* WIN32 */
2611
2612 return (-1);
2613 }
2614 }
2615
2616 return (recv(http->fd, buf, size, 0));
2617 }
2618
2619
2620 /*
2621 * 'http_bio_write()' - Write data for OpenSSL.
2622 */
2623
2624 static int /* O - Bytes written */
2625 http_bio_write(BIO *h, /* I - BIO data */
2626 const char *buf, /* I - Buffer to write */
2627 int num) /* I - Number of bytes to write */
2628 {
2629 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
2630 }
2631 #endif /* HAVE_SSL && HAVE_LIBSSL */
2632
2633
2634 #ifdef DEBUG
2635 /*
2636 * 'http_debug_hex()' - Do a hex dump of a buffer.
2637 */
2638
2639 static void
2640 http_debug_hex(const char *prefix, /* I - Prefix for line */
2641 const char *buffer, /* I - Buffer to dump */
2642 int bytes) /* I - Bytes to dump */
2643 {
2644 int i, j, /* Looping vars */
2645 ch; /* Current character */
2646 char line[255], /* Line buffer */
2647 *start, /* Start of line after prefix */
2648 *ptr; /* Pointer into line */
2649
2650
2651 if (_cups_debug_fd < 0 || _cups_debug_level < 6)
2652 return;
2653
2654 DEBUG_printf(("6%s: %d bytes:\n", prefix, bytes));
2655
2656 snprintf(line, sizeof(line), "6%s: ", prefix);
2657 start = line + strlen(line);
2658
2659 for (i = 0; i < bytes; i += 16)
2660 {
2661 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
2662 sprintf(ptr, "%02X", buffer[i + j] & 255);
2663
2664 while (j < 16)
2665 {
2666 strcpy(ptr, " ");
2667 ptr += 2;
2668 j ++;
2669 }
2670
2671 strcpy(ptr, " ");
2672 ptr += 2;
2673
2674 for (j = 0; j < 16 && (i + j) < bytes; j ++)
2675 {
2676 ch = buffer[i + j] & 255;
2677
2678 if (ch < ' ' || ch >= 127)
2679 ch = '.';
2680
2681 *ptr++ = ch;
2682 }
2683
2684 *ptr = '\0';
2685 DEBUG_puts(line);
2686 }
2687 }
2688 #endif /* DEBUG */
2689
2690
2691 /*
2692 * 'http_field()' - Return the field index for a field name.
2693 */
2694
2695 static http_field_t /* O - Field index */
2696 http_field(const char *name) /* I - String name */
2697 {
2698 int i; /* Looping var */
2699
2700
2701 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2702 if (strcasecmp(name, http_fields[i]) == 0)
2703 return ((http_field_t)i);
2704
2705 return (HTTP_FIELD_UNKNOWN);
2706 }
2707
2708
2709 #ifdef HAVE_SSL
2710 /*
2711 * 'http_read_ssl()' - Read from a SSL/TLS connection.
2712 */
2713
2714 static int /* O - Bytes read */
2715 http_read_ssl(http_t *http, /* I - Connection to server */
2716 char *buf, /* I - Buffer to store data */
2717 int len) /* I - Length of buffer */
2718 {
2719 # if defined(HAVE_LIBSSL)
2720 return (SSL_read((SSL *)(http->tls), buf, len));
2721
2722 # elif defined(HAVE_GNUTLS)
2723 return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));
2724
2725 # elif defined(HAVE_CDSASSL)
2726 int result; /* Return value */
2727 OSStatus error; /* Error info */
2728 size_t processed; /* Number of bytes processed */
2729
2730
2731 error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed);
2732
2733 switch (error)
2734 {
2735 case 0 :
2736 result = (int)processed;
2737 break;
2738 case errSSLClosedGraceful :
2739 result = 0;
2740 break;
2741 case errSSLWouldBlock :
2742 if (processed)
2743 result = (int)processed;
2744 else
2745 {
2746 result = -1;
2747 errno = EINTR;
2748 }
2749 break;
2750 default :
2751 errno = EPIPE;
2752 result = -1;
2753 break;
2754 }
2755
2756 return (result);
2757 # endif /* HAVE_LIBSSL */
2758 }
2759 #endif /* HAVE_SSL */
2760
2761
2762 /*
2763 * 'http_send()' - Send a request with all fields and the trailing blank line.
2764 */
2765
2766 static int /* O - 0 on success, non-zero on error */
2767 http_send(http_t *http, /* I - Connection to server */
2768 http_state_t request, /* I - Request code */
2769 const char *uri) /* I - URI */
2770 {
2771 int i; /* Looping var */
2772 char buf[1024]; /* Encoded URI buffer */
2773 static const char * const codes[] =
2774 { /* Request code strings */
2775 NULL,
2776 "OPTIONS",
2777 "GET",
2778 NULL,
2779 "HEAD",
2780 "POST",
2781 NULL,
2782 NULL,
2783 "PUT",
2784 NULL,
2785 "DELETE",
2786 "TRACE",
2787 "CLOSE"
2788 };
2789
2790
2791 DEBUG_printf(("7http_send(http=%p, request=HTTP_%s, uri=\"%s\")",
2792 http, codes[request], uri));
2793
2794 if (http == NULL || uri == NULL)
2795 return (-1);
2796
2797 /*
2798 * Set the User-Agent field if it isn't already...
2799 */
2800
2801 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
2802 httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
2803
2804 /*
2805 * Encode the URI as needed...
2806 */
2807
2808 _httpEncodeURI(buf, uri, sizeof(buf));
2809
2810 /*
2811 * See if we had an error the last time around; if so, reconnect...
2812 */
2813
2814 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
2815 if (httpReconnect(http))
2816 return (-1);
2817
2818 /*
2819 * Flush any written data that is pending...
2820 */
2821
2822 if (http->wused)
2823 httpFlushWrite(http);
2824
2825 /*
2826 * Send the request header...
2827 */
2828
2829 http->state = request;
2830 http->data_encoding = HTTP_ENCODE_FIELDS;
2831
2832 if (request == HTTP_POST || request == HTTP_PUT)
2833 http->state ++;
2834
2835 http->status = HTTP_CONTINUE;
2836
2837 #ifdef HAVE_SSL
2838 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
2839 {
2840 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
2841 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
2842 }
2843 #endif /* HAVE_SSL */
2844
2845 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
2846 {
2847 http->status = HTTP_ERROR;
2848 return (-1);
2849 }
2850
2851 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2852 if (http->fields[i][0] != '\0')
2853 {
2854 DEBUG_printf(("9http_send: %s: %s", http_fields[i],
2855 httpGetField(http, i)));
2856
2857 if (httpPrintf(http, "%s: %s\r\n", http_fields[i],
2858 httpGetField(http, i)) < 1)
2859 {
2860 http->status = HTTP_ERROR;
2861 return (-1);
2862 }
2863 }
2864
2865 if (http->cookie)
2866 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
2867 {
2868 http->status = HTTP_ERROR;
2869 return (-1);
2870 }
2871
2872 if (http->expect == HTTP_CONTINUE &&
2873 (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
2874 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
2875 {
2876 http->status = HTTP_ERROR;
2877 return (-1);
2878 }
2879
2880 if (httpPrintf(http, "\r\n") < 1)
2881 {
2882 http->status = HTTP_ERROR;
2883 return (-1);
2884 }
2885
2886 httpFlushWrite(http);
2887 httpGetLength2(http);
2888 httpClearFields(http);
2889
2890 /*
2891 * The Kerberos and AuthRef authentication strings can only be used once...
2892 */
2893
2894 if (http->field_authorization && http->authstring &&
2895 (!strncmp(http->authstring, "Negotiate", 9) ||
2896 !strncmp(http->authstring, "AuthRef", 7)))
2897 {
2898 http->_authstring[0] = '\0';
2899
2900 if (http->authstring != http->_authstring)
2901 free(http->authstring);
2902
2903 http->authstring = http->_authstring;
2904 }
2905
2906 return (0);
2907 }
2908
2909
2910 #ifdef HAVE_SSL
2911 /*
2912 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
2913 */
2914
2915 static int /* O - Status of connection */
2916 http_setup_ssl(http_t *http) /* I - Connection to server */
2917 {
2918 # ifdef HAVE_LIBSSL
2919 SSL_CTX *context; /* Context for encryption */
2920 SSL *conn; /* Connection for encryption */
2921 BIO *bio; /* BIO data */
2922 # elif defined(HAVE_GNUTLS)
2923 http_tls_t *conn; /* TLS session object */
2924 gnutls_certificate_client_credentials *credentials;
2925 /* TLS credentials */
2926 # elif defined(HAVE_CDSASSL)
2927 OSStatus error; /* Error code */
2928 http_tls_t *conn; /* CDSA connection information */
2929 # endif /* HAVE_LIBSSL */
2930
2931
2932 DEBUG_printf(("7http_setup_ssl(http=%p)", http));
2933
2934 # ifdef HAVE_LIBSSL
2935 context = SSL_CTX_new(SSLv23_client_method());
2936
2937 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
2938
2939 bio = BIO_new(_httpBIOMethods());
2940 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
2941
2942 conn = SSL_new(context);
2943 SSL_set_bio(conn, bio, bio);
2944
2945 if (SSL_connect(conn) != 1)
2946 {
2947 # ifdef DEBUG
2948 unsigned long error; /* Error code */
2949
2950 while ((error = ERR_get_error()) != 0)
2951 DEBUG_printf(("8http_setup_ssl: %s", ERR_error_string(error, NULL)));
2952 # endif /* DEBUG */
2953
2954 SSL_CTX_free(context);
2955 SSL_free(conn);
2956
2957 # ifdef WIN32
2958 http->error = WSAGetLastError();
2959 # else
2960 http->error = errno;
2961 # endif /* WIN32 */
2962 http->status = HTTP_ERROR;
2963
2964 return (HTTP_ERROR);
2965 }
2966
2967 # elif defined(HAVE_GNUTLS)
2968 if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
2969 {
2970 http->error = errno;
2971 http->status = HTTP_ERROR;
2972
2973 return (-1);
2974 }
2975
2976 credentials = (gnutls_certificate_client_credentials *)
2977 malloc(sizeof(gnutls_certificate_client_credentials));
2978 if (credentials == NULL)
2979 {
2980 free(conn);
2981
2982 http->error = errno;
2983 http->status = HTTP_ERROR;
2984
2985 return (-1);
2986 }
2987
2988 gnutls_certificate_allocate_credentials(credentials);
2989
2990 gnutls_init(&(conn->session), GNUTLS_CLIENT);
2991 gnutls_set_default_priority(conn->session);
2992 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
2993 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http);
2994 gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS);
2995 gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS);
2996
2997 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
2998 {
2999 http->error = errno;
3000 http->status = HTTP_ERROR;
3001
3002 return (-1);
3003 }
3004
3005 conn->credentials = credentials;
3006
3007 # elif defined(HAVE_CDSASSL)
3008 conn = (http_tls_t *)calloc(1, sizeof(http_tls_t));
3009
3010 if (conn == NULL)
3011 return (-1);
3012
3013 if ((error = SSLNewContext(false, &conn->session)))
3014 {
3015 http->error = error;
3016 http->status = HTTP_ERROR;
3017
3018 free(conn);
3019 return (-1);
3020 }
3021
3022 /*
3023 * Use a union to resolve warnings about int/pointer size mismatches...
3024 */
3025
3026 error = SSLSetConnection(conn->session, http);
3027
3028 if (!error)
3029 error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
3030
3031 if (!error)
3032 error = SSLSetAllowsExpiredCerts(conn->session, true);
3033
3034 if (!error)
3035 error = SSLSetAllowsAnyRoot(conn->session, true);
3036
3037 if (!error)
3038 error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);
3039
3040 if (!error)
3041 {
3042 while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
3043 usleep(1000);
3044 }
3045
3046 if (error)
3047 {
3048 http->error = error;
3049 http->status = HTTP_ERROR;
3050
3051 SSLDisposeContext(conn->session);
3052
3053 free(conn);
3054
3055 return (-1);
3056 }
3057 # endif /* HAVE_CDSASSL */
3058
3059 http->tls = conn;
3060 return (0);
3061 }
3062 #endif /* HAVE_SSL */
3063
3064
3065 #ifdef HAVE_SSL
3066 /*
3067 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
3068 */
3069
3070 static void
3071 http_shutdown_ssl(http_t *http) /* I - Connection to server */
3072 {
3073 # ifdef HAVE_LIBSSL
3074 SSL_CTX *context; /* Context for encryption */
3075 SSL *conn; /* Connection for encryption */
3076
3077
3078 conn = (SSL *)(http->tls);
3079 context = SSL_get_SSL_CTX(conn);
3080
3081 SSL_shutdown(conn);
3082 SSL_CTX_free(context);
3083 SSL_free(conn);
3084
3085 # elif defined(HAVE_GNUTLS)
3086 http_tls_t *conn; /* Encryption session */
3087 gnutls_certificate_client_credentials *credentials;
3088 /* TLS credentials */
3089
3090
3091 conn = (http_tls_t *)(http->tls);
3092 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
3093
3094 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
3095 gnutls_deinit(conn->session);
3096 gnutls_certificate_free_credentials(*credentials);
3097 free(credentials);
3098 free(conn);
3099
3100 # elif defined(HAVE_CDSASSL)
3101 http_tls_t *conn; /* CDSA connection information */
3102
3103
3104 conn = (http_tls_t *)(http->tls);
3105
3106 while (SSLClose(conn->session) == errSSLWouldBlock)
3107 usleep(1000);
3108
3109 SSLDisposeContext(conn->session);
3110
3111 if (conn->certsArray)
3112 CFRelease(conn->certsArray);
3113
3114 free(conn);
3115 # endif /* HAVE_LIBSSL */
3116
3117 http->tls = NULL;
3118 }
3119 #endif /* HAVE_SSL */
3120
3121
3122 #ifdef HAVE_SSL
3123 /*
3124 * 'http_upgrade()' - Force upgrade to TLS encryption.
3125 */
3126
3127 static int /* O - Status of connection */
3128 http_upgrade(http_t *http) /* I - Connection to server */
3129 {
3130 int ret; /* Return value */
3131 http_t myhttp; /* Local copy of HTTP data */
3132
3133
3134 DEBUG_printf(("7http_upgrade(%p)", http));
3135
3136 /*
3137 * Copy the HTTP data to a local variable so we can do the OPTIONS
3138 * request without interfering with the existing request data...
3139 */
3140
3141 memcpy(&myhttp, http, sizeof(myhttp));
3142
3143 /*
3144 * Send an OPTIONS request to the server, requiring SSL or TLS
3145 * encryption on the link...
3146 */
3147
3148 http->field_authorization = NULL; /* Don't free the auth string */
3149
3150 httpClearFields(http);
3151 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
3152 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
3153
3154 if ((ret = httpOptions(http, "*")) == 0)
3155 {
3156 /*
3157 * Wait for the secure connection...
3158 */
3159
3160 while (httpUpdate(http) == HTTP_CONTINUE);
3161 }
3162
3163 httpFlush(http);
3164
3165 /*
3166 * Restore the HTTP request data...
3167 */
3168
3169 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
3170 http->data_encoding = myhttp.data_encoding;
3171 http->data_remaining = myhttp.data_remaining;
3172 http->_data_remaining = myhttp._data_remaining;
3173 http->expect = myhttp.expect;
3174 http->field_authorization = myhttp.field_authorization;
3175 http->digest_tries = myhttp.digest_tries;
3176
3177 /*
3178 * See if we actually went secure...
3179 */
3180
3181 if (!http->tls)
3182 {
3183 /*
3184 * Server does not support HTTP upgrade...
3185 */
3186
3187 DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
3188
3189 # ifdef WIN32
3190 closesocket(http->fd);
3191 # else
3192 close(http->fd);
3193 # endif
3194
3195 http->fd = -1;
3196
3197 return (-1);
3198 }
3199 else
3200 return (ret);
3201 }
3202 #endif /* HAVE_SSL */
3203
3204
3205 /*
3206 * 'http_write()' - Write a buffer to a HTTP connection.
3207 */
3208
3209 static int /* O - Number of bytes written */
3210 http_write(http_t *http, /* I - Connection to server */
3211 const char *buffer, /* I - Buffer for data */
3212 int length) /* I - Number of bytes to write */
3213 {
3214 int tbytes, /* Total bytes sent */
3215 bytes; /* Bytes sent */
3216
3217
3218 http->error = 0;
3219 tbytes = 0;
3220
3221 while (length > 0)
3222 {
3223 #ifdef HAVE_SSL
3224 if (http->tls)
3225 bytes = http_write_ssl(http, buffer, length);
3226 else
3227 #endif /* HAVE_SSL */
3228 bytes = send(http->fd, buffer, length, 0);
3229
3230 if (bytes < 0)
3231 {
3232 #ifdef WIN32
3233 if (WSAGetLastError() != http->error)
3234 {
3235 http->error = WSAGetLastError();
3236 continue;
3237 }
3238 #else
3239 if (errno == EINTR || errno == EAGAIN)
3240 continue;
3241 else if (errno != http->error && errno != ECONNRESET)
3242 {
3243 http->error = errno;
3244 continue;
3245 }
3246 #endif /* WIN32 */
3247
3248 DEBUG_puts("8http_write: error writing data...");
3249
3250 return (-1);
3251 }
3252
3253 buffer += bytes;
3254 tbytes += bytes;
3255 length -= bytes;
3256 }
3257
3258 #ifdef DEBUG
3259 http_debug_hex("http_write", buffer - tbytes, tbytes);
3260 #endif /* DEBUG */
3261
3262 return (tbytes);
3263 }
3264
3265
3266 /*
3267 * 'http_write_chunk()' - Write a chunked buffer.
3268 */
3269
3270 static int /* O - Number bytes written */
3271 http_write_chunk(http_t *http, /* I - Connection to server */
3272 const char *buffer, /* I - Buffer to write */
3273 int length) /* I - Length of buffer */
3274 {
3275 char header[255]; /* Chunk header */
3276 int bytes; /* Bytes written */
3277
3278
3279 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=%d)",
3280 http, buffer, length));
3281
3282 /*
3283 * Write the chunk header, data, and trailer.
3284 */
3285
3286 sprintf(header, "%x\r\n", length);
3287 if (http_write(http, header, (int)strlen(header)) < 0)
3288 {
3289 DEBUG_puts("8http_write_chunk: http_write of length failed!");
3290 return (-1);
3291 }
3292
3293 if ((bytes = http_write(http, buffer, length)) < 0)
3294 {
3295 DEBUG_puts("8http_write_chunk: http_write of buffer failed!");
3296 return (-1);
3297 }
3298
3299 if (http_write(http, "\r\n", 2) < 0)
3300 {
3301 DEBUG_puts("8http_write_chunk: http_write of CR LF failed!");
3302 return (-1);
3303 }
3304
3305 return (bytes);
3306 }
3307
3308
3309 #ifdef HAVE_SSL
3310 /*
3311 * 'http_write_ssl()' - Write to a SSL/TLS connection.
3312 */
3313
3314 static int /* O - Bytes written */
3315 http_write_ssl(http_t *http, /* I - Connection to server */
3316 const char *buf, /* I - Buffer holding data */
3317 int len) /* I - Length of buffer */
3318 {
3319 # if defined(HAVE_LIBSSL)
3320 return (SSL_write((SSL *)(http->tls), buf, len));
3321
3322 # elif defined(HAVE_GNUTLS)
3323 return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
3324 # elif defined(HAVE_CDSASSL)
3325 int result; /* Return value */
3326 OSStatus error; /* Error info */
3327 size_t processed; /* Number of bytes processed */
3328
3329
3330 error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed);
3331
3332 switch (error)
3333 {
3334 case 0 :
3335 result = (int)processed;
3336 break;
3337 case errSSLClosedGraceful :
3338 result = 0;
3339 break;
3340 case errSSLWouldBlock :
3341 if (processed)
3342 result = (int)processed;
3343 else
3344 {
3345 result = -1;
3346 errno = EINTR;
3347 }
3348 break;
3349 default :
3350 errno = EPIPE;
3351 result = -1;
3352 break;
3353 }
3354
3355 return (result);
3356 # endif /* HAVE_LIBSSL */
3357 }
3358 #endif /* HAVE_SSL */
3359
3360
3361 /*
3362 * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
3363 */