]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Make sure User-Agent field is set for all requests (STR #1366)
[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 size_t length) /* I - Length (0 for chunked) */
1341 {
1342 if (!http)
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 * Set the User-Agent field if it isn't already...
1817 */
1818
1819 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
1820 httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
1821
1822 /*
1823 * Encode the URI as needed...
1824 */
1825
1826 for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
1827 if (*uri <= ' ' || *uri >= 127)
1828 {
1829 if (ptr < (buf + sizeof(buf) - 1))
1830 *ptr ++ = '%';
1831 if (ptr < (buf + sizeof(buf) - 1))
1832 *ptr ++ = hex[(*uri >> 4) & 15];
1833 if (ptr < (buf + sizeof(buf) - 1))
1834 *ptr ++ = hex[*uri & 15];
1835 }
1836 else
1837 *ptr ++ = *uri;
1838
1839 *ptr = '\0';
1840
1841 /*
1842 * See if we had an error the last time around; if so, reconnect...
1843 */
1844
1845 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
1846 httpReconnect(http);
1847
1848 /*
1849 * Send the request header...
1850 */
1851
1852 http->state = request;
1853 if (request == HTTP_POST || request == HTTP_PUT)
1854 http->state ++;
1855
1856 http->status = HTTP_CONTINUE;
1857
1858 #ifdef HAVE_SSL
1859 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
1860 {
1861 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
1862 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
1863 }
1864 #endif /* HAVE_SSL */
1865
1866 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
1867 {
1868 http->status = HTTP_ERROR;
1869 return (-1);
1870 }
1871
1872 for (i = 0; i < HTTP_FIELD_MAX; i ++)
1873 if (http->fields[i][0] != '\0')
1874 {
1875 DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));
1876
1877 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)
1878 {
1879 http->status = HTTP_ERROR;
1880 return (-1);
1881 }
1882 }
1883
1884 if (http->cookie)
1885 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
1886 {
1887 http->status = HTTP_ERROR;
1888 return (-1);
1889 }
1890
1891 if (httpPrintf(http, "\r\n") < 1)
1892 {
1893 http->status = HTTP_ERROR;
1894 return (-1);
1895 }
1896
1897 httpGetLength2(http);
1898 httpClearFields(http);
1899
1900 return (0);
1901 }
1902
1903
1904 #ifdef HAVE_SSL
1905 /*
1906 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
1907 */
1908
1909 static int /* O - Status of connection */
1910 http_setup_ssl(http_t *http) /* I - HTTP data */
1911 {
1912 # ifdef HAVE_LIBSSL
1913 SSL_CTX *context; /* Context for encryption */
1914 SSL *conn; /* Connection for encryption */
1915 # elif defined(HAVE_GNUTLS)
1916 http_tls_t *conn; /* TLS session object */
1917 gnutls_certificate_client_credentials *credentials;
1918 /* TLS credentials */
1919 # elif defined(HAVE_CDSASSL)
1920 SSLContextRef conn; /* Context for encryption */
1921 OSStatus error; /* Error info */
1922 # endif /* HAVE_LIBSSL */
1923
1924
1925 DEBUG_printf(("http_setup_ssl(http=%p)\n", http));
1926
1927 # ifdef HAVE_LIBSSL
1928 context = SSL_CTX_new(SSLv23_client_method());
1929
1930 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
1931
1932 conn = SSL_new(context);
1933
1934 SSL_set_fd(conn, http->fd);
1935 if (SSL_connect(conn) != 1)
1936 {
1937 # ifdef DEBUG
1938 unsigned long error; /* Error code */
1939
1940 while ((error = ERR_get_error()) != 0)
1941 printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));
1942 # endif /* DEBUG */
1943
1944 SSL_CTX_free(context);
1945 SSL_free(conn);
1946
1947 # ifdef WIN32
1948 http->error = WSAGetLastError();
1949 # else
1950 http->error = errno;
1951 # endif /* WIN32 */
1952 http->status = HTTP_ERROR;
1953
1954 return (HTTP_ERROR);
1955 }
1956
1957 # elif defined(HAVE_GNUTLS)
1958 conn = (http_tls_t *)malloc(sizeof(http_tls_t));
1959
1960 if (conn == NULL)
1961 {
1962 http->error = errno;
1963 http->status = HTTP_ERROR;
1964
1965 return (-1);
1966 }
1967
1968 credentials = (gnutls_certificate_client_credentials *)
1969 malloc(sizeof(gnutls_certificate_client_credentials));
1970 if (credentials == NULL)
1971 {
1972 free(conn);
1973
1974 http->error = errno;
1975 http->status = HTTP_ERROR;
1976
1977 return (-1);
1978 }
1979
1980 gnutls_certificate_allocate_credentials(credentials);
1981
1982 gnutls_init(&(conn->session), GNUTLS_CLIENT);
1983 gnutls_set_default_priority(conn->session);
1984 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
1985 gnutls_transport_set_ptr(conn->session, http->fd);
1986
1987 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
1988 {
1989 http->error = errno;
1990 http->status = HTTP_ERROR;
1991
1992 return (-1);
1993 }
1994
1995 conn->credentials = credentials;
1996
1997 # elif defined(HAVE_CDSASSL)
1998 error = SSLNewContext(false, &conn);
1999
2000 if (!error)
2001 error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
2002
2003 if (!error)
2004 error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);
2005
2006 if (!error)
2007 error = SSLSetAllowsExpiredCerts(conn, true);
2008
2009 if (!error)
2010 error = SSLSetAllowsAnyRoot(conn, true);
2011
2012 if (!error)
2013 error = SSLHandshake(conn);
2014
2015 if (error != 0)
2016 {
2017 http->error = error;
2018 http->status = HTTP_ERROR;
2019
2020 SSLDisposeContext(conn);
2021
2022 close(http->fd);
2023
2024 return (-1);
2025 }
2026 # endif /* HAVE_CDSASSL */
2027
2028 http->tls = conn;
2029 return (0);
2030 }
2031 #endif /* HAVE_SSL */
2032
2033
2034 #ifdef HAVE_SSL
2035 /*
2036 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
2037 */
2038
2039 static void
2040 http_shutdown_ssl(http_t *http) /* I - HTTP data */
2041 {
2042 # ifdef HAVE_LIBSSL
2043 SSL_CTX *context; /* Context for encryption */
2044 SSL *conn; /* Connection for encryption */
2045
2046
2047 conn = (SSL *)(http->tls);
2048 context = SSL_get_SSL_CTX(conn);
2049
2050 SSL_shutdown(conn);
2051 SSL_CTX_free(context);
2052 SSL_free(conn);
2053
2054 # elif defined(HAVE_GNUTLS)
2055 http_tls_t *conn; /* Encryption session */
2056 gnutls_certificate_client_credentials *credentials;
2057 /* TLS credentials */
2058
2059
2060 conn = (http_tls_t *)(http->tls);
2061 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
2062
2063 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
2064 gnutls_deinit(conn->session);
2065 gnutls_certificate_free_credentials(*credentials);
2066 free(credentials);
2067 free(conn);
2068
2069 # elif defined(HAVE_CDSASSL)
2070 SSLClose((SSLContextRef)http->tls);
2071 SSLDisposeContext((SSLContextRef)http->tls);
2072 # endif /* HAVE_LIBSSL */
2073
2074 http->tls = NULL;
2075 }
2076 #endif /* HAVE_SSL */
2077
2078
2079 #ifdef HAVE_SSL
2080 /*
2081 * 'http_upgrade()' - Force upgrade to TLS encryption.
2082 */
2083
2084 static int /* O - Status of connection */
2085 http_upgrade(http_t *http) /* I - HTTP data */
2086 {
2087 int ret; /* Return value */
2088 http_t myhttp; /* Local copy of HTTP data */
2089
2090
2091 DEBUG_printf(("http_upgrade(%p)\n", http));
2092
2093 /*
2094 * Copy the HTTP data to a local variable so we can do the OPTIONS
2095 * request without interfering with the existing request data...
2096 */
2097
2098 memcpy(&myhttp, http, sizeof(myhttp));
2099
2100 /*
2101 * Send an OPTIONS request to the server, requiring SSL or TLS
2102 * encryption on the link...
2103 */
2104
2105 httpClearFields(&myhttp);
2106 httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");
2107 httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
2108
2109 if ((ret = httpOptions(&myhttp, "*")) == 0)
2110 {
2111 /*
2112 * Wait for the secure connection...
2113 */
2114
2115 while (httpUpdate(&myhttp) == HTTP_CONTINUE);
2116 }
2117
2118 httpFlush(&myhttp);
2119
2120 /*
2121 * Copy the HTTP data back over, if any...
2122 */
2123
2124 http->fd = myhttp.fd;
2125 http->error = myhttp.error;
2126 http->activity = myhttp.activity;
2127 http->status = myhttp.status;
2128 http->version = myhttp.version;
2129 http->keep_alive = myhttp.keep_alive;
2130 http->used = myhttp.used;
2131
2132 if (http->used)
2133 memcpy(http->buffer, myhttp.buffer, http->used);
2134
2135 http->auth_type = myhttp.auth_type;
2136 http->nonce_count = myhttp.nonce_count;
2137
2138 memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));
2139
2140 http->tls = myhttp.tls;
2141 http->encryption = myhttp.encryption;
2142
2143 /*
2144 * See if we actually went secure...
2145 */
2146
2147 if (!http->tls)
2148 {
2149 /*
2150 * Server does not support HTTP upgrade...
2151 */
2152
2153 DEBUG_puts("Server does not support HTTP upgrade!");
2154
2155 # ifdef WIN32
2156 closesocket(http->fd);
2157 # else
2158 close(http->fd);
2159 # endif
2160
2161 http->fd = -1;
2162
2163 return (-1);
2164 }
2165 else
2166 return (ret);
2167 }
2168 #endif /* HAVE_SSL */
2169
2170
2171 /*
2172 * 'http_wait()' - Wait for data available on a connection.
2173 */
2174
2175 static int /* O - 1 if data is available, 0 otherwise */
2176 http_wait(http_t *http, /* I - HTTP data */
2177 int msec) /* I - Milliseconds to wait */
2178 {
2179 #ifndef WIN32
2180 struct rlimit limit; /* Runtime limit */
2181 int set_size; /* Size of select set */
2182 #endif /* !WIN32 */
2183 struct timeval timeout; /* Timeout */
2184 int nfds; /* Result from select() */
2185
2186
2187 DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
2188
2189 /*
2190 * Check the SSL/TLS buffers for data first...
2191 */
2192
2193 #ifdef HAVE_SSL
2194 if (http->tls)
2195 {
2196 # ifdef HAVE_LIBSSL
2197 if (SSL_pending((SSL *)(http->tls)))
2198 return (1);
2199 # elif defined(HAVE_GNUTLS)
2200 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2201 return (1);
2202 # elif defined(HAVE_CDSASSL)
2203 size_t bytes; /* Bytes that are available */
2204
2205 if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
2206 return (1);
2207 # endif /* HAVE_LIBSSL */
2208 }
2209 #endif /* HAVE_SSL */
2210
2211 /*
2212 * Then try doing a select() to poll the socket...
2213 */
2214
2215 if (!http->input_set)
2216 {
2217 #ifdef WIN32
2218 /*
2219 * Windows has a fixed-size select() structure, different (surprise,
2220 * surprise!) from all UNIX implementations. Just allocate this
2221 * fixed structure...
2222 */
2223
2224 http->input_set = calloc(1, sizeof(fd_set));
2225 #else
2226 /*
2227 * Allocate the select() input set based upon the max number of file
2228 * descriptors available for this process...
2229 */
2230
2231 getrlimit(RLIMIT_NOFILE, &limit);
2232
2233 set_size = (limit.rlim_cur + 31) / 8 + 4;
2234 if (set_size < sizeof(fd_set))
2235 set_size = sizeof(fd_set);
2236
2237 http->input_set = calloc(1, set_size);
2238 #endif /* WIN32 */
2239
2240 if (!http->input_set)
2241 return (0);
2242 }
2243
2244 do
2245 {
2246 FD_SET(http->fd, http->input_set);
2247
2248 if (msec >= 0)
2249 {
2250 timeout.tv_sec = msec / 1000;
2251 timeout.tv_usec = (msec % 1000) * 1000;
2252
2253 nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
2254 }
2255 else
2256 nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
2257 }
2258 #ifdef WIN32
2259 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2260 #else
2261 while (nfds < 0 && errno == EINTR);
2262 #endif /* WIN32 */
2263
2264 FD_CLR(http->fd, http->input_set);
2265
2266 return (nfds > 0);
2267 }
2268
2269
2270 /*
2271 * 'http_write()' - Write a buffer to a HTTP connection.
2272 */
2273
2274 static int /* O - Number of bytes written */
2275 http_write(http_t *http, /* I - HTTP data */
2276 const char *buffer, /* I - Buffer for data */
2277 int length) /* I - Number of bytes to write */
2278 {
2279 int tbytes, /* Total bytes sent */
2280 bytes; /* Bytes sent */
2281
2282
2283 tbytes = 0;
2284
2285 while (length > 0)
2286 {
2287 #ifdef HAVE_SSL
2288 if (http->tls)
2289 bytes = http_write_ssl(http, buffer, length);
2290 else
2291 #endif /* HAVE_SSL */
2292 bytes = send(http->fd, buffer, length, 0);
2293
2294 if (bytes < 0)
2295 {
2296 #ifdef WIN32
2297 if (WSAGetLastError() != http->error)
2298 {
2299 http->error = WSAGetLastError();
2300 continue;
2301 }
2302 #else
2303 if (errno == EINTR)
2304 continue;
2305 else if (errno != http->error && errno != ECONNRESET)
2306 {
2307 http->error = errno;
2308 continue;
2309 }
2310 #endif /* WIN32 */
2311
2312 DEBUG_puts("http_write: error writing data...\n");
2313
2314 return (-1);
2315 }
2316
2317 buffer += bytes;
2318 tbytes += bytes;
2319 length -= bytes;
2320 }
2321
2322 #ifdef DEBUG
2323 {
2324 int i, j, ch;
2325 printf("http_write: wrote %d bytes: \n", tbytes);
2326 for (i = 0, buffer -= tbytes; i < tbytes; i += 16)
2327 {
2328 printf(" ");
2329
2330 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2331 printf(" %02X", buffer[i + j] & 255);
2332
2333 while (j < 16)
2334 {
2335 printf(" ");
2336 j ++;
2337 }
2338
2339 printf(" ");
2340 for (j = 0; j < 16 && (i + j) < tbytes; j ++)
2341 {
2342 ch = buffer[i + j] & 255;
2343
2344 if (ch < ' ' || ch == 127)
2345 ch = '.';
2346
2347 putchar(ch);
2348 }
2349 putchar('\n');
2350 }
2351 }
2352 #endif /* DEBUG */
2353
2354 return (tbytes);
2355 }
2356
2357
2358 /*
2359 * 'http_write_chunk()' - Write a chunked buffer.
2360 */
2361
2362 static int /* O - Number bytes written */
2363 http_write_chunk(http_t *http, /* I - HTTP data */
2364 const char *buffer, /* I - Buffer to write */
2365 int length) /* I - Length of buffer */
2366 {
2367 char header[255]; /* Chunk header */
2368 int bytes; /* Bytes written */
2369
2370 DEBUG_printf(("http_write_chunk(http=%p, buffer=%p, length=%d)\n",
2371 http, buffer, length));
2372
2373 /*
2374 * Write the chunk header, data, and trailer.
2375 */
2376
2377 sprintf(header, "%x\r\n", length);
2378 if (http_write(http, header, strlen(header)) < 0)
2379 {
2380 DEBUG_puts(" http_write of length failed!");
2381 return (-1);
2382 }
2383
2384 if ((bytes = http_write(http, buffer, length)) < 0)
2385 {
2386 DEBUG_puts(" http_write of buffer failed!");
2387 return (-1);
2388 }
2389
2390 if (http_write(http, "\r\n", 2) < 0)
2391 {
2392 DEBUG_puts(" http_write of CR LF failed!");
2393 return (-1);
2394 }
2395
2396 return (bytes);
2397 }
2398
2399
2400 #ifdef HAVE_SSL
2401 /*
2402 * 'http_write_ssl()' - Write to a SSL/TLS connection.
2403 */
2404
2405 static int /* O - Bytes written */
2406 http_write_ssl(http_t *http, /* I - HTTP data */
2407 const char *buf, /* I - Buffer holding data */
2408 int len) /* I - Length of buffer */
2409 {
2410 # if defined(HAVE_LIBSSL)
2411 return (SSL_write((SSL *)(http->tls), buf, len));
2412
2413 # elif defined(HAVE_GNUTLS)
2414 return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
2415 # elif defined(HAVE_CDSASSL)
2416 OSStatus error; /* Error info */
2417 size_t processed; /* Number of bytes processed */
2418
2419
2420 error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
2421
2422 if (error == 0)
2423 return (processed);
2424 else
2425 {
2426 http->error = error;
2427 return (-1);
2428 }
2429 # endif /* HAVE_LIBSSL */
2430 }
2431 #endif /* HAVE_SSL */
2432
2433
2434 /*
2435 * End of "$Id$".
2436 */