]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
More IPv6/address transparency changes for STR #1313.
[thirdparty/cups.git] / cups / http.c
1 /*
2 * "$Id$"
3 *
4 * HTTP routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
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 *
28 * httpCheck() - Check to see if there is a pending response from
29 * the server.
30 * httpClearCookie() - Clear the cookie value(s).
31 * httpClose() - Close an HTTP connection...
32 * httpConnect() - Connect to a HTTP server.
33 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
34 * httpDelete() - Send a DELETE request to the server.
35 * httpEncryption() - Set the required encryption on the link.
36 * httpFlush() - Flush data from a HTTP connection.
37 * httpFlushWrite() - Flush data in write buffer.
38 * httpGet() - Send a GET request to the server.
39 * httpGetLength() - Get the amount of data remaining from the
40 * content-length or transfer-encoding fields.
41 * httpGetLength2() - Get the amount of data remaining from the
42 * content-length or transfer-encoding fields.
43 * httpGetSubField() - Get a sub-field value.
44 * httpGets() - Get a line of text from a HTTP connection.
45 * httpHead() - Send a HEAD request to the server.
46 * httpInitialize() - Initialize the HTTP interface library and set the
47 * default HTTP proxy (if any).
48 * httpOptions() - Send an OPTIONS request to the server.
49 * httpPost() - Send a POST request to the server.
50 * httpPrintf() - Print a formatted string to a HTTP connection.
51 * httpPut() - Send a PUT request to the server.
52 * httpRead() - Read data from a HTTP connection.
53 * httpReconnect() - Reconnect to a HTTP server...
54 * httpSetCookie() - Set the cookie value(s)...
55 * httpSetField() - Set the value of an HTTP header.
56 * httpSetLength() - Set the content-length and transfer-encoding.
57 * httpTrace() - Send an TRACE request to the server.
58 * httpUpdate() - Update the current HTTP state for incoming data.
59 * httpWait() - Wait for data available on a connection.
60 * httpWrite() - Write data to a HTTP connection.
61 * http_field() - Return the field index for a field name.
62 * http_read_ssl() - Read from a SSL/TLS connection.
63 * http_send() - Send a request with all fields and the trailing
64 * blank line.
65 * http_setup_ssl() - Set up SSL/TLS on a connection.
66 * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
67 * http_upgrade() - Force upgrade to TLS encryption.
68 * http_wait() - Wait for data available on a connection.
69 * http_write() - Write data to a connection.
70 * http_write_ssl() - Write to a SSL/TLS connection.
71 * http_read_cdsa() - Read function for CDSA decryption code.
72 * http_write_cdsa() - Write function for CDSA encryption code.
73 */
74
75 /*
76 * Include necessary headers...
77 */
78
79 #include "http-private.h"
80 #include "globals.h"
81 #include "debug.h"
82 #include <stdlib.h>
83 #include <fcntl.h>
84 #include <errno.h>
85 #ifndef WIN32
86 # include <signal.h>
87 # include <sys/time.h>
88 # include <sys/resource.h>
89 #endif /* !WIN32 */
90
91
92 /*
93 * Some operating systems have done away with the Fxxxx constants for
94 * the fcntl() call; this works around that "feature"...
95 */
96
97 #ifndef FNONBLK
98 # define FNONBLK O_NONBLOCK
99 #endif /* !FNONBLK */
100
101
102 /*
103 * Local functions...
104 */
105
106 static http_field_t http_field(const char *name);
107 static int http_send(http_t *http, http_state_t request,
108 const char *uri);
109 static int http_wait(http_t *http, int msec);
110 static int http_write(http_t *http, const char *buffer,
111 int length);
112 static int http_write_chunk(http_t *http, const char *buffer,
113 int length);
114 #ifdef HAVE_SSL
115 # ifdef HAVE_CDSASSL
116 static OSStatus http_read_cdsa(SSLConnectionRef connection, void *data, size_t *dataLength);
117 # endif /* HAVE_CDSASSL */
118 static int http_read_ssl(http_t *http, char *buf, int len);
119 static int http_setup_ssl(http_t *http);
120 static void http_shutdown_ssl(http_t *http);
121 static int http_upgrade(http_t *http);
122 # ifdef HAVE_CDSASSL
123 static OSStatus http_write_cdsa(SSLConnectionRef connection, const void *data, size_t *dataLength);
124 # endif /* HAVE_CDSASSL */
125 static int http_write_ssl(http_t *http, const char *buf, int len);
126 #endif /* HAVE_SSL */
127
128
129 /*
130 * Local globals...
131 */
132
133 static const char * const http_fields[] =
134 {
135 "Accept-Language",
136 "Accept-Ranges",
137 "Authorization",
138 "Connection",
139 "Content-Encoding",
140 "Content-Language",
141 "Content-Length",
142 "Content-Location",
143 "Content-MD5",
144 "Content-Range",
145 "Content-Type",
146 "Content-Version",
147 "Date",
148 "Host",
149 "If-Modified-Since",
150 "If-Unmodified-since",
151 "Keep-Alive",
152 "Last-Modified",
153 "Link",
154 "Location",
155 "Range",
156 "Referer",
157 "Retry-After",
158 "Transfer-Encoding",
159 "Upgrade",
160 "User-Agent",
161 "WWW-Authenticate"
162 };
163
164
165 /*
166 * 'httpCheck()' - Check to see if there is a pending response from the server.
167 */
168
169 int /* O - 0 = no data, 1 = data available */
170 httpCheck(http_t *http) /* I - HTTP connection */
171 {
172 return (httpWait(http, 0));
173 }
174
175
176 /*
177 * 'httpClearCookie()' - Clear the cookie value(s).
178 *
179 * @since CUPS 1.1.19@
180 */
181
182 void
183 httpClearCookie(http_t *http) /* I - Connection */
184 {
185 if (!http)
186 return;
187
188 if (http->cookie)
189 {
190 free(http->cookie);
191 http->cookie = NULL;
192 }
193 }
194
195
196 /*
197 * 'httpClose()' - Close an HTTP connection...
198 */
199
200 void
201 httpClose(http_t *http) /* I - Connection to close */
202 {
203 DEBUG_printf(("httpClose(http=%p)\n", http));
204
205 if (!http)
206 return;
207
208 httpAddrFreeList(http->addrlist);
209
210 if (http->input_set)
211 free(http->input_set);
212
213 if (http->cookie)
214 free(http->cookie);
215
216 #ifdef HAVE_SSL
217 if (http->tls)
218 http_shutdown_ssl(http);
219 #endif /* HAVE_SSL */
220
221 #ifdef WIN32
222 closesocket(http->fd);
223 #else
224 close(http->fd);
225 #endif /* WIN32 */
226
227 free(http);
228 }
229
230
231 /*
232 * 'httpConnect()' - Connect to a HTTP server.
233 */
234
235 http_t * /* O - New HTTP connection */
236 httpConnect(const char *host, /* I - Host to connect to */
237 int port) /* I - Port number */
238 {
239 http_encryption_t encryption; /* Type of encryption to use */
240
241
242 /*
243 * Set the default encryption status...
244 */
245
246 if (port == 443)
247 encryption = HTTP_ENCRYPT_ALWAYS;
248 else
249 encryption = HTTP_ENCRYPT_IF_REQUESTED;
250
251 return (httpConnectEncrypt(host, port, encryption));
252 }
253
254
255 /*
256 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
257 */
258
259 http_t * /* O - New HTTP connection */
260 httpConnectEncrypt(
261 const char *host, /* I - Host to connect to */
262 int port, /* I - Port number */
263 http_encryption_t encryption) /* I - Type of encryption to use */
264 {
265 http_t *http; /* New HTTP connection */
266 http_addrlist_t *addrlist; /* Host address data */
267 char service[255]; /* Service name */
268
269
270 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)\n",
271 host ? host : "(null)", port, encryption));
272
273 if (!host)
274 return (NULL);
275
276 httpInitialize();
277
278 /*
279 * Lookup the host...
280 */
281
282 sprintf(service, "%d", port);
283
284 if ((addrlist = httpAddrGetList(host, AF_UNSPEC, service)) == NULL)
285 return (NULL);
286
287 /*
288 * Allocate memory for the structure...
289 */
290
291 http = calloc(sizeof(http_t), 1);
292 if (http == NULL)
293 return (NULL);
294
295 http->version = HTTP_1_1;
296 http->blocking = 1;
297 http->activity = time(NULL);
298 http->fd = -1;
299
300 /*
301 * Set the encryption status...
302 */
303
304 if (port == 443) /* Always use encryption for https */
305 http->encryption = HTTP_ENCRYPT_ALWAYS;
306 else
307 http->encryption = encryption;
308
309 /*
310 * Loop through the addresses we have until one of them connects...
311 */
312
313 strlcpy(http->hostname, host, sizeof(http->hostname));
314
315 /*
316 * Connect to the remote system...
317 */
318
319 http->addrlist = addrlist;
320
321 if (!httpReconnect(http))
322 return (http);
323
324 /*
325 * Could not connect to any known address - bail out!
326 */
327
328 httpAddrFreeList(addrlist);
329
330 free(http);
331
332 return (NULL);
333 }
334
335
336 /*
337 * 'httpDelete()' - Send a DELETE request to the server.
338 */
339
340 int /* O - Status of call (0 = success) */
341 httpDelete(http_t *http, /* I - HTTP data */
342 const char *uri) /* I - URI to delete */
343 {
344 return (http_send(http, HTTP_DELETE, uri));
345 }
346
347
348 /*
349 * 'httpEncryption()' - Set the required encryption on the link.
350 */
351
352 int /* O - -1 on error, 0 on success */
353 httpEncryption(http_t *http, /* I - HTTP data */
354 http_encryption_t e) /* I - New encryption preference */
355 {
356 DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e));
357
358 #ifdef HAVE_SSL
359 if (!http)
360 return (0);
361
362 http->encryption = e;
363
364 if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
365 (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
366 return (httpReconnect(http));
367 else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
368 return (http_upgrade(http));
369 else
370 return (0);
371 #else
372 if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
373 return (-1);
374 else
375 return (0);
376 #endif /* HAVE_SSL */
377 }
378
379
380 /*
381 * 'httpFlush()' - Flush data from a HTTP connection.
382 */
383
384 void
385 httpFlush(http_t *http) /* I - HTTP data */
386 {
387 char buffer[8192]; /* Junk buffer */
388
389
390 DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state));
391
392 while (httpRead(http, buffer, sizeof(buffer)) > 0);
393 }
394
395
396 /*
397 * 'httpFlushWrite()' - Flush data in write buffer.
398 *
399 * @since CUPS 1.2@
400 */
401
402 int /* O - Bytes written or -1 on error */
403 httpFlushWrite(http_t *http) /* I - HTTP data */
404 {
405 int bytes; /* Bytes written */
406
407
408 DEBUG_printf(("httpFlushWrite(http=%p)\n", http));
409
410 if (!http || !http->wused)
411 return (0);
412
413 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
414 bytes = http_write_chunk(http, http->wbuffer, http->wused);
415 else
416 bytes = http_write(http, http->wbuffer, http->wused);
417
418 http->wused = 0;
419
420 return (bytes);
421 }
422
423
424 /*
425 * 'httpGet()' - Send a GET request to the server.
426 */
427
428 int /* O - Status of call (0 = success) */
429 httpGet(http_t *http, /* I - HTTP data */
430 const char *uri) /* I - URI to get */
431 {
432 return (http_send(http, HTTP_GET, uri));
433 }
434
435
436 /*
437 * 'httpGetSubField()' - Get a sub-field value.
438 */
439
440 char * /* O - Value or NULL */
441 httpGetSubField(http_t *http, /* I - HTTP data */
442 http_field_t field, /* I - Field index */
443 const char *name, /* I - Name of sub-field */
444 char *value) /* O - Value string */
445 {
446 const char *fptr; /* Pointer into field */
447 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
448 *ptr; /* Pointer into string buffer */
449
450
451 DEBUG_printf(("httpGetSubField(http=%p, field=%d, name=\"%s\", value=%p)\n",
452 http, field, name, value));
453
454 if (http == NULL ||
455 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
456 field > HTTP_FIELD_WWW_AUTHENTICATE ||
457 name == NULL || value == NULL)
458 return (NULL);
459
460 for (fptr = http->fields[field]; *fptr;)
461 {
462 /*
463 * Skip leading whitespace...
464 */
465
466 while (isspace(*fptr & 255))
467 fptr ++;
468
469 if (*fptr == ',')
470 {
471 fptr ++;
472 continue;
473 }
474
475 /*
476 * Get the sub-field name...
477 */
478
479 for (ptr = temp;
480 *fptr && *fptr != '=' && !isspace(*fptr & 255) && ptr < (temp + sizeof(temp) - 1);
481 *ptr++ = *fptr++);
482
483 *ptr = '\0';
484
485 DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp));
486
487 /*
488 * Skip trailing chars up to the '='...
489 */
490
491 while (isspace(*fptr & 255))
492 fptr ++;
493
494 if (!*fptr)
495 break;
496
497 if (*fptr != '=')
498 continue;
499
500 /*
501 * Skip = and leading whitespace...
502 */
503
504 fptr ++;
505
506 while (isspace(*fptr & 255))
507 fptr ++;
508
509 if (*fptr == '\"')
510 {
511 /*
512 * Read quoted string...
513 */
514
515 for (ptr = value, fptr ++;
516 *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1);
517 *ptr++ = *fptr++);
518
519 *ptr = '\0';
520
521 while (*fptr && *fptr != '\"')
522 fptr ++;
523
524 if (*fptr)
525 fptr ++;
526 }
527 else
528 {
529 /*
530 * Read unquoted string...
531 */
532
533 for (ptr = value;
534 *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1);
535 *ptr++ = *fptr++);
536
537 *ptr = '\0';
538
539 while (*fptr && !isspace(*fptr & 255) && *fptr != ',')
540 fptr ++;
541 }
542
543 DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value));
544
545 /*
546 * See if this is the one...
547 */
548
549 if (strcmp(name, temp) == 0)
550 return (value);
551 }
552
553 value[0] = '\0';
554
555 return (NULL);
556 }
557
558
559 /*
560 * 'httpGetLength()' - Get the amount of data remaining from the
561 * content-length or transfer-encoding fields.
562 *
563 * This function is deprecated and will not return lengths larger than
564 * 2^31 - 1; use httpGetLength2() instead.
565 *
566 * @since CUPS 1.2@
567 */
568
569 int /* O - Content length */
570 httpGetLength(http_t *http) /* I - HTTP data */
571 {
572 /*
573 * Get the read content length and return the 32-bit value.
574 */
575
576 httpGetLength2(http);
577
578 return (http->_data_remaining);
579 }
580
581
582 /*
583 * 'httpGetLength2()' - Get the amount of data remaining from the
584 * content-length or transfer-encoding fields.
585 *
586 * This function returns the complete content length, even for
587 * content larger than 2^31 - 1.
588 */
589
590 off_t /* O - Content length */
591 httpGetLength2(http_t *http) /* I - HTTP data */
592 {
593 DEBUG_printf(("httpGetLength2(http=%p), state=%d\n", http, http->state));
594
595 if (!strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"))
596 {
597 DEBUG_puts("httpGetLength2: chunked request!");
598
599 http->data_encoding = HTTP_ENCODE_CHUNKED;
600 http->data_remaining = 0;
601 }
602 else
603 {
604 http->data_encoding = HTTP_ENCODE_LENGTH;
605
606 /*
607 * The following is a hack for HTTP servers that don't send a
608 * content-length or transfer-encoding field...
609 *
610 * If there is no content-length then the connection must close
611 * after the transfer is complete...
612 */
613
614 if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0')
615 http->data_remaining = 2147483647;
616 else
617 http->data_remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH],
618 NULL, 10);
619
620 DEBUG_printf(("httpGetLength2: content_length=" CUPS_LLFMT "\n",
621 CUPS_LLCAST http->data_remaining));
622 }
623
624 if (http->data_remaining <= INT_MAX)
625 http->_data_remaining = (int)http->data_remaining;
626 else
627 http->_data_remaining = INT_MAX;
628
629 return (http->data_remaining);
630 }
631
632
633 /*
634 * 'httpGets()' - Get a line of text from a HTTP connection.
635 */
636
637 char * /* O - Line or NULL */
638 httpGets(char *line, /* I - Line to read into */
639 int length, /* I - Max length of buffer */
640 http_t *http) /* I - HTTP data */
641 {
642 char *lineptr, /* Pointer into line */
643 *lineend, /* End of line */
644 *bufptr, /* Pointer into input buffer */
645 *bufend; /* Pointer to end of buffer */
646 int bytes, /* Number of bytes read */
647 eol; /* End-of-line? */
648
649
650 DEBUG_printf(("httpGets(line=%p, length=%d, http=%p)\n", line, length, http));
651
652 if (http == NULL || line == NULL)
653 return (NULL);
654
655 /*
656 * Read a line from the buffer...
657 */
658
659 lineptr = line;
660 lineend = line + length - 1;
661 eol = 0;
662
663 while (lineptr < lineend)
664 {
665 /*
666 * Pre-load the buffer as needed...
667 */
668
669 #ifdef WIN32
670 WSASetLastError(0);
671 #else
672 errno = 0;
673 #endif /* WIN32 */
674
675 while (http->used == 0)
676 {
677 /*
678 * No newline; see if there is more data to be read...
679 */
680
681 if (!http->blocking && !http_wait(http, 1000))
682 return (NULL);
683
684 #ifdef HAVE_SSL
685 if (http->tls)
686 bytes = http_read_ssl(http, http->buffer + http->used,
687 HTTP_MAX_BUFFER - http->used);
688 else
689 #endif /* HAVE_SSL */
690 bytes = recv(http->fd, http->buffer + http->used,
691 HTTP_MAX_BUFFER - http->used, 0);
692
693 DEBUG_printf(("httpGets: read %d bytes...\n", bytes));
694
695 if (bytes < 0)
696 {
697 /*
698 * Nope, can't get a line this time...
699 */
700
701 #ifdef WIN32
702 if (WSAGetLastError() != http->error)
703 {
704 http->error = WSAGetLastError();
705 continue;
706 }
707
708 DEBUG_printf(("httpGets: recv() error %d!\n", WSAGetLastError()));
709 #else
710 DEBUG_printf(("httpGets: recv() error %d!\n", errno));
711
712 if (errno == EINTR)
713 continue;
714 else if (errno != http->error)
715 {
716 http->error = errno;
717 continue;
718 }
719 #endif /* WIN32 */
720
721 return (NULL);
722 }
723 else if (bytes == 0)
724 {
725 http->error = EPIPE;
726
727 return (NULL);
728 }
729
730 /*
731 * Yup, update the amount used...
732 */
733
734 http->used += bytes;
735 }
736
737 /*
738 * Now copy as much of the current line as possible...
739 */
740
741 for (bufptr = http->buffer, bufend = http->buffer + http->used;
742 lineptr < lineend && bufptr < bufend;)
743 {
744 if (*bufptr == 0x0a)
745 {
746 eol = 1;
747 bufptr ++;
748 break;
749 }
750 else if (*bufptr == 0x0d)
751 bufptr ++;
752 else
753 *lineptr++ = *bufptr++;
754 }
755
756 http->used -= bufptr - http->buffer;
757 if (http->used > 0)
758 memmove(http->buffer, bufptr, http->used);
759
760 if (eol)
761 {
762 /*
763 * End of line...
764 */
765
766 http->activity = time(NULL);
767
768 *lineptr = '\0';
769
770 DEBUG_printf(("httpGets: Returning \"%s\"\n", line));
771
772 return (line);
773 }
774 }
775
776 DEBUG_puts("httpGets: No new line available!");
777
778 return (NULL);
779 }
780
781
782 /*
783 * 'httpHead()' - Send a HEAD request to the server.
784 */
785
786 int /* O - Status of call (0 = success) */
787 httpHead(http_t *http, /* I - HTTP data */
788 const char *uri) /* I - URI for head */
789 {
790 return (http_send(http, HTTP_HEAD, uri));
791 }
792
793
794 /*
795 * 'httpInitialize()' - Initialize the HTTP interface library and set the
796 * default HTTP proxy (if any).
797 */
798
799 void
800 httpInitialize(void)
801 {
802 #ifdef HAVE_LIBSSL
803 # ifndef WIN32
804 struct timeval curtime; /* Current time in microseconds */
805 # endif /* !WIN32 */
806 int i; /* Looping var */
807 unsigned char data[1024]; /* Seed data */
808 #endif /* HAVE_LIBSSL */
809
810 #ifdef WIN32
811 WSADATA winsockdata; /* WinSock data */
812 static int initialized = 0; /* Has WinSock been initialized? */
813
814
815 if (!initialized)
816 WSAStartup(MAKEWORD(1,1), &winsockdata);
817 #elif defined(HAVE_SIGSET)
818 sigset(SIGPIPE, SIG_IGN);
819 #elif defined(HAVE_SIGACTION)
820 struct sigaction action; /* POSIX sigaction data */
821
822
823 /*
824 * Ignore SIGPIPE signals...
825 */
826
827 memset(&action, 0, sizeof(action));
828 action.sa_handler = SIG_IGN;
829 sigaction(SIGPIPE, &action, NULL);
830 #else
831 signal(SIGPIPE, SIG_IGN);
832 #endif /* WIN32 */
833
834 #ifdef HAVE_GNUTLS
835 gnutls_global_init();
836 #endif /* HAVE_GNUTLS */
837
838 #ifdef HAVE_LIBSSL
839 SSL_load_error_strings();
840 SSL_library_init();
841
842 /*
843 * Using the current time is a dubious random seed, but on some systems
844 * it is the best we can do (on others, this seed isn't even used...)
845 */
846
847 #ifdef WIN32
848 #else
849 gettimeofday(&curtime, NULL);
850 srand(curtime.tv_sec + curtime.tv_usec);
851 #endif /* WIN32 */
852
853 for (i = 0; i < sizeof(data); i ++)
854 data[i] = rand(); /* Yes, this is a poor source of random data... */
855
856 RAND_seed(&data, sizeof(data));
857 #endif /* HAVE_LIBSSL */
858 }
859
860
861 /*
862 * 'httpOptions()' - Send an OPTIONS request to the server.
863 */
864
865 int /* O - Status of call (0 = success) */
866 httpOptions(http_t *http, /* I - HTTP data */
867 const char *uri) /* I - URI for options */
868 {
869 return (http_send(http, HTTP_OPTIONS, uri));
870 }
871
872
873 /*
874 * 'httpPost()' - Send a POST request to the server.
875 */
876
877 int /* O - Status of call (0 = success) */
878 httpPost(http_t *http, /* I - HTTP data */
879 const char *uri) /* I - URI for post */
880 {
881 return (http_send(http, HTTP_POST, uri));
882 }
883
884
885 /*
886 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
887 */
888
889 int /* O - Number of bytes written */
890 httpPrintf(http_t *http, /* I - HTTP data */
891 const char *format, /* I - printf-style format string */
892 ...) /* I - Additional args as needed */
893 {
894 int bytes; /* Number of bytes to write */
895 char buf[16384]; /* Buffer for formatted string */
896 va_list ap; /* Variable argument pointer */
897
898
899 DEBUG_printf(("httpPrintf(http=%p, format=\"%s\", ...)\n", http, format));
900
901 va_start(ap, format);
902 bytes = vsnprintf(buf, sizeof(buf), format, ap);
903 va_end(ap);
904
905 DEBUG_printf(("httpPrintf: %s", buf));
906
907 if (http->wused)
908 {
909 DEBUG_puts(" flushing existing data...");
910
911 if (httpFlushWrite(http) < 0)
912 return (-1);
913 }
914
915 return (http_write(http, buf, bytes));
916 }
917
918
919 /*
920 * 'httpPut()' - Send a PUT request to the server.
921 */
922
923 int /* O - Status of call (0 = success) */
924 httpPut(http_t *http, /* I - HTTP data */
925 const char *uri) /* I - URI to put */
926 {
927 return (http_send(http, HTTP_PUT, uri));
928 }
929
930
931 /*
932 * 'httpRead()' - Read data from a HTTP connection.
933 */
934
935 int /* O - Number of bytes read */
936 httpRead(http_t *http, /* I - HTTP data */
937 char *buffer, /* I - Buffer for data */
938 int length) /* I - Maximum number of bytes */
939 {
940 int bytes; /* Bytes read */
941 char len[32]; /* Length string */
942
943
944 DEBUG_printf(("httpRead(http=%p, buffer=%p, length=%d)\n",
945 http, buffer, length));
946
947 if (http == NULL || buffer == NULL)
948 return (-1);
949
950 http->activity = time(NULL);
951
952 if (length <= 0)
953 return (0);
954
955 if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
956 http->data_remaining <= 0)
957 {
958 DEBUG_puts("httpRead: Getting chunk length...");
959
960 if (httpGets(len, sizeof(len), http) == NULL)
961 {
962 DEBUG_puts("httpRead: Could not get length!");
963 return (0);
964 }
965
966 http->data_remaining = strtoll(len, NULL, 16);
967 if (http->data_remaining < 0)
968 {
969 DEBUG_puts("httpRead: Negative chunk length!");
970 return (0);
971 }
972 }
973
974 DEBUG_printf(("httpRead: data_remaining=" CUPS_LLFMT "\n",
975 CUPS_LLCAST http->data_remaining));
976
977 if (http->data_remaining <= 0)
978 {
979 /*
980 * A zero-length chunk ends a transfer; unless we are reading POST
981 * data, go idle...
982 */
983
984 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
985 httpGets(len, sizeof(len), http);
986
987 if (http->state == HTTP_POST_RECV)
988 http->state ++;
989 else
990 http->state = HTTP_WAITING;
991
992 /*
993 * Prevent future reads for this request...
994 */
995
996 http->data_encoding = HTTP_ENCODE_LENGTH;
997
998 return (0);
999 }
1000 else if (length > http->data_remaining)
1001 length = http->data_remaining;
1002
1003 if (http->used == 0 && length <= 256)
1004 {
1005 /*
1006 * Buffer small reads for better performance...
1007 */
1008
1009 if (!http->blocking && !httpWait(http, 1000))
1010 return (0);
1011
1012 if (http->data_remaining > sizeof(http->buffer))
1013 bytes = sizeof(http->buffer);
1014 else
1015 bytes = http->data_remaining;
1016
1017 #ifdef HAVE_SSL
1018 if (http->tls)
1019 bytes = http_read_ssl(http, http->buffer, bytes);
1020 else
1021 #endif /* HAVE_SSL */
1022 {
1023 DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n",
1024 bytes));
1025
1026 bytes = recv(http->fd, http->buffer, bytes, 0);
1027
1028 DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n",
1029 bytes));
1030 }
1031
1032 if (bytes > 0)
1033 http->used = bytes;
1034 else if (bytes < 0)
1035 {
1036 #ifdef WIN32
1037 http->error = WSAGetLastError();
1038 return (-1);
1039 #else
1040 if (errno != EINTR)
1041 {
1042 http->error = errno;
1043 return (-1);
1044 }
1045 #endif /* WIN32 */
1046 }
1047 else
1048 {
1049 http->error = EPIPE;
1050 return (0);
1051 }
1052 }
1053
1054 if (http->used > 0)
1055 {
1056 if (length > http->used)
1057 length = http->used;
1058
1059 bytes = length;
1060
1061 DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes));
1062
1063 memcpy(buffer, http->buffer, length);
1064 http->used -= length;
1065
1066 if (http->used > 0)
1067 memmove(http->buffer, http->buffer + length, http->used);
1068 }
1069 #ifdef HAVE_SSL
1070 else if (http->tls)
1071 {
1072 if (!http->blocking && !httpWait(http, 1000))
1073 return (0);
1074
1075 bytes = http_read_ssl(http, buffer, length);
1076 }
1077 #endif /* HAVE_SSL */
1078 else
1079 {
1080 if (!http->blocking && !httpWait(http, 1000))
1081 return (0);
1082
1083 DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length));
1084
1085 while ((bytes = recv(http->fd, buffer, length, 0)) < 0)
1086 if (errno != EINTR)
1087 break;
1088
1089 DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes));
1090 }
1091
1092 if (bytes > 0)
1093 {
1094 http->data_remaining -= bytes;
1095
1096 if (http->data_remaining <= INT_MAX)
1097 http->_data_remaining = (int)http->data_remaining;
1098 else
1099 http->_data_remaining = INT_MAX;
1100 }
1101 else if (bytes < 0)
1102 {
1103 #ifdef WIN32
1104 http->error = WSAGetLastError();
1105 #else
1106 if (errno == EINTR)
1107 bytes = 0;
1108 else
1109 http->error = errno;
1110 #endif /* WIN32 */
1111 }
1112 else
1113 {
1114 http->error = EPIPE;
1115 return (0);
1116 }
1117
1118 if (http->data_remaining == 0)
1119 {
1120 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1121 httpGets(len, sizeof(len), http);
1122
1123 if (http->data_encoding != HTTP_ENCODE_CHUNKED)
1124 {
1125 if (http->state == HTTP_POST_RECV)
1126 http->state ++;
1127 else
1128 http->state = HTTP_WAITING;
1129 }
1130 }
1131
1132 #ifdef DEBUG
1133 {
1134 int i, j, ch;
1135 printf("httpRead: Read %d bytes:\n", bytes);
1136 for (i = 0; i < bytes; i += 16)
1137 {
1138 printf(" ");
1139
1140 for (j = 0; j < 16 && (i + j) < bytes; j ++)
1141 printf(" %02X", buffer[i + j] & 255);
1142
1143 while (j < 16)
1144 {
1145 printf(" ");
1146 j ++;
1147 }
1148
1149 printf(" ");
1150 for (j = 0; j < 16 && (i + j) < bytes; j ++)
1151 {
1152 ch = buffer[i + j] & 255;
1153
1154 if (ch < ' ' || ch == 127)
1155 ch = '.';
1156
1157 putchar(ch);
1158 }
1159 putchar('\n');
1160 }
1161 }
1162 #endif /* DEBUG */
1163
1164 return (bytes);
1165 }
1166
1167
1168 /*
1169 * 'httpReconnect()' - Reconnect to a HTTP server...
1170 */
1171
1172 int /* O - 0 on success, non-zero on failure */
1173 httpReconnect(http_t *http) /* I - HTTP data */
1174 {
1175 http_addrlist_t *addr; /* Connected address */
1176
1177
1178 DEBUG_printf(("httpReconnect(http=%p)\n", http));
1179
1180 if (!http)
1181 return (-1);
1182
1183 #ifdef HAVE_SSL
1184 if (http->tls)
1185 http_shutdown_ssl(http);
1186 #endif /* HAVE_SSL */
1187
1188 /*
1189 * Close any previously open socket...
1190 */
1191
1192 if (http->fd >= 0)
1193 #ifdef WIN32
1194 closesocket(http->fd);
1195 #else
1196 close(http->fd);
1197 #endif /* WIN32 */
1198
1199 /*
1200 * Connect to the server...
1201 */
1202
1203 if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL)
1204 {
1205 /*
1206 * Unable to connect...
1207 */
1208
1209 #ifdef WIN32
1210 http->error = WSAGetLastError();
1211 #else
1212 http->error = errno;
1213 #endif /* WIN32 */
1214 http->status = HTTP_ERROR;
1215
1216 return (-1);
1217 }
1218
1219 http->hostaddr = &(addr->addr);
1220 http->error = 0;
1221 http->status = HTTP_CONTINUE;
1222
1223 #ifdef HAVE_SSL
1224 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
1225 {
1226 /*
1227 * Always do encryption via SSL.
1228 */
1229
1230 if (http_setup_ssl(http) != 0)
1231 {
1232 #ifdef WIN32
1233 closesocket(http->fd);
1234 #else
1235 close(http->fd);
1236 #endif /* WIN32 */
1237
1238 return (-1);
1239 }
1240 }
1241 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
1242 return (http_upgrade(http));
1243 #endif /* HAVE_SSL */
1244
1245 return (0);
1246 }
1247
1248
1249 /*
1250 * 'httpSetCookie()' - Set the cookie value(s)...
1251 *
1252 * @since CUPS 1.1.19@
1253 */
1254
1255 void
1256 httpSetCookie(http_t *http, /* I - Connection */
1257 const char *cookie) /* I - Cookie string */
1258 {
1259 if (!http)
1260 return;
1261
1262 if (http->cookie)
1263 free(http->cookie);
1264
1265 if (cookie)
1266 http->cookie = strdup(cookie);
1267 else
1268 http->cookie = NULL;
1269 }
1270
1271
1272 /*
1273 * 'httpSetField()' - Set the value of an HTTP header.
1274 */
1275
1276 void
1277 httpSetField(http_t *http, /* I - HTTP data */
1278 http_field_t field, /* I - Field index */
1279 const char *value) /* I - Value */
1280 {
1281 if (http == NULL ||
1282 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
1283 field > HTTP_FIELD_WWW_AUTHENTICATE ||
1284 value == NULL)
1285 return;
1286
1287 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
1288 }
1289
1290
1291 /*
1292 * 'httpSetLength()' - Set the content-length and content-encoding.
1293 *
1294 * @since CUPS 1.2@
1295 */
1296
1297 void
1298 httpSetLength(http_t *http, /* I - HTTP data */
1299 off_t length) /* I - Length (0 for chunked) */
1300 {
1301 if (!http || length < 0)
1302 return;
1303
1304 if (!length)
1305 {
1306 strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked");
1307 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
1308 }
1309 else
1310 {
1311 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
1312 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
1313 CUPS_LLFMT, CUPS_LLCAST length);
1314 }
1315 }
1316
1317
1318 /*
1319 * 'httpTrace()' - Send an TRACE request to the server.
1320 */
1321
1322 int /* O - Status of call (0 = success) */
1323 httpTrace(http_t *http, /* I - HTTP data */
1324 const char *uri) /* I - URI for trace */
1325 {
1326 return (http_send(http, HTTP_TRACE, uri));
1327 }
1328
1329
1330 /*
1331 * 'httpUpdate()' - Update the current HTTP state for incoming data.
1332 */
1333
1334 http_status_t /* O - HTTP status */
1335 httpUpdate(http_t *http) /* I - HTTP data */
1336 {
1337 char line[32768], /* Line from connection... */
1338 *value; /* Pointer to value on line */
1339 http_field_t field; /* Field index */
1340 int major, minor, /* HTTP version numbers */
1341 status; /* Request status */
1342
1343
1344 DEBUG_printf(("httpUpdate(http=%p), state=%d\n", http, http->state));
1345
1346 /*
1347 * Flush pending data, if any...
1348 */
1349
1350 if (http->wused)
1351 {
1352 DEBUG_puts(" flushing buffer...");
1353
1354 if (httpFlushWrite(http) < 0)
1355 return (HTTP_ERROR);
1356 }
1357
1358 /*
1359 * If we haven't issued any commands, then there is nothing to "update"...
1360 */
1361
1362 if (http->state == HTTP_WAITING)
1363 return (HTTP_CONTINUE);
1364
1365 /*
1366 * Grab all of the lines we can from the connection...
1367 */
1368
1369 while (httpGets(line, sizeof(line), http) != NULL)
1370 {
1371 DEBUG_printf(("httpUpdate: Got \"%s\"\n", line));
1372
1373 if (line[0] == '\0')
1374 {
1375 /*
1376 * Blank line means the start of the data section (if any). Return
1377 * the result code, too...
1378 *
1379 * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
1380 * Instead, we just return HTTP_CONTINUE to the caller and keep on
1381 * tryin'...
1382 */
1383
1384 if (http->status == HTTP_CONTINUE)
1385 return (http->status);
1386
1387 if (http->status < HTTP_BAD_REQUEST)
1388 http->digest_tries = 0;
1389
1390 #ifdef HAVE_SSL
1391 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
1392 {
1393 if (http_setup_ssl(http) != 0)
1394 {
1395 # ifdef WIN32
1396 closesocket(http->fd);
1397 # else
1398 close(http->fd);
1399 # endif /* WIN32 */
1400
1401 return (HTTP_ERROR);
1402 }
1403
1404 return (HTTP_CONTINUE);
1405 }
1406 #endif /* HAVE_SSL */
1407
1408 httpGetLength2(http);
1409
1410 switch (http->state)
1411 {
1412 case HTTP_GET :
1413 case HTTP_POST :
1414 case HTTP_POST_RECV :
1415 case HTTP_PUT :
1416 http->state ++;
1417 case HTTP_POST_SEND :
1418 break;
1419
1420 default :
1421 http->state = HTTP_WAITING;
1422 break;
1423 }
1424
1425 return (http->status);
1426 }
1427 else if (strncmp(line, "HTTP/", 5) == 0)
1428 {
1429 /*
1430 * Got the beginning of a response...
1431 */
1432
1433 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
1434 return (HTTP_ERROR);
1435
1436 http->version = (http_version_t)(major * 100 + minor);
1437 http->status = (http_status_t)status;
1438 }
1439 else if ((value = strchr(line, ':')) != NULL)
1440 {
1441 /*
1442 * Got a value...
1443 */
1444
1445 *value++ = '\0';
1446 while (isspace(*value & 255))
1447 value ++;
1448
1449 /*
1450 * Be tolerants of servers that send unknown attribute fields...
1451 */
1452
1453 if (!strcasecmp(line, "expect"))
1454 {
1455 /*
1456 * "Expect: 100-continue" or similar...
1457 */
1458
1459 http->expect = (http_status_t)atoi(value);
1460 }
1461 else if (!strcasecmp(line, "cookie"))
1462 {
1463 /*
1464 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
1465 */
1466
1467 httpSetCookie(http, value);
1468 }
1469 else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
1470 {
1471 DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line));
1472 continue;
1473 }
1474 else
1475 httpSetField(http, field, value);
1476 }
1477 else
1478 {
1479 http->status = HTTP_ERROR;
1480 return (HTTP_ERROR);
1481 }
1482 }
1483
1484 /*
1485 * See if there was an error...
1486 */
1487
1488 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
1489 return (http->status);
1490
1491 if (http->error)
1492 {
1493 DEBUG_printf(("httpUpdate: socket error %d - %s\n", http->error,
1494 strerror(http->error)));
1495 http->status = HTTP_ERROR;
1496 return (HTTP_ERROR);
1497 }
1498
1499 /*
1500 * If we haven't already returned, then there is nothing new...
1501 */
1502
1503 return (HTTP_CONTINUE);
1504 }
1505
1506
1507 /*
1508 * 'httpWait()' - Wait for data available on a connection.
1509 *
1510 * @since CUPS 1.1.19@
1511 */
1512
1513 int /* O - 1 if data is available, 0 otherwise */
1514 httpWait(http_t *http, /* I - HTTP data */
1515 int msec) /* I - Milliseconds to wait */
1516 {
1517 /*
1518 * First see if there is data in the buffer...
1519 */
1520
1521 if (http == NULL)
1522 return (0);
1523
1524 if (http->used)
1525 return (1);
1526
1527 /*
1528 * If not, check the SSL/TLS buffers and do a select() on the connection...
1529 */
1530
1531 return (http_wait(http, msec));
1532 }
1533
1534
1535 /*
1536 * 'httpWrite()' - Write data to a HTTP connection.
1537 */
1538
1539 int /* O - Number of bytes written */
1540 httpWrite(http_t *http, /* I - HTTP data */
1541 const char *buffer, /* I - Buffer for data */
1542 int length) /* I - Number of bytes to write */
1543 {
1544 int bytes; /* Bytes written */
1545
1546
1547 DEBUG_printf(("httpWrite(http=%p, buffer=%p, length=%d)\n", http,
1548 buffer, length));
1549
1550 /*
1551 * Range check input...
1552 */
1553
1554 if (http == NULL || buffer == NULL)
1555 return (-1);
1556
1557 /*
1558 * Mark activity on the connection...
1559 */
1560
1561 http->activity = time(NULL);
1562
1563 /*
1564 * Buffer small writes for better performance...
1565 */
1566
1567 if (length > 0)
1568 {
1569 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
1570 {
1571 DEBUG_printf((" flushing buffer (wused=%d, length=%d)\n",
1572 http->wused, length));
1573
1574 httpFlushWrite(http);
1575 }
1576
1577 if ((length + http->wused) <= sizeof(http->wbuffer))
1578 {
1579 /*
1580 * Write to buffer...
1581 */
1582
1583 DEBUG_printf((" copying %d bytes to wbuffer...\n", length));
1584
1585 memcpy(http->wbuffer + http->wused, buffer, length);
1586 http->wused += length;
1587 bytes = length;
1588 }
1589 else
1590 {
1591 /*
1592 * Otherwise write the data directly...
1593 */
1594
1595 DEBUG_printf((" writing %d bytes to socket...\n", length));
1596
1597 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1598 bytes = http_write_chunk(http, buffer, length);
1599 else
1600 bytes = http_write(http, buffer, length);
1601
1602 DEBUG_printf((" wrote %d bytes...\n", bytes));
1603 }
1604
1605 if (http->data_encoding == HTTP_ENCODE_LENGTH)
1606 http->data_remaining -= bytes;
1607 }
1608
1609 /*
1610 * Handle end-of-request processing...
1611 */
1612
1613 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
1614 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
1615 {
1616 /*
1617 * Finished with the transfer; unless we are sending POST or PUT
1618 * data, go idle...
1619 */
1620
1621 DEBUG_puts("httpWrite: changing states...");
1622
1623 if (http->wused)
1624 httpFlushWrite(http);
1625
1626 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1627 {
1628 /*
1629 * Send a 0-length chunk at the end of the request...
1630 */
1631
1632 http_write(http, "0\r\n\r\n", 5);
1633
1634 /*
1635 * Reset the data state...
1636 */
1637
1638 http->data_encoding = HTTP_ENCODE_LENGTH;
1639 http->data_remaining = 0;
1640 }
1641
1642 if (http->state == HTTP_POST_RECV)
1643 http->state ++;
1644 else if (http->state == HTTP_PUT_RECV)
1645 http->state = HTTP_STATUS;
1646 else
1647 http->state = HTTP_WAITING;
1648 }
1649
1650 return (bytes);
1651 }
1652
1653
1654 /*
1655 * 'http_field()' - Return the field index for a field name.
1656 */
1657
1658 static http_field_t /* O - Field index */
1659 http_field(const char *name) /* I - String name */
1660 {
1661 int i; /* Looping var */
1662
1663
1664 for (i = 0; i < HTTP_FIELD_MAX; i ++)
1665 if (strcasecmp(name, http_fields[i]) == 0)
1666 return ((http_field_t)i);
1667
1668 return (HTTP_FIELD_UNKNOWN);
1669 }
1670
1671
1672 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
1673 /*
1674 * 'http_read_cdsa()' - Read function for CDSA decryption code.
1675 */
1676
1677 static OSStatus /* O - -1 on error, 0 on success */
1678 http_read_cdsa(
1679 SSLConnectionRef connection, /* I - SSL/TLS connection */
1680 void *data, /* I - Data buffer */
1681 size_t *dataLength) /* IO - Number of bytes */
1682 {
1683 ssize_t bytes; /* Number of bytes read */
1684
1685
1686 bytes = recv((int)connection, data, *dataLength, 0);
1687 if (bytes >= 0)
1688 {
1689 *dataLength = bytes;
1690 return (0);
1691 }
1692 else
1693 return (-1);
1694 }
1695 #endif /* HAVE_SSL && HAVE_CDSASSL */
1696
1697
1698 #ifdef HAVE_SSL
1699 /*
1700 * 'http_read_ssl()' - Read from a SSL/TLS connection.
1701 */
1702
1703 static int /* O - Bytes read */
1704 http_read_ssl(http_t *http, /* I - HTTP data */
1705 char *buf, /* I - Buffer to store data */
1706 int len) /* I - Length of buffer */
1707 {
1708 # if defined(HAVE_LIBSSL)
1709 return (SSL_read((SSL *)(http->tls), buf, len));
1710
1711 # elif defined(HAVE_GNUTLS)
1712 return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));
1713
1714 # elif defined(HAVE_CDSASSL)
1715 OSStatus error; /* Error info */
1716 size_t processed; /* Number of bytes processed */
1717
1718
1719 error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);
1720
1721 if (error == 0)
1722 return (processed);
1723 else
1724 {
1725 http->error = error;
1726
1727 return (-1);
1728 }
1729 # endif /* HAVE_LIBSSL */
1730 }
1731 #endif /* HAVE_SSL */
1732
1733
1734 /*
1735 * 'http_send()' - Send a request with all fields and the trailing blank line.
1736 */
1737
1738 static int /* O - 0 on success, non-zero on error */
1739 http_send(http_t *http, /* I - HTTP data */
1740 http_state_t request, /* I - Request code */
1741 const char *uri) /* I - URI */
1742 {
1743 int i; /* Looping var */
1744 char *ptr, /* Pointer in buffer */
1745 buf[1024]; /* Encoded URI buffer */
1746 static const char * const codes[] =
1747 { /* Request code strings */
1748 NULL,
1749 "OPTIONS",
1750 "GET",
1751 NULL,
1752 "HEAD",
1753 "POST",
1754 NULL,
1755 NULL,
1756 "PUT",
1757 NULL,
1758 "DELETE",
1759 "TRACE",
1760 "CLOSE"
1761 };
1762 static const char hex[] = "0123456789ABCDEF";
1763 /* Hex digits */
1764
1765
1766 DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
1767 http, codes[request], uri));
1768
1769 if (http == NULL || uri == NULL)
1770 return (-1);
1771
1772 /*
1773 * Encode the URI as needed...
1774 */
1775
1776 for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
1777 if (*uri <= ' ' || *uri >= 127)
1778 {
1779 if (ptr < (buf + sizeof(buf) - 1))
1780 *ptr ++ = '%';
1781 if (ptr < (buf + sizeof(buf) - 1))
1782 *ptr ++ = hex[(*uri >> 4) & 15];
1783 if (ptr < (buf + sizeof(buf) - 1))
1784 *ptr ++ = hex[*uri & 15];
1785 }
1786 else
1787 *ptr ++ = *uri;
1788
1789 *ptr = '\0';
1790
1791 /*
1792 * See if we had an error the last time around; if so, reconnect...
1793 */
1794
1795 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
1796 httpReconnect(http);
1797
1798 /*
1799 * Send the request header...
1800 */
1801
1802 http->state = request;
1803 if (request == HTTP_POST || request == HTTP_PUT)
1804 http->state ++;
1805
1806 http->status = HTTP_CONTINUE;
1807
1808 #ifdef HAVE_SSL
1809 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
1810 {
1811 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
1812 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
1813 }
1814 #endif /* HAVE_SSL */
1815
1816 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
1817 {
1818 http->status = HTTP_ERROR;
1819 return (-1);
1820 }
1821
1822 for (i = 0; i < HTTP_FIELD_MAX; i ++)
1823 if (http->fields[i][0] != '\0')
1824 {
1825 DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));
1826
1827 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)
1828 {
1829 http->status = HTTP_ERROR;
1830 return (-1);
1831 }
1832 }
1833
1834 if (httpPrintf(http, "\r\n") < 1)
1835 {
1836 http->status = HTTP_ERROR;
1837 return (-1);
1838 }
1839
1840 httpGetLength2(http);
1841 httpClearFields(http);
1842
1843 return (0);
1844 }
1845
1846
1847 #ifdef HAVE_SSL
1848 /*
1849 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
1850 */
1851
1852 static int /* O - Status of connection */
1853 http_setup_ssl(http_t *http) /* I - HTTP data */
1854 {
1855 # ifdef HAVE_LIBSSL
1856 SSL_CTX *context; /* Context for encryption */
1857 SSL *conn; /* Connection for encryption */
1858 # elif defined(HAVE_GNUTLS)
1859 http_tls_t *conn; /* TLS session object */
1860 gnutls_certificate_client_credentials *credentials;
1861 /* TLS credentials */
1862 # elif defined(HAVE_CDSASSL)
1863 SSLContextRef conn; /* Context for encryption */
1864 OSStatus error; /* Error info */
1865 # endif /* HAVE_LIBSSL */
1866
1867
1868 DEBUG_printf(("http_setup_ssl(http=%p)\n", http));
1869
1870 # ifdef HAVE_LIBSSL
1871 context = SSL_CTX_new(SSLv23_client_method());
1872
1873 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
1874
1875 conn = SSL_new(context);
1876
1877 SSL_set_fd(conn, http->fd);
1878 if (SSL_connect(conn) != 1)
1879 {
1880 # ifdef DEBUG
1881 unsigned long error; /* Error code */
1882
1883 while ((error = ERR_get_error()) != 0)
1884 printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));
1885 # endif /* DEBUG */
1886
1887 SSL_CTX_free(context);
1888 SSL_free(conn);
1889
1890 # ifdef WIN32
1891 http->error = WSAGetLastError();
1892 # else
1893 http->error = errno;
1894 # endif /* WIN32 */
1895 http->status = HTTP_ERROR;
1896
1897 return (HTTP_ERROR);
1898 }
1899
1900 # elif defined(HAVE_GNUTLS)
1901 conn = (http_tls_t *)malloc(sizeof(http_tls_t));
1902
1903 if (conn == NULL)
1904 {
1905 http->error = errno;
1906 http->status = HTTP_ERROR;
1907
1908 return (-1);
1909 }
1910
1911 credentials = (gnutls_certificate_client_credentials *)
1912 malloc(sizeof(gnutls_certificate_client_credentials));
1913 if (credentials == NULL)
1914 {
1915 free(conn);
1916
1917 http->error = errno;
1918 http->status = HTTP_ERROR;
1919
1920 return (-1);
1921 }
1922
1923 gnutls_certificate_allocate_credentials(credentials);
1924
1925 gnutls_init(&(conn->session), GNUTLS_CLIENT);
1926 gnutls_set_default_priority(conn->session);
1927 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
1928 gnutls_transport_set_ptr(conn->session, http->fd);
1929
1930 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
1931 {
1932 http->error = errno;
1933 http->status = HTTP_ERROR;
1934
1935 return (-1);
1936 }
1937
1938 conn->credentials = credentials;
1939
1940 # elif defined(HAVE_CDSASSL)
1941 error = SSLNewContext(false, &conn);
1942
1943 if (!error)
1944 error = SSLSetIOFuncs(conn, http_read_cdsa, http_write_cdsa);
1945
1946 if (!error)
1947 error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);
1948
1949 if (!error)
1950 error = SSLSetAllowsExpiredCerts(conn, true);
1951
1952 if (!error)
1953 error = SSLSetAllowsAnyRoot(conn, true);
1954
1955 if (!error)
1956 error = SSLHandshake(conn);
1957
1958 if (error != 0)
1959 {
1960 http->error = error;
1961 http->status = HTTP_ERROR;
1962
1963 SSLDisposeContext(conn);
1964
1965 close(http->fd);
1966
1967 return (-1);
1968 }
1969 # endif /* HAVE_CDSASSL */
1970
1971 http->tls = conn;
1972 return (0);
1973 }
1974 #endif /* HAVE_SSL */
1975
1976
1977 #ifdef HAVE_SSL
1978 /*
1979 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
1980 */
1981
1982 static void
1983 http_shutdown_ssl(http_t *http) /* I - HTTP data */
1984 {
1985 # ifdef HAVE_LIBSSL
1986 SSL_CTX *context; /* Context for encryption */
1987 SSL *conn; /* Connection for encryption */
1988
1989
1990 conn = (SSL *)(http->tls);
1991 context = SSL_get_SSL_CTX(conn);
1992
1993 SSL_shutdown(conn);
1994 SSL_CTX_free(context);
1995 SSL_free(conn);
1996
1997 # elif defined(HAVE_GNUTLS)
1998 http_tls_t *conn; /* Encryption session */
1999 gnutls_certificate_client_credentials *credentials;
2000 /* TLS credentials */
2001
2002
2003 conn = (http_tls_t *)(http->tls);
2004 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
2005
2006 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
2007 gnutls_deinit(conn->session);
2008 gnutls_certificate_free_credentials(*credentials);
2009 free(credentials);
2010 free(conn);
2011
2012 # elif defined(HAVE_CDSASSL)
2013 SSLClose((SSLContextRef)http->tls);
2014 SSLDisposeContext((SSLContextRef)http->tls);
2015 # endif /* HAVE_LIBSSL */
2016
2017 http->tls = NULL;
2018 }
2019 #endif /* HAVE_SSL */
2020
2021
2022 #ifdef HAVE_SSL
2023 /*
2024 * 'http_upgrade()' - Force upgrade to TLS encryption.
2025 */
2026
2027 static int /* O - Status of connection */
2028 http_upgrade(http_t *http) /* I - HTTP data */
2029 {
2030 int ret; /* Return value */
2031 http_t myhttp; /* Local copy of HTTP data */
2032
2033
2034 DEBUG_printf(("http_upgrade(%p)\n", http));
2035
2036 /*
2037 * Copy the HTTP data to a local variable so we can do the OPTIONS
2038 * request without interfering with the existing request data...
2039 */
2040
2041 memcpy(&myhttp, http, sizeof(myhttp));
2042
2043 /*
2044 * Send an OPTIONS request to the server, requiring SSL or TLS
2045 * encryption on the link...
2046 */
2047
2048 httpClearFields(&myhttp);
2049 httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");
2050 httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
2051
2052 if ((ret = httpOptions(&myhttp, "*")) == 0)
2053 {
2054 /*
2055 * Wait for the secure connection...
2056 */
2057
2058 while (httpUpdate(&myhttp) == HTTP_CONTINUE);
2059 }
2060
2061 httpFlush(&myhttp);
2062
2063 /*
2064 * Copy the HTTP data back over, if any...
2065 */
2066
2067 http->fd = myhttp.fd;
2068 http->error = myhttp.error;
2069 http->activity = myhttp.activity;
2070 http->status = myhttp.status;
2071 http->version = myhttp.version;
2072 http->keep_alive = myhttp.keep_alive;
2073 http->used = myhttp.used;
2074
2075 if (http->used)
2076 memcpy(http->buffer, myhttp.buffer, http->used);
2077
2078 http->auth_type = myhttp.auth_type;
2079 http->nonce_count = myhttp.nonce_count;
2080
2081 memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));
2082
2083 http->tls = myhttp.tls;
2084 http->encryption = myhttp.encryption;
2085
2086 /*
2087 * See if we actually went secure...
2088 */
2089
2090 if (!http->tls)
2091 {
2092 /*
2093 * Server does not support HTTP upgrade...
2094 */
2095
2096 DEBUG_puts("Server does not support HTTP upgrade!");
2097
2098 # ifdef WIN32
2099 closesocket(http->fd);
2100 # else
2101 close(http->fd);
2102 # endif
2103
2104 http->fd = -1;
2105
2106 return (-1);
2107 }
2108 else
2109 return (ret);
2110 }
2111 #endif /* HAVE_SSL */
2112
2113
2114 /*
2115 * 'http_wait()' - Wait for data available on a connection.
2116 */
2117
2118 static int /* O - 1 if data is available, 0 otherwise */
2119 http_wait(http_t *http, /* I - HTTP data */
2120 int msec) /* I - Milliseconds to wait */
2121 {
2122 #ifndef WIN32
2123 struct rlimit limit; /* Runtime limit */
2124 #endif /* !WIN32 */
2125 struct timeval timeout; /* Timeout */
2126 int nfds; /* Result from select() */
2127 int set_size; /* Size of select set */
2128
2129
2130 DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
2131
2132 /*
2133 * Check the SSL/TLS buffers for data first...
2134 */
2135
2136 #ifdef HAVE_SSL
2137 if (http->tls)
2138 {
2139 # ifdef HAVE_LIBSSL
2140 if (SSL_pending((SSL *)(http->tls)))
2141 return (1);
2142 # elif defined(HAVE_GNUTLS)
2143 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2144 return (1);
2145 # elif defined(HAVE_CDSASSL)
2146 size_t bytes; /* Bytes that are available */
2147
2148 if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
2149 return (1);
2150 # endif /* HAVE_LIBSSL */
2151 }
2152 #endif /* HAVE_SSL */
2153
2154 /*
2155 * Then try doing a select() to poll the socket...
2156 */
2157
2158 if (!http->input_set)
2159 {
2160 #ifdef WIN32
2161 /*
2162 * Windows has a fixed-size select() structure, different (surprise,
2163 * surprise!) from all UNIX implementations. Just allocate this
2164 * fixed structure...
2165 */
2166
2167 http->input_set = calloc(1, sizeof(fd_set));
2168 #else
2169 /*
2170 * Allocate the select() input set based upon the max number of file
2171 * descriptors available for this process...
2172 */
2173
2174 getrlimit(RLIMIT_NOFILE, &limit);
2175
2176 set_size = (limit.rlim_cur + 31) / 8 + 4;
2177 if (set_size < sizeof(fd_set))
2178 set_size = sizeof(fd_set);
2179
2180 http->input_set = calloc(1, set_size);
2181 #endif /* WIN32 */
2182
2183 if (!http->input_set)
2184 return (0);
2185 }
2186
2187 do
2188 {
2189 FD_SET(http->fd, http->input_set);
2190
2191 if (msec >= 0)
2192 {
2193 timeout.tv_sec = msec / 1000;
2194 timeout.tv_usec = (msec % 1000) * 1000;
2195
2196 nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
2197 }
2198 else
2199 nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
2200 }
2201 #ifdef WIN32
2202 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2203 #else
2204 while (nfds < 0 && errno == EINTR);
2205 #endif /* WIN32 */
2206
2207 FD_CLR(http->fd, http->input_set);
2208
2209 return (nfds > 0);
2210 }
2211
2212
2213 /*
2214 * 'http_write()' - Write a buffer to a HTTP connection.
2215 */
2216
2217 static int /* O - Number of bytes written */
2218 http_write(http_t *http, /* I - HTTP data */
2219 const char *buffer, /* I - Buffer for data */
2220 int length) /* I - Number of bytes to write */
2221 {
2222 int tbytes, /* Total bytes sent */
2223 bytes; /* Bytes sent */
2224
2225
2226 tbytes = 0;
2227
2228 while (length > 0)
2229 {
2230 #ifdef HAVE_SSL
2231 if (http->tls)
2232 bytes = http_write_ssl(http, buffer, length);
2233 else
2234 #endif /* HAVE_SSL */
2235 bytes = send(http->fd, buffer, length, 0);
2236
2237 if (bytes < 0)
2238 {
2239 #ifdef WIN32
2240 if (WSAGetLastError() != http->error)
2241 {
2242 http->error = WSAGetLastError();
2243 continue;
2244 }
2245 #else
2246 if (errno == EINTR)
2247 continue;
2248 else if (errno != http->error && errno != ECONNRESET)
2249 {
2250 http->error = errno;
2251 continue;
2252 }
2253 #endif /* WIN32 */
2254
2255 DEBUG_puts("http_write: error writing data...\n");
2256
2257 return (-1);
2258 }
2259
2260 buffer += bytes;
2261 tbytes += bytes;
2262 length -= bytes;
2263 }
2264
2265 #ifdef DEBUG
2266 {
2267 int i, j, ch;
2268 printf("http_write: wrote %d bytes: \n", tbytes);
2269 for (i = 0, buffer -= tbytes; i < tbytes; i += 16)
2270 {
2271 printf(" ");
2272
2273 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2274 printf(" %02X", buffer[i + j] & 255);
2275
2276 while (j < 16)
2277 {
2278 printf(" ");
2279 j ++;
2280 }
2281
2282 printf(" ");
2283 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2284 {
2285 ch = buffer[i + j] & 255;
2286
2287 if (ch < ' ' || ch == 127)
2288 ch = '.';
2289
2290 putchar(ch);
2291 }
2292 putchar('\n');
2293 }
2294 }
2295 #endif /* DEBUG */
2296
2297 return (tbytes);
2298 }
2299
2300
2301 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2302 /*
2303 * 'http_write_cdsa()' - Write function for CDSA encryption code.
2304 */
2305
2306 static OSStatus /* O - -1 on error, 0 on success */
2307 http_write_cdsa(
2308 SSLConnectionRef connection, /* I - SSL/TLS connection */
2309 const void *data, /* I - Data buffer */
2310 size_t *dataLength) /* IO - Number of bytes */
2311 {
2312 ssize_t bytes; /* Number of write written */
2313
2314
2315 bytes = write((int)connection, data, *dataLength);
2316 if (bytes >= 0)
2317 {
2318 *dataLength = bytes;
2319 return (0);
2320 }
2321 else
2322 return (-1);
2323 }
2324 #endif /* HAVE_SSL && HAVE_CDSASSL */
2325
2326
2327 /*
2328 * 'http_write_chunk()' - Write a chunked buffer.
2329 */
2330
2331 static int /* O - Number bytes written */
2332 http_write_chunk(http_t *http, /* I - HTTP data */
2333 const char *buffer, /* I - Buffer to write */
2334 int length) /* I - Length of buffer */
2335 {
2336 char header[255]; /* Chunk header */
2337 int bytes; /* Bytes written */
2338
2339 DEBUG_printf(("http_write_chunk(http=%p, buffer=%p, length=%d)\n",
2340 http, buffer, length));
2341
2342 /*
2343 * Write the chunk header, data, and trailer.
2344 */
2345
2346 sprintf(header, "%x\r\n", length);
2347 if (http_write(http, header, strlen(header)) < 0)
2348 {
2349 DEBUG_puts(" http_write of length failed!");
2350 return (-1);
2351 }
2352
2353 if ((bytes = http_write(http, buffer, length)) < 0)
2354 {
2355 DEBUG_puts(" http_write of buffer failed!");
2356 return (-1);
2357 }
2358
2359 if (http_write(http, "\r\n", 2) < 0)
2360 {
2361 DEBUG_puts(" http_write of CR LF failed!");
2362 return (-1);
2363 }
2364
2365 return (bytes);
2366 }
2367
2368
2369 #ifdef HAVE_SSL
2370 /*
2371 * 'http_write_ssl()' - Write to a SSL/TLS connection.
2372 */
2373
2374 static int /* O - Bytes written */
2375 http_write_ssl(http_t *http, /* I - HTTP data */
2376 const char *buf, /* I - Buffer holding data */
2377 int len) /* I - Length of buffer */
2378 {
2379 # if defined(HAVE_LIBSSL)
2380 return (SSL_write((SSL *)(http->tls), buf, len));
2381
2382 # elif defined(HAVE_GNUTLS)
2383 return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
2384 # elif defined(HAVE_CDSASSL)
2385 OSStatus error; /* Error info */
2386 size_t processed; /* Number of bytes processed */
2387
2388
2389 error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
2390
2391 if (error == 0)
2392 return (processed);
2393 else
2394 {
2395 http->error = error;
2396 return (-1);
2397 }
2398 # endif /* HAVE_LIBSSL */
2399 }
2400 #endif /* HAVE_SSL */
2401
2402
2403 /*
2404 * End of "$Id$".
2405 */