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