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