]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
a42ea4569350274caa38f2808c090ad187d85cb1
[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 else
1629 bytes = 0;
1630
1631 /*
1632 * Handle end-of-request processing...
1633 */
1634
1635 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
1636 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
1637 {
1638 /*
1639 * Finished with the transfer; unless we are sending POST or PUT
1640 * data, go idle...
1641 */
1642
1643 DEBUG_puts("httpWrite: changing states...");
1644
1645 if (http->wused)
1646 httpFlushWrite(http);
1647
1648 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1649 {
1650 /*
1651 * Send a 0-length chunk at the end of the request...
1652 */
1653
1654 http_write(http, "0\r\n\r\n", 5);
1655
1656 /*
1657 * Reset the data state...
1658 */
1659
1660 http->data_encoding = HTTP_ENCODE_LENGTH;
1661 http->data_remaining = 0;
1662 }
1663
1664 if (http->state == HTTP_POST_RECV)
1665 http->state ++;
1666 else if (http->state == HTTP_PUT_RECV)
1667 http->state = HTTP_STATUS;
1668 else
1669 http->state = HTTP_WAITING;
1670 }
1671
1672 return (bytes);
1673 }
1674
1675
1676 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
1677 /*
1678 * '_httpWriteCDSA()' - Write function for CDSA encryption code.
1679 */
1680
1681 OSStatus /* O - -1 on error, 0 on success */
1682 _httpWriteCDSA(
1683 SSLConnectionRef connection, /* I - SSL/TLS connection */
1684 const void *data, /* I - Data buffer */
1685 size_t *dataLength) /* IO - Number of bytes */
1686 {
1687 ssize_t bytes; /* Number of write written */
1688
1689
1690 bytes = write((int)connection, data, *dataLength);
1691 if (bytes >= 0)
1692 {
1693 *dataLength = bytes;
1694 return (0);
1695 }
1696 else
1697 return (-1);
1698 }
1699 #endif /* HAVE_SSL && HAVE_CDSASSL */
1700
1701
1702 /*
1703 * 'http_field()' - Return the field index for a field name.
1704 */
1705
1706 static http_field_t /* O - Field index */
1707 http_field(const char *name) /* I - String name */
1708 {
1709 int i; /* Looping var */
1710
1711
1712 for (i = 0; i < HTTP_FIELD_MAX; i ++)
1713 if (strcasecmp(name, http_fields[i]) == 0)
1714 return ((http_field_t)i);
1715
1716 return (HTTP_FIELD_UNKNOWN);
1717 }
1718
1719
1720 #ifdef HAVE_SSL
1721 /*
1722 * 'http_read_ssl()' - Read from a SSL/TLS connection.
1723 */
1724
1725 static int /* O - Bytes read */
1726 http_read_ssl(http_t *http, /* I - HTTP data */
1727 char *buf, /* I - Buffer to store data */
1728 int len) /* I - Length of buffer */
1729 {
1730 # if defined(HAVE_LIBSSL)
1731 return (SSL_read((SSL *)(http->tls), buf, len));
1732
1733 # elif defined(HAVE_GNUTLS)
1734 return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));
1735
1736 # elif defined(HAVE_CDSASSL)
1737 OSStatus error; /* Error info */
1738 size_t processed; /* Number of bytes processed */
1739
1740
1741 error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);
1742
1743 if (error == 0)
1744 return (processed);
1745 else
1746 {
1747 http->error = error;
1748
1749 return (-1);
1750 }
1751 # endif /* HAVE_LIBSSL */
1752 }
1753 #endif /* HAVE_SSL */
1754
1755
1756 /*
1757 * 'http_send()' - Send a request with all fields and the trailing blank line.
1758 */
1759
1760 static int /* O - 0 on success, non-zero on error */
1761 http_send(http_t *http, /* I - HTTP data */
1762 http_state_t request, /* I - Request code */
1763 const char *uri) /* I - URI */
1764 {
1765 int i; /* Looping var */
1766 char *ptr, /* Pointer in buffer */
1767 buf[1024]; /* Encoded URI buffer */
1768 static const char * const codes[] =
1769 { /* Request code strings */
1770 NULL,
1771 "OPTIONS",
1772 "GET",
1773 NULL,
1774 "HEAD",
1775 "POST",
1776 NULL,
1777 NULL,
1778 "PUT",
1779 NULL,
1780 "DELETE",
1781 "TRACE",
1782 "CLOSE"
1783 };
1784 static const char hex[] = "0123456789ABCDEF";
1785 /* Hex digits */
1786
1787
1788 DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
1789 http, codes[request], uri));
1790
1791 if (http == NULL || uri == NULL)
1792 return (-1);
1793
1794 /*
1795 * Encode the URI as needed...
1796 */
1797
1798 for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
1799 if (*uri <= ' ' || *uri >= 127)
1800 {
1801 if (ptr < (buf + sizeof(buf) - 1))
1802 *ptr ++ = '%';
1803 if (ptr < (buf + sizeof(buf) - 1))
1804 *ptr ++ = hex[(*uri >> 4) & 15];
1805 if (ptr < (buf + sizeof(buf) - 1))
1806 *ptr ++ = hex[*uri & 15];
1807 }
1808 else
1809 *ptr ++ = *uri;
1810
1811 *ptr = '\0';
1812
1813 /*
1814 * See if we had an error the last time around; if so, reconnect...
1815 */
1816
1817 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
1818 httpReconnect(http);
1819
1820 /*
1821 * Send the request header...
1822 */
1823
1824 http->state = request;
1825 if (request == HTTP_POST || request == HTTP_PUT)
1826 http->state ++;
1827
1828 http->status = HTTP_CONTINUE;
1829
1830 #ifdef HAVE_SSL
1831 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
1832 {
1833 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
1834 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
1835 }
1836 #endif /* HAVE_SSL */
1837
1838 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
1839 {
1840 http->status = HTTP_ERROR;
1841 return (-1);
1842 }
1843
1844 for (i = 0; i < HTTP_FIELD_MAX; i ++)
1845 if (http->fields[i][0] != '\0')
1846 {
1847 DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));
1848
1849 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)
1850 {
1851 http->status = HTTP_ERROR;
1852 return (-1);
1853 }
1854 }
1855
1856 if (httpPrintf(http, "\r\n") < 1)
1857 {
1858 http->status = HTTP_ERROR;
1859 return (-1);
1860 }
1861
1862 httpGetLength2(http);
1863 httpClearFields(http);
1864
1865 return (0);
1866 }
1867
1868
1869 #ifdef HAVE_SSL
1870 /*
1871 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
1872 */
1873
1874 static int /* O - Status of connection */
1875 http_setup_ssl(http_t *http) /* I - HTTP data */
1876 {
1877 # ifdef HAVE_LIBSSL
1878 SSL_CTX *context; /* Context for encryption */
1879 SSL *conn; /* Connection for encryption */
1880 # elif defined(HAVE_GNUTLS)
1881 http_tls_t *conn; /* TLS session object */
1882 gnutls_certificate_client_credentials *credentials;
1883 /* TLS credentials */
1884 # elif defined(HAVE_CDSASSL)
1885 SSLContextRef conn; /* Context for encryption */
1886 OSStatus error; /* Error info */
1887 # endif /* HAVE_LIBSSL */
1888
1889
1890 DEBUG_printf(("http_setup_ssl(http=%p)\n", http));
1891
1892 # ifdef HAVE_LIBSSL
1893 context = SSL_CTX_new(SSLv23_client_method());
1894
1895 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
1896
1897 conn = SSL_new(context);
1898
1899 SSL_set_fd(conn, http->fd);
1900 if (SSL_connect(conn) != 1)
1901 {
1902 # ifdef DEBUG
1903 unsigned long error; /* Error code */
1904
1905 while ((error = ERR_get_error()) != 0)
1906 printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));
1907 # endif /* DEBUG */
1908
1909 SSL_CTX_free(context);
1910 SSL_free(conn);
1911
1912 # ifdef WIN32
1913 http->error = WSAGetLastError();
1914 # else
1915 http->error = errno;
1916 # endif /* WIN32 */
1917 http->status = HTTP_ERROR;
1918
1919 return (HTTP_ERROR);
1920 }
1921
1922 # elif defined(HAVE_GNUTLS)
1923 conn = (http_tls_t *)malloc(sizeof(http_tls_t));
1924
1925 if (conn == NULL)
1926 {
1927 http->error = errno;
1928 http->status = HTTP_ERROR;
1929
1930 return (-1);
1931 }
1932
1933 credentials = (gnutls_certificate_client_credentials *)
1934 malloc(sizeof(gnutls_certificate_client_credentials));
1935 if (credentials == NULL)
1936 {
1937 free(conn);
1938
1939 http->error = errno;
1940 http->status = HTTP_ERROR;
1941
1942 return (-1);
1943 }
1944
1945 gnutls_certificate_allocate_credentials(credentials);
1946
1947 gnutls_init(&(conn->session), GNUTLS_CLIENT);
1948 gnutls_set_default_priority(conn->session);
1949 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
1950 gnutls_transport_set_ptr(conn->session, http->fd);
1951
1952 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
1953 {
1954 http->error = errno;
1955 http->status = HTTP_ERROR;
1956
1957 return (-1);
1958 }
1959
1960 conn->credentials = credentials;
1961
1962 # elif defined(HAVE_CDSASSL)
1963 error = SSLNewContext(false, &conn);
1964
1965 if (!error)
1966 error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
1967
1968 if (!error)
1969 error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);
1970
1971 if (!error)
1972 error = SSLSetAllowsExpiredCerts(conn, true);
1973
1974 if (!error)
1975 error = SSLSetAllowsAnyRoot(conn, true);
1976
1977 if (!error)
1978 error = SSLHandshake(conn);
1979
1980 if (error != 0)
1981 {
1982 http->error = error;
1983 http->status = HTTP_ERROR;
1984
1985 SSLDisposeContext(conn);
1986
1987 close(http->fd);
1988
1989 return (-1);
1990 }
1991 # endif /* HAVE_CDSASSL */
1992
1993 http->tls = conn;
1994 return (0);
1995 }
1996 #endif /* HAVE_SSL */
1997
1998
1999 #ifdef HAVE_SSL
2000 /*
2001 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
2002 */
2003
2004 static void
2005 http_shutdown_ssl(http_t *http) /* I - HTTP data */
2006 {
2007 # ifdef HAVE_LIBSSL
2008 SSL_CTX *context; /* Context for encryption */
2009 SSL *conn; /* Connection for encryption */
2010
2011
2012 conn = (SSL *)(http->tls);
2013 context = SSL_get_SSL_CTX(conn);
2014
2015 SSL_shutdown(conn);
2016 SSL_CTX_free(context);
2017 SSL_free(conn);
2018
2019 # elif defined(HAVE_GNUTLS)
2020 http_tls_t *conn; /* Encryption session */
2021 gnutls_certificate_client_credentials *credentials;
2022 /* TLS credentials */
2023
2024
2025 conn = (http_tls_t *)(http->tls);
2026 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
2027
2028 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
2029 gnutls_deinit(conn->session);
2030 gnutls_certificate_free_credentials(*credentials);
2031 free(credentials);
2032 free(conn);
2033
2034 # elif defined(HAVE_CDSASSL)
2035 SSLClose((SSLContextRef)http->tls);
2036 SSLDisposeContext((SSLContextRef)http->tls);
2037 # endif /* HAVE_LIBSSL */
2038
2039 http->tls = NULL;
2040 }
2041 #endif /* HAVE_SSL */
2042
2043
2044 #ifdef HAVE_SSL
2045 /*
2046 * 'http_upgrade()' - Force upgrade to TLS encryption.
2047 */
2048
2049 static int /* O - Status of connection */
2050 http_upgrade(http_t *http) /* I - HTTP data */
2051 {
2052 int ret; /* Return value */
2053 http_t myhttp; /* Local copy of HTTP data */
2054
2055
2056 DEBUG_printf(("http_upgrade(%p)\n", http));
2057
2058 /*
2059 * Copy the HTTP data to a local variable so we can do the OPTIONS
2060 * request without interfering with the existing request data...
2061 */
2062
2063 memcpy(&myhttp, http, sizeof(myhttp));
2064
2065 /*
2066 * Send an OPTIONS request to the server, requiring SSL or TLS
2067 * encryption on the link...
2068 */
2069
2070 httpClearFields(&myhttp);
2071 httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");
2072 httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
2073
2074 if ((ret = httpOptions(&myhttp, "*")) == 0)
2075 {
2076 /*
2077 * Wait for the secure connection...
2078 */
2079
2080 while (httpUpdate(&myhttp) == HTTP_CONTINUE);
2081 }
2082
2083 httpFlush(&myhttp);
2084
2085 /*
2086 * Copy the HTTP data back over, if any...
2087 */
2088
2089 http->fd = myhttp.fd;
2090 http->error = myhttp.error;
2091 http->activity = myhttp.activity;
2092 http->status = myhttp.status;
2093 http->version = myhttp.version;
2094 http->keep_alive = myhttp.keep_alive;
2095 http->used = myhttp.used;
2096
2097 if (http->used)
2098 memcpy(http->buffer, myhttp.buffer, http->used);
2099
2100 http->auth_type = myhttp.auth_type;
2101 http->nonce_count = myhttp.nonce_count;
2102
2103 memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));
2104
2105 http->tls = myhttp.tls;
2106 http->encryption = myhttp.encryption;
2107
2108 /*
2109 * See if we actually went secure...
2110 */
2111
2112 if (!http->tls)
2113 {
2114 /*
2115 * Server does not support HTTP upgrade...
2116 */
2117
2118 DEBUG_puts("Server does not support HTTP upgrade!");
2119
2120 # ifdef WIN32
2121 closesocket(http->fd);
2122 # else
2123 close(http->fd);
2124 # endif
2125
2126 http->fd = -1;
2127
2128 return (-1);
2129 }
2130 else
2131 return (ret);
2132 }
2133 #endif /* HAVE_SSL */
2134
2135
2136 /*
2137 * 'http_wait()' - Wait for data available on a connection.
2138 */
2139
2140 static int /* O - 1 if data is available, 0 otherwise */
2141 http_wait(http_t *http, /* I - HTTP data */
2142 int msec) /* I - Milliseconds to wait */
2143 {
2144 #ifndef WIN32
2145 struct rlimit limit; /* Runtime limit */
2146 #endif /* !WIN32 */
2147 struct timeval timeout; /* Timeout */
2148 int nfds; /* Result from select() */
2149 int set_size; /* Size of select set */
2150
2151
2152 DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
2153
2154 /*
2155 * Check the SSL/TLS buffers for data first...
2156 */
2157
2158 #ifdef HAVE_SSL
2159 if (http->tls)
2160 {
2161 # ifdef HAVE_LIBSSL
2162 if (SSL_pending((SSL *)(http->tls)))
2163 return (1);
2164 # elif defined(HAVE_GNUTLS)
2165 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2166 return (1);
2167 # elif defined(HAVE_CDSASSL)
2168 size_t bytes; /* Bytes that are available */
2169
2170 if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
2171 return (1);
2172 # endif /* HAVE_LIBSSL */
2173 }
2174 #endif /* HAVE_SSL */
2175
2176 /*
2177 * Then try doing a select() to poll the socket...
2178 */
2179
2180 if (!http->input_set)
2181 {
2182 #ifdef WIN32
2183 /*
2184 * Windows has a fixed-size select() structure, different (surprise,
2185 * surprise!) from all UNIX implementations. Just allocate this
2186 * fixed structure...
2187 */
2188
2189 http->input_set = calloc(1, sizeof(fd_set));
2190 #else
2191 /*
2192 * Allocate the select() input set based upon the max number of file
2193 * descriptors available for this process...
2194 */
2195
2196 getrlimit(RLIMIT_NOFILE, &limit);
2197
2198 set_size = (limit.rlim_cur + 31) / 8 + 4;
2199 if (set_size < sizeof(fd_set))
2200 set_size = sizeof(fd_set);
2201
2202 http->input_set = calloc(1, set_size);
2203 #endif /* WIN32 */
2204
2205 if (!http->input_set)
2206 return (0);
2207 }
2208
2209 do
2210 {
2211 FD_SET(http->fd, http->input_set);
2212
2213 if (msec >= 0)
2214 {
2215 timeout.tv_sec = msec / 1000;
2216 timeout.tv_usec = (msec % 1000) * 1000;
2217
2218 nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
2219 }
2220 else
2221 nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
2222 }
2223 #ifdef WIN32
2224 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2225 #else
2226 while (nfds < 0 && errno == EINTR);
2227 #endif /* WIN32 */
2228
2229 FD_CLR(http->fd, http->input_set);
2230
2231 return (nfds > 0);
2232 }
2233
2234
2235 /*
2236 * 'http_write()' - Write a buffer to a HTTP connection.
2237 */
2238
2239 static int /* O - Number of bytes written */
2240 http_write(http_t *http, /* I - HTTP data */
2241 const char *buffer, /* I - Buffer for data */
2242 int length) /* I - Number of bytes to write */
2243 {
2244 int tbytes, /* Total bytes sent */
2245 bytes; /* Bytes sent */
2246
2247
2248 tbytes = 0;
2249
2250 while (length > 0)
2251 {
2252 #ifdef HAVE_SSL
2253 if (http->tls)
2254 bytes = http_write_ssl(http, buffer, length);
2255 else
2256 #endif /* HAVE_SSL */
2257 bytes = send(http->fd, buffer, length, 0);
2258
2259 if (bytes < 0)
2260 {
2261 #ifdef WIN32
2262 if (WSAGetLastError() != http->error)
2263 {
2264 http->error = WSAGetLastError();
2265 continue;
2266 }
2267 #else
2268 if (errno == EINTR)
2269 continue;
2270 else if (errno != http->error && errno != ECONNRESET)
2271 {
2272 http->error = errno;
2273 continue;
2274 }
2275 #endif /* WIN32 */
2276
2277 DEBUG_puts("http_write: error writing data...\n");
2278
2279 return (-1);
2280 }
2281
2282 buffer += bytes;
2283 tbytes += bytes;
2284 length -= bytes;
2285 }
2286
2287 #ifdef DEBUG
2288 {
2289 int i, j, ch;
2290 printf("http_write: wrote %d bytes: \n", tbytes);
2291 for (i = 0, buffer -= tbytes; i < tbytes; i += 16)
2292 {
2293 printf(" ");
2294
2295 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2296 printf(" %02X", buffer[i + j] & 255);
2297
2298 while (j < 16)
2299 {
2300 printf(" ");
2301 j ++;
2302 }
2303
2304 printf(" ");
2305 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2306 {
2307 ch = buffer[i + j] & 255;
2308
2309 if (ch < ' ' || ch == 127)
2310 ch = '.';
2311
2312 putchar(ch);
2313 }
2314 putchar('\n');
2315 }
2316 }
2317 #endif /* DEBUG */
2318
2319 return (tbytes);
2320 }
2321
2322
2323 /*
2324 * 'http_write_chunk()' - Write a chunked buffer.
2325 */
2326
2327 static int /* O - Number bytes written */
2328 http_write_chunk(http_t *http, /* I - HTTP data */
2329 const char *buffer, /* I - Buffer to write */
2330 int length) /* I - Length of buffer */
2331 {
2332 char header[255]; /* Chunk header */
2333 int bytes; /* Bytes written */
2334
2335 DEBUG_printf(("http_write_chunk(http=%p, buffer=%p, length=%d)\n",
2336 http, buffer, length));
2337
2338 /*
2339 * Write the chunk header, data, and trailer.
2340 */
2341
2342 sprintf(header, "%x\r\n", length);
2343 if (http_write(http, header, strlen(header)) < 0)
2344 {
2345 DEBUG_puts(" http_write of length failed!");
2346 return (-1);
2347 }
2348
2349 if ((bytes = http_write(http, buffer, length)) < 0)
2350 {
2351 DEBUG_puts(" http_write of buffer failed!");
2352 return (-1);
2353 }
2354
2355 if (http_write(http, "\r\n", 2) < 0)
2356 {
2357 DEBUG_puts(" http_write of CR LF failed!");
2358 return (-1);
2359 }
2360
2361 return (bytes);
2362 }
2363
2364
2365 #ifdef HAVE_SSL
2366 /*
2367 * 'http_write_ssl()' - Write to a SSL/TLS connection.
2368 */
2369
2370 static int /* O - Bytes written */
2371 http_write_ssl(http_t *http, /* I - HTTP data */
2372 const char *buf, /* I - Buffer holding data */
2373 int len) /* I - Length of buffer */
2374 {
2375 # if defined(HAVE_LIBSSL)
2376 return (SSL_write((SSL *)(http->tls), buf, len));
2377
2378 # elif defined(HAVE_GNUTLS)
2379 return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
2380 # elif defined(HAVE_CDSASSL)
2381 OSStatus error; /* Error info */
2382 size_t processed; /* Number of bytes processed */
2383
2384
2385 error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
2386
2387 if (error == 0)
2388 return (processed);
2389 else
2390 {
2391 http->error = error;
2392 return (-1);
2393 }
2394 # endif /* HAVE_LIBSSL */
2395 }
2396 #endif /* HAVE_SSL */
2397
2398
2399 /*
2400 * End of "$Id$".
2401 */