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