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