1/* 2 * "$Id: http.c 12131 2014-08-28 23:38:16Z msweet $" 3 * 4 * HTTP routines for CUPS. 5 * 6 * Copyright 2007-2014 by Apple Inc. 7 * Copyright 1997-2007 by Easy Software Products, all rights reserved. 8 * 9 * This file contains Kerberos support code, copyright 2006 by 10 * Jelmer Vernooij. 11 * 12 * These coded instructions, statements, and computer programs are the 13 * property of Apple Inc. and are protected by Federal copyright 14 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 15 * which should have been included with this file. If this file is 16 * file is missing or damaged, see the license at "http://www.cups.org/". 17 * 18 * This file is subject to the Apple OS-Developed Software exception. 19 */ 20 21/* 22 * Include necessary headers... 23 */ 24 25#include "cups-private.h" 26#include <fcntl.h> 27#include <math.h> 28#ifdef WIN32 29# include <tchar.h> 30#else 31# include <signal.h> 32# include <sys/time.h> 33# include <sys/resource.h> 34#endif /* WIN32 */ 35#ifdef HAVE_POLL 36# include <poll.h> 37#endif /* HAVE_POLL */ 38 39 40/* 41 * Local functions... 42 */ 43 44#ifdef HAVE_LIBZ 45static void http_content_coding_finish(http_t *http); 46static void http_content_coding_start(http_t *http, 47 const char *value); 48#endif /* HAVE_LIBZ */ 49static http_t *http_create(const char *host, int port, 50 http_addrlist_t *addrlist, int family, 51 http_encryption_t encryption, 52 int blocking, _http_mode_t mode); 53#ifdef DEBUG 54static void http_debug_hex(const char *prefix, const char *buffer, 55 int bytes); 56#endif /* DEBUG */ 57static ssize_t http_read(http_t *http, char *buffer, size_t length); 58static ssize_t http_read_buffered(http_t *http, char *buffer, size_t length); 59static ssize_t http_read_chunk(http_t *http, char *buffer, size_t length); 60static int http_send(http_t *http, http_state_t request, 61 const char *uri); 62static ssize_t http_write(http_t *http, const char *buffer, 63 size_t length); 64static ssize_t http_write_chunk(http_t *http, const char *buffer, 65 size_t length); 66static off_t http_set_length(http_t *http); 67static void http_set_timeout(int fd, double timeout); 68static void http_set_wait(http_t *http); 69 70#ifdef HAVE_SSL 71static int http_tls_upgrade(http_t *http); 72#endif /* HAVE_SSL */ 73 74 75/* 76 * Local globals... 77 */ 78 79static const char * const http_fields[] = 80 { 81 "Accept-Language", 82 "Accept-Ranges", 83 "Authorization", 84 "Connection", 85 "Content-Encoding", 86 "Content-Language", 87 "Content-Length", 88 "Content-Location", 89 "Content-MD5", 90 "Content-Range", 91 "Content-Type", 92 "Content-Version", 93 "Date", 94 "Host", 95 "If-Modified-Since", 96 "If-Unmodified-since", 97 "Keep-Alive", 98 "Last-Modified", 99 "Link", 100 "Location", 101 "Range", 102 "Referer", 103 "Retry-After", 104 "Transfer-Encoding", 105 "Upgrade", 106 "User-Agent", 107 "WWW-Authenticate", 108 "Accept-Encoding", 109 "Allow", 110 "Server" 111 }; 112 113 114/* 115 * 'httpAcceptConnection()' - Accept a new HTTP client connection from the 116 * specified listening socket. 117 * 118 * @since CUPS 1.7/OS X 10.9@ 119 */ 120 121http_t * /* O - HTTP connection or @code NULL@ */ 122httpAcceptConnection(int fd, /* I - Listen socket file descriptor */ 123 int blocking) /* I - 1 if the connection should be 124 blocking, 0 otherwise */ 125{ 126 http_t *http; /* HTTP connection */ 127 http_addrlist_t addrlist; /* Dummy address list */ 128 socklen_t addrlen; /* Length of address */ 129 int val; /* Socket option value */ 130 131 132 /* 133 * Range check input... 134 */ 135 136 if (fd < 0) 137 return (NULL); 138 139 /* 140 * Create the client connection... 141 */ 142 143 memset(&addrlist, 0, sizeof(addrlist)); 144 145 if ((http = http_create(NULL, 0, &addrlist, AF_UNSPEC, 146 HTTP_ENCRYPTION_IF_REQUESTED, blocking, 147 _HTTP_MODE_SERVER)) == NULL) 148 return (NULL); 149 150 /* 151 * Accept the client and get the remote address... 152 */ 153 154 addrlen = sizeof(http_addr_t); 155 156 if ((http->fd = accept(fd, (struct sockaddr *)&(http->addrlist->addr), 157 &addrlen)) < 0) 158 { 159 _cupsSetHTTPError(HTTP_STATUS_ERROR); 160 httpClose(http); 161 162 return (NULL); 163 } 164 165 http->hostaddr = &(http->addrlist->addr); 166 167 if (httpAddrLocalhost(http->hostaddr)) 168 strlcpy(http->hostname, "localhost", sizeof(http->hostname)); 169 else 170 httpAddrString(http->hostaddr, http->hostname, sizeof(http->hostname)); 171 172#ifdef SO_NOSIGPIPE 173 /* 174 * Disable SIGPIPE for this socket. 175 */ 176 177 val = 1; 178 setsockopt(http->fd, SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val)); 179#endif /* SO_NOSIGPIPE */ 180 181 /* 182 * Using TCP_NODELAY improves responsiveness, especially on systems 183 * with a slow loopback interface. Since we write large buffers 184 * when sending print files and requests, there shouldn't be any 185 * performance penalty for this... 186 */ 187 188 val = 1; 189 setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, CUPS_SOCAST &val, sizeof(val)); 190 191#ifdef FD_CLOEXEC 192 /* 193 * Close this socket when starting another process... 194 */ 195 196 fcntl(http->fd, F_SETFD, FD_CLOEXEC); 197#endif /* FD_CLOEXEC */ 198 199 return (http); 200} 201 202 203/* 204 * 'httpAddCredential()' - Allocates and adds a single credential to an array. 205 * 206 * Use @code cupsArrayNew(NULL, NULL)@ to create a credentials array. 207 * 208 * @since CUPS 1.5/OS X 10.7@ 209 */ 210 211int /* O - 0 on success, -1 on error */ 212httpAddCredential( 213 cups_array_t *credentials, /* I - Credentials array */ 214 const void *data, /* I - PEM-encoded X.509 data */ 215 size_t datalen) /* I - Length of data */ 216{ 217 http_credential_t *credential; /* Credential data */ 218 219 220 if ((credential = malloc(sizeof(http_credential_t))) != NULL) 221 { 222 credential->datalen = datalen; 223 224 if ((credential->data = malloc(datalen)) != NULL) 225 { 226 memcpy(credential->data, data, datalen); 227 cupsArrayAdd(credentials, credential); 228 return (0); 229 } 230 231 free(credential); 232 } 233 234 return (-1); 235} 236 237 238/* 239 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection. 240 */ 241 242void 243httpBlocking(http_t *http, /* I - HTTP connection */ 244 int b) /* I - 1 = blocking, 0 = non-blocking */ 245{ 246 if (http) 247 { 248 http->blocking = b; 249 http_set_wait(http); 250 } 251} 252 253 254/* 255 * 'httpCheck()' - Check to see if there is a pending response from the server. 256 */ 257 258int /* O - 0 = no data, 1 = data available */ 259httpCheck(http_t *http) /* I - HTTP connection */ 260{ 261 return (httpWait(http, 0)); 262} 263 264 265/* 266 * 'httpClearCookie()' - Clear the cookie value(s). 267 * 268 * @since CUPS 1.1.19/OS X 10.3@ 269 */ 270 271void 272httpClearCookie(http_t *http) /* I - HTTP connection */ 273{ 274 if (!http) 275 return; 276 277 if (http->cookie) 278 { 279 free(http->cookie); 280 http->cookie = NULL; 281 } 282} 283 284 285/* 286 * 'httpClearFields()' - Clear HTTP request fields. 287 */ 288 289void 290httpClearFields(http_t *http) /* I - HTTP connection */ 291{ 292 DEBUG_printf(("httpClearFields(http=%p)", http)); 293 294 if (http) 295 { 296 memset(http->fields, 0, sizeof(http->fields)); 297 298 if (http->mode == _HTTP_MODE_CLIENT) 299 { 300 if (http->hostname[0] == '/') 301 httpSetField(http, HTTP_FIELD_HOST, "localhost"); 302 else 303 httpSetField(http, HTTP_FIELD_HOST, http->hostname); 304 } 305 306 if (http->field_authorization) 307 { 308 free(http->field_authorization); 309 http->field_authorization = NULL; 310 } 311 312 if (http->accept_encoding) 313 { 314 _cupsStrFree(http->accept_encoding); 315 http->accept_encoding = NULL; 316 } 317 318 if (http->allow) 319 { 320 _cupsStrFree(http->allow); 321 http->allow = NULL; 322 } 323 324 if (http->server) 325 { 326 _cupsStrFree(http->server); 327 http->server = NULL; 328 } 329 330 http->expect = (http_status_t)0; 331 } 332} 333 334 335/* 336 * 'httpClose()' - Close an HTTP connection. 337 */ 338 339void 340httpClose(http_t *http) /* I - HTTP connection */ 341{ 342#ifdef HAVE_GSSAPI 343 OM_uint32 minor_status; /* Minor status code */ 344#endif /* HAVE_GSSAPI */ 345 346 347 DEBUG_printf(("httpClose(http=%p)", http)); 348 349 /* 350 * Range check input... 351 */ 352 353 if (!http) 354 return; 355 356 /* 357 * Close any open connection... 358 */ 359 360 _httpDisconnect(http); 361 362 /* 363 * Free memory used... 364 */ 365 366 httpAddrFreeList(http->addrlist); 367 368 if (http->cookie) 369 free(http->cookie); 370 371#ifdef HAVE_GSSAPI 372 if (http->gssctx != GSS_C_NO_CONTEXT) 373 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER); 374 375 if (http->gssname != GSS_C_NO_NAME) 376 gss_release_name(&minor_status, &http->gssname); 377#endif /* HAVE_GSSAPI */ 378 379#ifdef HAVE_AUTHORIZATION_H 380 if (http->auth_ref) 381 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); 382#endif /* HAVE_AUTHORIZATION_H */ 383 384 httpClearFields(http); 385 386 if (http->authstring && http->authstring != http->_authstring) 387 free(http->authstring); 388 389 free(http); 390} 391 392 393/* 394 * 'httpCompareCredentials()' - Compare two sets of X.509 credentials. 395 * 396 * @since CUPS 2.0/OS 10.10@ 397 */ 398 399int /* O - 1 if they match, 0 if they do not */ 400httpCompareCredentials( 401 cups_array_t *cred1, /* I - First set of X.509 credentials */ 402 cups_array_t *cred2) /* I - Second set of X.509 credentials */ 403{ 404 http_credential_t *temp1, *temp2; /* Temporary credentials */ 405 406 407 for (temp1 = (http_credential_t *)cupsArrayFirst(cred1), temp2 = (http_credential_t *)cupsArrayFirst(cred2); temp1 && temp2; temp1 = (http_credential_t *)cupsArrayNext(cred1), temp2 = (http_credential_t *)cupsArrayNext(cred2)) 408 if (temp1->datalen != temp2->datalen) 409 return (0); 410 else if (memcmp(temp1->data, temp2->data, temp1->datalen)) 411 return (0); 412 413 return (temp1 == temp2); 414} 415 416 417/* 418 * 'httpConnect()' - Connect to a HTTP server. 419 * 420 * This function is deprecated - use @link httpConnect2@ instead. 421 * 422 * @deprecated@ 423 */ 424 425http_t * /* O - New HTTP connection */ 426httpConnect(const char *host, /* I - Host to connect to */ 427 int port) /* I - Port number */ 428{ 429 return (httpConnect2(host, port, NULL, AF_UNSPEC, 430 HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL)); 431} 432 433 434/* 435 * 'httpConnect2()' - Connect to a HTTP server. 436 * 437 * @since CUPS 1.7/OS X 10.9@ 438 */ 439 440http_t * /* O - New HTTP connection */ 441httpConnect2( 442 const char *host, /* I - Host to connect to */ 443 int port, /* I - Port number */ 444 http_addrlist_t *addrlist, /* I - List of addresses or NULL to lookup */ 445 int family, /* I - Address family to use or @code AF_UNSPEC@ for any */ 446 http_encryption_t encryption, /* I - Type of encryption to use */ 447 int blocking, /* I - 1 for blocking connection, 0 for non-blocking */ 448 int msec, /* I - Connection timeout in milliseconds, 0 means don't connect */ 449 int *cancel) /* I - Pointer to "cancel" variable */ 450{ 451 http_t *http; /* New HTTP connection */ 452 453 454 DEBUG_printf(("httpConnect2(host=\"%s\", port=%d, addrlist=%p, family=%d, " 455 "encryption=%d, blocking=%d, msec=%d, cancel=%p)", host, port, 456 addrlist, family, encryption, blocking, msec, cancel)); 457 458 /* 459 * Create the HTTP structure... 460 */ 461 462 if ((http = http_create(host, port, addrlist, family, encryption, blocking, 463 _HTTP_MODE_CLIENT)) == NULL) 464 return (NULL); 465 466 /* 467 * Optionally connect to the remote system... 468 */ 469 470 if (msec == 0 || !httpReconnect2(http, msec, cancel)) 471 return (http); 472 473 /* 474 * Could not connect to any known address - bail out! 475 */ 476 477 httpClose(http); 478 479 return (NULL); 480} 481 482 483/* 484 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption. 485 * 486 * This function is now deprecated. Please use the @link httpConnect2@ function 487 * instead. 488 * 489 * @deprecated@ 490 */ 491 492http_t * /* O - New HTTP connection */ 493httpConnectEncrypt( 494 const char *host, /* I - Host to connect to */ 495 int port, /* I - Port number */ 496 http_encryption_t encryption) /* I - Type of encryption to use */ 497{ 498 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)", 499 host, port, encryption)); 500 501 return (httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 30000, 502 NULL)); 503} 504 505 506/* 507 * 'httpDelete()' - Send a DELETE request to the server. 508 */ 509 510int /* O - Status of call (0 = success) */ 511httpDelete(http_t *http, /* I - HTTP connection */ 512 const char *uri) /* I - URI to delete */ 513{ 514 return (http_send(http, HTTP_STATE_DELETE, uri)); 515} 516 517 518/* 519 * '_httpDisconnect()' - Disconnect a HTTP connection. 520 */ 521 522void 523_httpDisconnect(http_t *http) /* I - HTTP connection */ 524{ 525#ifdef HAVE_SSL 526 if (http->tls) 527 _httpTLSStop(http); 528#endif /* HAVE_SSL */ 529 530 httpAddrClose(NULL, http->fd); 531 532 http->fd = -1; 533} 534 535 536/* 537 * 'httpEncryption()' - Set the required encryption on the link. 538 */ 539 540int /* O - -1 on error, 0 on success */ 541httpEncryption(http_t *http, /* I - HTTP connection */ 542 http_encryption_t e) /* I - New encryption preference */ 543{ 544 DEBUG_printf(("httpEncryption(http=%p, e=%d)", http, e)); 545 546#ifdef HAVE_SSL 547 if (!http) 548 return (0); 549 550 if (http->mode == _HTTP_MODE_CLIENT) 551 { 552 http->encryption = e; 553 554 if ((http->encryption == HTTP_ENCRYPTION_ALWAYS && !http->tls) || 555 (http->encryption == HTTP_ENCRYPTION_NEVER && http->tls)) 556 return (httpReconnect2(http, 30000, NULL)); 557 else if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls) 558 return (http_tls_upgrade(http)); 559 else 560 return (0); 561 } 562 else 563 { 564 if (e == HTTP_ENCRYPTION_NEVER && http->tls) 565 return (-1); 566 567 http->encryption = e; 568 if (e != HTTP_ENCRYPTION_IF_REQUESTED && !http->tls) 569 return (_httpTLSStart(http)); 570 else 571 return (0); 572 } 573#else 574 if (e == HTTP_ENCRYPTION_ALWAYS || e == HTTP_ENCRYPTION_REQUIRED) 575 return (-1); 576 else 577 return (0); 578#endif /* HAVE_SSL */ 579} 580 581 582/* 583 * 'httpError()' - Get the last error on a connection. 584 */ 585 586int /* O - Error code (errno) value */ 587httpError(http_t *http) /* I - HTTP connection */ 588{ 589 if (http) 590 return (http->error); 591 else 592 return (EINVAL); 593} 594 595 596/* 597 * 'httpFieldValue()' - Return the HTTP field enumeration value for a field 598 * name. 599 */ 600 601http_field_t /* O - Field index */ 602httpFieldValue(const char *name) /* I - String name */ 603{ 604 int i; /* Looping var */ 605 606 607 for (i = 0; i < HTTP_FIELD_MAX; i ++) 608 if (!_cups_strcasecmp(name, http_fields[i])) 609 return ((http_field_t)i); 610 611 return (HTTP_FIELD_UNKNOWN); 612} 613 614 615/* 616 * 'httpFlush()' - Flush data from a HTTP connection. 617 */ 618 619void 620httpFlush(http_t *http) /* I - HTTP connection */ 621{ 622 char buffer[8192]; /* Junk buffer */ 623 int blocking; /* To block or not to block */ 624 http_state_t oldstate; /* Old state */ 625 626 627 DEBUG_printf(("httpFlush(http=%p), state=%s", http, 628 httpStateString(http->state))); 629 630 /* 631 * Nothing to do if we are in the "waiting" state... 632 */ 633 634 if (http->state == HTTP_STATE_WAITING) 635 return; 636 637 /* 638 * Temporarily set non-blocking mode so we don't get stuck in httpRead()... 639 */ 640 641 blocking = http->blocking; 642 http->blocking = 0; 643 644 /* 645 * Read any data we can... 646 */ 647 648 oldstate = http->state; 649 while (httpRead2(http, buffer, sizeof(buffer)) > 0); 650 651 /* 652 * Restore blocking and reset the connection if we didn't get all of 653 * the remaining data... 654 */ 655 656 http->blocking = blocking; 657 658 if (http->state == oldstate && http->state != HTTP_STATE_WAITING && 659 http->fd >= 0) 660 { 661 /* 662 * Didn't get the data back, so close the current connection. 663 */ 664 665#ifdef HAVE_LIBZ 666 if (http->coding) 667 http_content_coding_finish(http); 668#endif /* HAVE_LIBZ */ 669 670 DEBUG_puts("1httpFlush: Setting state to HTTP_STATE_WAITING and closing."); 671 672 http->state = HTTP_STATE_WAITING; 673 674#ifdef HAVE_SSL 675 if (http->tls) 676 _httpTLSStop(http); 677#endif /* HAVE_SSL */ 678 679 httpAddrClose(NULL, http->fd); 680 681 http->fd = -1; 682 } 683} 684 685 686/* 687 * 'httpFlushWrite()' - Flush data in write buffer. 688 * 689 * @since CUPS 1.2/OS X 10.5@ 690 */ 691 692int /* O - Bytes written or -1 on error */ 693httpFlushWrite(http_t *http) /* I - HTTP connection */ 694{ 695 ssize_t bytes; /* Bytes written */ 696 697 698 DEBUG_printf(("httpFlushWrite(http=%p) data_encoding=%d", http, 699 http ? http->data_encoding : 100)); 700 701 if (!http || !http->wused) 702 { 703 DEBUG_puts(http ? "1httpFlushWrite: Write buffer is empty." : 704 "1httpFlushWrite: No connection."); 705 return (0); 706 } 707 708 if (http->data_encoding == HTTP_ENCODING_CHUNKED) 709 bytes = http_write_chunk(http, http->wbuffer, (size_t)http->wused); 710 else 711 bytes = http_write(http, http->wbuffer, (size_t)http->wused); 712 713 http->wused = 0; 714 715 DEBUG_printf(("1httpFlushWrite: Returning %d, errno=%d.", (int)bytes, errno)); 716 717 return ((int)bytes); 718} 719 720 721/* 722 * 'httpFreeCredentials()' - Free an array of credentials. 723 */ 724 725void 726httpFreeCredentials( 727 cups_array_t *credentials) /* I - Array of credentials */ 728{ 729 http_credential_t *credential; /* Credential */ 730 731 732 for (credential = (http_credential_t *)cupsArrayFirst(credentials); 733 credential; 734 credential = (http_credential_t *)cupsArrayNext(credentials)) 735 { 736 cupsArrayRemove(credentials, credential); 737 free((void *)credential->data); 738 free(credential); 739 } 740 741 cupsArrayDelete(credentials); 742} 743 744 745/* 746 * 'httpGet()' - Send a GET request to the server. 747 */ 748 749int /* O - Status of call (0 = success) */ 750httpGet(http_t *http, /* I - HTTP connection */ 751 const char *uri) /* I - URI to get */ 752{ 753 return (http_send(http, HTTP_STATE_GET, uri)); 754} 755 756 757/* 758 * 'httpGetActivity()' - Get the most recent activity for a connection. 759 * 760 * The return value is the UNIX time of the last read or write. 761 * 762 * @since CUPS 2.0/OS 10.10@ 763 */ 764 765time_t /* O - Time of last read or write */ 766httpGetActivity(http_t *http) /* I - HTTP connection */ 767{ 768 return (http ? http->activity : 0); 769} 770 771 772/* 773 * 'httpGetAuthString()' - Get the current authorization string. 774 * 775 * The authorization string is set by cupsDoAuthentication() and 776 * httpSetAuthString(). Use httpGetAuthString() to retrieve the 777 * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION 778 * value. 779 * 780 * @since CUPS 1.3/OS X 10.5@ 781 */ 782 783char * /* O - Authorization string */ 784httpGetAuthString(http_t *http) /* I - HTTP connection */ 785{ 786 if (http) 787 return (http->authstring); 788 else 789 return (NULL); 790} 791 792 793/* 794 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection. 795 * 796 * @since CUPS 1.2/OS X 10.5@ 797 */ 798 799int /* O - 1 if blocking, 0 if non-blocking */ 800httpGetBlocking(http_t *http) /* I - HTTP connection */ 801{ 802 return (http ? http->blocking : 0); 803} 804 805 806/* 807 * 'httpGetContentEncoding()' - Get a common content encoding, if any, between 808 * the client and server. 809 * 810 * This function uses the value of the Accepts-Encoding HTTP header and must be 811 * called after receiving a response from the server or a request from the 812 * client. The value returned can be use in subsequent requests (for clients) 813 * or in the response (for servers) in order to compress the content stream. 814 * 815 * @since CUPS 1.7/OS X 10.9@ 816 */ 817 818const char * /* O - Content-Coding value or 819 @code NULL@ for the identity 820 coding. */ 821httpGetContentEncoding(http_t *http) /* I - HTTP connection */ 822{ 823#ifdef HAVE_LIBZ 824 if (http && http->accept_encoding) 825 { 826 int i; /* Looping var */ 827 char temp[HTTP_MAX_VALUE], /* Copy of Accepts-Encoding value */ 828 *start, /* Start of coding value */ 829 *end; /* End of coding value */ 830 double qvalue; /* "qvalue" for coding */ 831 struct lconv *loc = localeconv(); /* Locale data */ 832 static const char * const codings[] = 833 { /* Supported content codings */ 834 "deflate", 835 "gzip", 836 "x-deflate", 837 "x-gzip" 838 }; 839 840 strlcpy(temp, http->accept_encoding, sizeof(temp)); 841 842 for (start = temp; *start; start = end) 843 { 844 /* 845 * Find the end of the coding name... 846 */ 847 848 qvalue = 1.0; 849 end = start; 850 while (*end && *end != ';' && *end != ',' && !isspace(*end & 255)) 851 end ++; 852 853 if (*end == ';') 854 { 855 /* 856 * Grab the qvalue as needed... 857 */ 858 859 if (!strncmp(end, ";q=", 3)) 860 qvalue = _cupsStrScand(end + 3, NULL, loc); 861 862 /* 863 * Skip past all attributes... 864 */ 865 866 *end++ = '\0'; 867 while (*end && *end != ',' && !isspace(*end & 255)) 868 end ++; 869 } 870 else if (*end) 871 *end++ = '\0'; 872 873 while (*end && isspace(*end & 255)) 874 end ++; 875 876 /* 877 * Check value if it matches something we support... 878 */ 879 880 if (qvalue <= 0.0) 881 continue; 882 883 for (i = 0; i < (int)(sizeof(codings) / sizeof(codings[0])); i ++) 884 if (!strcmp(start, codings[i])) 885 return (codings[i]); 886 } 887 } 888#endif /* HAVE_LIBZ */ 889 890 return (NULL); 891} 892 893 894/* 895 * 'httpGetCookie()' - Get any cookie data from the response. 896 * 897 * @since CUPS 1.1.19/OS X 10.3@ 898 */ 899 900const char * /* O - Cookie data or NULL */ 901httpGetCookie(http_t *http) /* I - HTTP connecion */ 902{ 903 return (http ? http->cookie : NULL); 904} 905 906 907/* 908 * 'httpGetEncryption()' - Get the current encryption mode of a connection. 909 * 910 * This function returns the encryption mode for the connection. Use the 911 * @link httpIsEncrypted@ function to determine whether a TLS session has 912 * been established. 913 * 914 * @since CUPS 2.0/OS 10.10@ 915 */ 916 917http_encryption_t /* O - Current encryption mode */ 918httpGetEncryption(http_t *http) /* I - HTTP connection */ 919{ 920 return (http ? http->encryption : HTTP_ENCRYPTION_IF_REQUESTED); 921} 922 923 924/* 925 * 'httpGetExpect()' - Get the value of the Expect header, if any. 926 * 927 * Returns @code HTTP_STATUS_NONE@ if there is no Expect header, otherwise 928 * returns the expected HTTP status code, typically @code HTTP_STATUS_CONTINUE@. 929 * 930 * @since CUPS 1.7/OS X 10.9@ 931 */ 932 933http_status_t /* O - Expect: status, if any */ 934httpGetExpect(http_t *http) /* I - HTTP connection */ 935{ 936 if (!http) 937 return (HTTP_STATUS_ERROR); 938 else 939 return (http->expect); 940} 941 942 943/* 944 * 'httpGetFd()' - Get the file descriptor associated with a connection. 945 * 946 * @since CUPS 1.2/OS X 10.5@ 947 */ 948 949int /* O - File descriptor or -1 if none */ 950httpGetFd(http_t *http) /* I - HTTP connection */ 951{ 952 return (http ? http->fd : -1); 953} 954 955 956/* 957 * 'httpGetField()' - Get a field value from a request/response. 958 */ 959 960const char * /* O - Field value */ 961httpGetField(http_t *http, /* I - HTTP connection */ 962 http_field_t field) /* I - Field to get */ 963{ 964 if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) 965 return (NULL); 966 967 switch (field) 968 { 969 case HTTP_FIELD_ACCEPT_ENCODING : 970 return (http->accept_encoding); 971 972 case HTTP_FIELD_ALLOW : 973 return (http->allow); 974 975 case HTTP_FIELD_SERVER : 976 return (http->server); 977 978 case HTTP_FIELD_AUTHORIZATION : 979 if (http->field_authorization) 980 { 981 /* 982 * Special case for WWW-Authenticate: as its contents can be 983 * longer than HTTP_MAX_VALUE... 984 */ 985 986 return (http->field_authorization); 987 } 988 989 default : 990 return (http->fields[field]); 991 } 992} 993 994 995/* 996 * 'httpGetKeepAlive()' - Get the current Keep-Alive state of the connection. 997 * 998 * @since CUPS 2.0/OS 10.10@ 999 */ 1000 1001http_keepalive_t /* O - Keep-Alive state */ 1002httpGetKeepAlive(http_t *http) /* I - HTTP connection */ 1003{ 1004 return (http ? http->keep_alive : HTTP_KEEPALIVE_OFF); 1005} 1006 1007 1008/* 1009 * 'httpGetLength()' - Get the amount of data remaining from the 1010 * content-length or transfer-encoding fields. 1011 * 1012 * This function is deprecated and will not return lengths larger than 1013 * 2^31 - 1; use httpGetLength2() instead. 1014 * 1015 * @deprecated@ 1016 */ 1017 1018int /* O - Content length */ 1019httpGetLength(http_t *http) /* I - HTTP connection */ 1020{ 1021 /* 1022 * Get the read content length and return the 32-bit value. 1023 */ 1024 1025 if (http) 1026 { 1027 httpGetLength2(http); 1028 1029 return (http->_data_remaining); 1030 } 1031 else 1032 return (-1); 1033} 1034 1035 1036/* 1037 * 'httpGetLength2()' - Get the amount of data remaining from the 1038 * content-length or transfer-encoding fields. 1039 * 1040 * This function returns the complete content length, even for 1041 * content larger than 2^31 - 1. 1042 * 1043 * @since CUPS 1.2/OS X 10.5@ 1044 */ 1045 1046off_t /* O - Content length */ 1047httpGetLength2(http_t *http) /* I - HTTP connection */ 1048{ 1049 off_t remaining; /* Remaining length */ 1050 1051 1052 DEBUG_printf(("2httpGetLength2(http=%p), state=%s", http, 1053 httpStateString(http->state))); 1054 1055 if (!http) 1056 return (-1); 1057 1058 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked")) 1059 { 1060 DEBUG_puts("4httpGetLength2: chunked request!"); 1061 remaining = 0; 1062 } 1063 else 1064 { 1065 /* 1066 * The following is a hack for HTTP servers that don't send a 1067 * Content-Length or Transfer-Encoding field... 1068 * 1069 * If there is no Content-Length then the connection must close 1070 * after the transfer is complete... 1071 */ 1072 1073 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) 1074 { 1075 /* 1076 * Default content length is 0 for errors and certain types of operations, 1077 * and 2^31-1 for other successful requests... 1078 */ 1079 1080 if (http->status >= HTTP_STATUS_MULTIPLE_CHOICES || 1081 http->state == HTTP_STATE_OPTIONS || 1082 (http->state == HTTP_STATE_GET && http->mode == _HTTP_MODE_SERVER) || 1083 http->state == HTTP_STATE_HEAD || 1084 (http->state == HTTP_STATE_PUT && http->mode == _HTTP_MODE_CLIENT) || 1085 http->state == HTTP_STATE_DELETE || 1086 http->state == HTTP_STATE_TRACE || 1087 http->state == HTTP_STATE_CONNECT) 1088 remaining = 0; 1089 else 1090 remaining = 2147483647; 1091 } 1092 else if ((remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH], 1093 NULL, 10)) < 0) 1094 remaining = -1; 1095 1096 DEBUG_printf(("4httpGetLength2: content_length=" CUPS_LLFMT, 1097 CUPS_LLCAST remaining)); 1098 } 1099 1100 return (remaining); 1101} 1102 1103 1104/* 1105 * 'httpGetPending()' - Get the number of bytes that are buffered for writing. 1106 * 1107 * @since CUPS 2.0/OS 10.10@ 1108 */ 1109 1110size_t /* O - Number of bytes buffered */ 1111httpGetPending(http_t *http) /* I - HTTP connection */ 1112{ 1113 return (http ? (size_t)http->wused : 0); 1114} 1115 1116 1117/* 1118 * 'httpGetReady()' - Get the number of bytes that can be read without blocking. 1119 * 1120 * @since CUPS 2.0/OS 10.10@ 1121 */ 1122 1123size_t /* O - Number of bytes available */ 1124httpGetReady(http_t *http) /* I - HTTP connection */ 1125{ 1126 if (!http) 1127 return (0); 1128 else if (http->used > 0) 1129 return ((size_t)http->used); 1130#ifdef HAVE_SSL 1131 else if (http->tls) 1132 return (_httpTLSPending(http)); 1133#endif /* HAVE_SSL */ 1134 1135 return (0); 1136} 1137 1138 1139/* 1140 * 'httpGetRemaining()' - Get the number of remaining bytes in the message 1141 * body or current chunk. 1142 * 1143 * The @link httpIsChunked@ function can be used to determine whether the 1144 * message body is chunked or fixed-length. 1145 * 1146 * @since CUPS 2.0/OS 10.10@ 1147 */ 1148 1149size_t /* O - Remaining bytes */ 1150httpGetRemaining(http_t *http) /* I - HTTP connection */ 1151{ 1152 return (http ? (size_t)http->data_remaining : 0); 1153} 1154 1155 1156/* 1157 * 'httpGets()' - Get a line of text from a HTTP connection. 1158 */ 1159 1160char * /* O - Line or NULL */ 1161httpGets(char *line, /* I - Line to read into */ 1162 int length, /* I - Max length of buffer */ 1163 http_t *http) /* I - HTTP connection */ 1164{ 1165 char *lineptr, /* Pointer into line */ 1166 *lineend, /* End of line */ 1167 *bufptr, /* Pointer into input buffer */ 1168 *bufend; /* Pointer to end of buffer */ 1169 ssize_t bytes; /* Number of bytes read */ 1170 int eol; /* End-of-line? */ 1171 1172 1173 DEBUG_printf(("2httpGets(line=%p, length=%d, http=%p)", line, length, http)); 1174 1175 if (!http || !line || length <= 1) 1176 return (NULL); 1177 1178 /* 1179 * Read a line from the buffer... 1180 */ 1181 1182 http->error = 0; 1183 lineptr = line; 1184 lineend = line + length - 1; 1185 eol = 0; 1186 1187 while (lineptr < lineend) 1188 { 1189 /* 1190 * Pre-load the buffer as needed... 1191 */ 1192 1193#ifdef WIN32 1194 WSASetLastError(0); 1195#else 1196 errno = 0; 1197#endif /* WIN32 */ 1198 1199 while (http->used == 0) 1200 { 1201 /* 1202 * No newline; see if there is more data to be read... 1203 */ 1204 1205 while (!_httpWait(http, http->wait_value, 1)) 1206 { 1207 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 1208 continue; 1209 1210 DEBUG_puts("3httpGets: Timed out!"); 1211#ifdef WIN32 1212 http->error = WSAETIMEDOUT; 1213#else 1214 http->error = ETIMEDOUT; 1215#endif /* WIN32 */ 1216 return (NULL); 1217 } 1218 1219 bytes = http_read(http, http->buffer + http->used, (size_t)(HTTP_MAX_BUFFER - http->used)); 1220 1221 DEBUG_printf(("4httpGets: read " CUPS_LLFMT " bytes.", CUPS_LLCAST bytes)); 1222 1223 if (bytes < 0) 1224 { 1225 /* 1226 * Nope, can't get a line this time... 1227 */ 1228 1229#ifdef WIN32 1230 DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError())); 1231 1232 if (WSAGetLastError() == WSAEINTR) 1233 continue; 1234 else if (WSAGetLastError() == WSAEWOULDBLOCK) 1235 { 1236 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 1237 continue; 1238 1239 http->error = WSAGetLastError(); 1240 } 1241 else if (WSAGetLastError() != http->error) 1242 { 1243 http->error = WSAGetLastError(); 1244 continue; 1245 } 1246 1247#else 1248 DEBUG_printf(("3httpGets: recv() error %d!", errno)); 1249 1250 if (errno == EINTR) 1251 continue; 1252 else if (errno == EWOULDBLOCK || errno == EAGAIN) 1253 { 1254 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 1255 continue; 1256 else if (!http->timeout_cb && errno == EAGAIN) 1257 continue; 1258 1259 http->error = errno; 1260 } 1261 else if (errno != http->error) 1262 { 1263 http->error = errno; 1264 continue; 1265 } 1266#endif /* WIN32 */ 1267 1268 return (NULL); 1269 } 1270 else if (bytes == 0) 1271 { 1272 http->error = EPIPE; 1273 1274 return (NULL); 1275 } 1276 1277 /* 1278 * Yup, update the amount used... 1279 */ 1280 1281 http->used += (int)bytes; 1282 } 1283 1284 /* 1285 * Now copy as much of the current line as possible... 1286 */ 1287 1288 for (bufptr = http->buffer, bufend = http->buffer + http->used; 1289 lineptr < lineend && bufptr < bufend;) 1290 { 1291 if (*bufptr == 0x0a) 1292 { 1293 eol = 1; 1294 bufptr ++; 1295 break; 1296 } 1297 else if (*bufptr == 0x0d) 1298 bufptr ++; 1299 else 1300 *lineptr++ = *bufptr++; 1301 } 1302 1303 http->used -= (int)(bufptr - http->buffer); 1304 if (http->used > 0) 1305 memmove(http->buffer, bufptr, (size_t)http->used); 1306 1307 if (eol) 1308 { 1309 /* 1310 * End of line... 1311 */ 1312 1313 http->activity = time(NULL); 1314 1315 *lineptr = '\0'; 1316 1317 DEBUG_printf(("3httpGets: Returning \"%s\"", line)); 1318 1319 return (line); 1320 } 1321 } 1322 1323 DEBUG_puts("3httpGets: No new line available!"); 1324 1325 return (NULL); 1326} 1327 1328 1329/* 1330 * 'httpGetState()' - Get the current state of the HTTP request. 1331 */ 1332 1333http_state_t /* O - HTTP state */ 1334httpGetState(http_t *http) /* I - HTTP connection */ 1335{ 1336 return (http ? http->state : HTTP_STATE_ERROR); 1337} 1338 1339 1340/* 1341 * 'httpGetStatus()' - Get the status of the last HTTP request. 1342 * 1343 * @since CUPS 1.2/OS X 10.5@ 1344 */ 1345 1346http_status_t /* O - HTTP status */ 1347httpGetStatus(http_t *http) /* I - HTTP connection */ 1348{ 1349 return (http ? http->status : HTTP_STATUS_ERROR); 1350} 1351 1352 1353/* 1354 * 'httpGetSubField()' - Get a sub-field value. 1355 * 1356 * @deprecated@ 1357 */ 1358 1359char * /* O - Value or NULL */ 1360httpGetSubField(http_t *http, /* I - HTTP connection */ 1361 http_field_t field, /* I - Field index */ 1362 const char *name, /* I - Name of sub-field */ 1363 char *value) /* O - Value string */ 1364{ 1365 return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE)); 1366} 1367 1368 1369/* 1370 * 'httpGetSubField2()' - Get a sub-field value. 1371 * 1372 * @since CUPS 1.2/OS X 10.5@ 1373 */ 1374 1375char * /* O - Value or NULL */ 1376httpGetSubField2(http_t *http, /* I - HTTP connection */ 1377 http_field_t field, /* I - Field index */ 1378 const char *name, /* I - Name of sub-field */ 1379 char *value, /* O - Value string */ 1380 int valuelen) /* I - Size of value buffer */ 1381{ 1382 const char *fptr; /* Pointer into field */ 1383 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ 1384 *ptr, /* Pointer into string buffer */ 1385 *end; /* End of value buffer */ 1386 1387 DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, " 1388 "valuelen=%d)", http, field, name, value, valuelen)); 1389 1390 if (!http || !name || !value || valuelen < 2 || 1391 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) 1392 return (NULL); 1393 1394 end = value + valuelen - 1; 1395 1396 for (fptr = http->fields[field]; *fptr;) 1397 { 1398 /* 1399 * Skip leading whitespace... 1400 */ 1401 1402 while (_cups_isspace(*fptr)) 1403 fptr ++; 1404 1405 if (*fptr == ',') 1406 { 1407 fptr ++; 1408 continue; 1409 } 1410 1411 /* 1412 * Get the sub-field name... 1413 */ 1414 1415 for (ptr = temp; 1416 *fptr && *fptr != '=' && !_cups_isspace(*fptr) && 1417 ptr < (temp + sizeof(temp) - 1); 1418 *ptr++ = *fptr++); 1419 1420 *ptr = '\0'; 1421 1422 DEBUG_printf(("4httpGetSubField2: name=\"%s\"", temp)); 1423 1424 /* 1425 * Skip trailing chars up to the '='... 1426 */ 1427 1428 while (_cups_isspace(*fptr)) 1429 fptr ++; 1430 1431 if (!*fptr) 1432 break; 1433 1434 if (*fptr != '=') 1435 continue; 1436 1437 /* 1438 * Skip = and leading whitespace... 1439 */ 1440 1441 fptr ++; 1442 1443 while (_cups_isspace(*fptr)) 1444 fptr ++; 1445 1446 if (*fptr == '\"') 1447 { 1448 /* 1449 * Read quoted string... 1450 */ 1451 1452 for (ptr = value, fptr ++; 1453 *fptr && *fptr != '\"' && ptr < end; 1454 *ptr++ = *fptr++); 1455 1456 *ptr = '\0'; 1457 1458 while (*fptr && *fptr != '\"') 1459 fptr ++; 1460 1461 if (*fptr) 1462 fptr ++; 1463 } 1464 else 1465 { 1466 /* 1467 * Read unquoted string... 1468 */ 1469 1470 for (ptr = value; 1471 *fptr && !_cups_isspace(*fptr) && *fptr != ',' && ptr < end; 1472 *ptr++ = *fptr++); 1473 1474 *ptr = '\0'; 1475 1476 while (*fptr && !_cups_isspace(*fptr) && *fptr != ',') 1477 fptr ++; 1478 } 1479 1480 DEBUG_printf(("4httpGetSubField2: value=\"%s\"", value)); 1481 1482 /* 1483 * See if this is the one... 1484 */ 1485 1486 if (!strcmp(name, temp)) 1487 { 1488 DEBUG_printf(("3httpGetSubField2: Returning \"%s\"", value)); 1489 return (value); 1490 } 1491 } 1492 1493 value[0] = '\0'; 1494 1495 DEBUG_puts("3httpGetSubField2: Returning NULL"); 1496 1497 return (NULL); 1498} 1499 1500 1501/* 1502 * 'httpGetVersion()' - Get the HTTP version at the other end. 1503 */ 1504 1505http_version_t /* O - Version number */ 1506httpGetVersion(http_t *http) /* I - HTTP connection */ 1507{ 1508 return (http ? http->version : HTTP_VERSION_1_0); 1509} 1510 1511 1512/* 1513 * 'httpHead()' - Send a HEAD request to the server. 1514 */ 1515 1516int /* O - Status of call (0 = success) */ 1517httpHead(http_t *http, /* I - HTTP connection */ 1518 const char *uri) /* I - URI for head */ 1519{ 1520 DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", http, uri)); 1521 return (http_send(http, HTTP_STATE_HEAD, uri)); 1522} 1523 1524 1525/* 1526 * 'httpInitialize()' - Initialize the HTTP interface library and set the 1527 * default HTTP proxy (if any). 1528 */ 1529 1530void 1531httpInitialize(void) 1532{ 1533 static int initialized = 0; /* Have we been called before? */ 1534#ifdef WIN32 1535 WSADATA winsockdata; /* WinSock data */ 1536#endif /* WIN32 */ 1537 1538 1539 _cupsGlobalLock(); 1540 if (initialized) 1541 { 1542 _cupsGlobalUnlock(); 1543 return; 1544 } 1545 1546#ifdef WIN32 1547 WSAStartup(MAKEWORD(2,2), &winsockdata); 1548 1549#elif !defined(SO_NOSIGPIPE) 1550 /* 1551 * Ignore SIGPIPE signals... 1552 */ 1553 1554# ifdef HAVE_SIGSET 1555 sigset(SIGPIPE, SIG_IGN); 1556 1557# elif defined(HAVE_SIGACTION) 1558 struct sigaction action; /* POSIX sigaction data */ 1559 1560 1561 memset(&action, 0, sizeof(action)); 1562 action.sa_handler = SIG_IGN; 1563 sigaction(SIGPIPE, &action, NULL); 1564 1565# else 1566 signal(SIGPIPE, SIG_IGN); 1567# endif /* !SO_NOSIGPIPE */ 1568#endif /* WIN32 */ 1569 1570# ifdef HAVE_SSL 1571 _httpTLSInitialize(); 1572# endif /* HAVE_SSL */ 1573 1574 initialized = 1; 1575 _cupsGlobalUnlock(); 1576} 1577 1578 1579/* 1580 * 'httpIsChunked()' - Report whether a message body is chunked. 1581 * 1582 * This function returns non-zero if the message body is composed of 1583 * variable-length chunks. 1584 * 1585 * @since CUPS 2.0/OS 10.10@ 1586 */ 1587 1588int /* O - 1 if chunked, 0 if not */ 1589httpIsChunked(http_t *http) /* I - HTTP connection */ 1590{ 1591 return (http ? http->data_encoding == HTTP_ENCODING_CHUNKED : 0); 1592} 1593 1594 1595/* 1596 * 'httpIsEncrypted()' - Report whether a connection is encrypted. 1597 * 1598 * This function returns non-zero if the connection is currently encrypted. 1599 * 1600 * @since CUPS 2.0/OS 10.10@ 1601 */ 1602 1603int /* O - 1 if encrypted, 0 if not */ 1604httpIsEncrypted(http_t *http) /* I - HTTP connection */ 1605{ 1606 return (http ? http->tls != NULL : 0); 1607} 1608 1609 1610/* 1611 * 'httpOptions()' - Send an OPTIONS request to the server. 1612 */ 1613 1614int /* O - Status of call (0 = success) */ 1615httpOptions(http_t *http, /* I - HTTP connection */ 1616 const char *uri) /* I - URI for options */ 1617{ 1618 return (http_send(http, HTTP_STATE_OPTIONS, uri)); 1619} 1620 1621 1622/* 1623 * 'httpPeek()' - Peek at data from a HTTP connection. 1624 * 1625 * This function copies available data from the given HTTP connection, reading 1626 * a buffer as needed. The data is still available for reading using 1627 * @link httpRead@ or @link httpRead2@. 1628 * 1629 * For non-blocking connections the usual timeouts apply. 1630 * 1631 * @since CUPS 1.7/OS X 10.9@ 1632 */ 1633 1634ssize_t /* O - Number of bytes copied */ 1635httpPeek(http_t *http, /* I - HTTP connection */ 1636 char *buffer, /* I - Buffer for data */ 1637 size_t length) /* I - Maximum number of bytes */ 1638{ 1639 ssize_t bytes; /* Bytes read */ 1640 char len[32]; /* Length string */ 1641 1642 1643 DEBUG_printf(("httpPeek(http=%p, buffer=%p, length=" CUPS_LLFMT ")", 1644 http, buffer, CUPS_LLCAST length)); 1645 1646 if (http == NULL || buffer == NULL) 1647 return (-1); 1648 1649 http->activity = time(NULL); 1650 http->error = 0; 1651 1652 if (length <= 0) 1653 return (0); 1654 1655 if (http->data_encoding == HTTP_ENCODING_CHUNKED && 1656 http->data_remaining <= 0) 1657 { 1658 DEBUG_puts("2httpPeek: Getting chunk length..."); 1659 1660 if (httpGets(len, sizeof(len), http) == NULL) 1661 { 1662 DEBUG_puts("1httpPeek: Could not get length!"); 1663 return (0); 1664 } 1665 1666 if (!len[0]) 1667 { 1668 DEBUG_puts("1httpPeek: Blank chunk length, trying again..."); 1669 if (!httpGets(len, sizeof(len), http)) 1670 { 1671 DEBUG_puts("1httpPeek: Could not get chunk length."); 1672 return (0); 1673 } 1674 } 1675 1676 http->data_remaining = strtoll(len, NULL, 16); 1677 1678 if (http->data_remaining < 0) 1679 { 1680 DEBUG_puts("1httpPeek: Negative chunk length!"); 1681 return (0); 1682 } 1683 } 1684 1685 DEBUG_printf(("2httpPeek: data_remaining=" CUPS_LLFMT, 1686 CUPS_LLCAST http->data_remaining)); 1687 1688 if (http->data_remaining <= 0 && http->data_encoding != HTTP_ENCODING_FIELDS) 1689 { 1690 /* 1691 * A zero-length chunk ends a transfer; unless we are reading POST 1692 * data, go idle... 1693 */ 1694 1695#ifdef HAVE_LIBZ 1696 if (http->coding >= _HTTP_CODING_GUNZIP) 1697 http_content_coding_finish(http); 1698#endif /* HAVE_LIBZ */ 1699 1700 if (http->data_encoding == HTTP_ENCODING_CHUNKED) 1701 httpGets(len, sizeof(len), http); 1702 1703 if (http->state == HTTP_STATE_POST_RECV) 1704 http->state ++; 1705 else 1706 http->state = HTTP_STATE_STATUS; 1707 1708 DEBUG_printf(("1httpPeek: 0-length chunk, set state to %s.", 1709 httpStateString(http->state))); 1710 1711 /* 1712 * Prevent future reads for this request... 1713 */ 1714 1715 http->data_encoding = HTTP_ENCODING_FIELDS; 1716 1717 return (0); 1718 } 1719 else if (length > (size_t)http->data_remaining) 1720 length = (size_t)http->data_remaining; 1721 1722#ifdef HAVE_LIBZ 1723 if (http->used == 0 && 1724 (http->coding == _HTTP_CODING_IDENTITY || 1725 (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0))) 1726#else 1727 if (http->used == 0) 1728#endif /* HAVE_LIBZ */ 1729 { 1730 /* 1731 * Buffer small reads for better performance... 1732 */ 1733 1734 ssize_t buflen; /* Length of read for buffer */ 1735 1736 if (!http->blocking) 1737 { 1738 while (!httpWait(http, http->wait_value)) 1739 { 1740 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 1741 continue; 1742 1743 return (0); 1744 } 1745 } 1746 1747 if ((size_t)http->data_remaining > sizeof(http->buffer)) 1748 buflen = sizeof(http->buffer); 1749 else 1750 buflen = (ssize_t)http->data_remaining; 1751 1752 DEBUG_printf(("2httpPeek: Reading %d bytes into buffer.", (int)buflen)); 1753 bytes = http_read(http, http->buffer, (size_t)buflen); 1754 1755 DEBUG_printf(("2httpPeek: Read " CUPS_LLFMT " bytes into buffer.", 1756 CUPS_LLCAST bytes)); 1757 if (bytes > 0) 1758 { 1759#ifdef DEBUG 1760 http_debug_hex("httpPeek", http->buffer, (int)bytes); 1761#endif /* DEBUG */ 1762 1763 http->used = (int)bytes; 1764 } 1765 } 1766 1767#ifdef HAVE_LIBZ 1768 if (http->coding >= _HTTP_CODING_GUNZIP) 1769 { 1770# ifdef HAVE_INFLATECOPY 1771 int zerr; /* Decompressor error */ 1772 z_stream stream; /* Copy of decompressor stream */ 1773 1774 if (http->used > 0 && http->stream.avail_in < HTTP_MAX_BUFFER) 1775 { 1776 size_t buflen = buflen = HTTP_MAX_BUFFER - http->stream.avail_in; 1777 /* Number of bytes to copy */ 1778 1779 if (http->stream.avail_in > 0 && 1780 http->stream.next_in > http->sbuffer) 1781 memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in); 1782 1783 http->stream.next_in = http->sbuffer; 1784 1785 if (buflen > (size_t)http->data_remaining) 1786 buflen = (size_t)http->data_remaining; 1787 1788 if (buflen > (size_t)http->used) 1789 buflen = (size_t)http->used; 1790 1791 DEBUG_printf(("1httpPeek: Copying %d more bytes of data into " 1792 "decompression buffer.", (int)buflen)); 1793 1794 memcpy(http->sbuffer + http->stream.avail_in, http->buffer, buflen); 1795 http->stream.avail_in += buflen; 1796 http->used -= (int)buflen; 1797 http->data_remaining -= (off_t)buflen; 1798 1799 if (http->used > 0) 1800 memmove(http->buffer, http->buffer + buflen, (size_t)http->used); 1801 } 1802 1803 DEBUG_printf(("2httpPeek: length=%d, avail_in=%d", (int)length, 1804 (int)http->stream.avail_in)); 1805 1806 if (inflateCopy(&stream, &(http->stream)) != Z_OK) 1807 { 1808 DEBUG_puts("2httpPeek: Unable to copy decompressor stream."); 1809 http->error = ENOMEM; 1810 return (-1); 1811 } 1812 1813 stream.next_out = (Bytef *)buffer; 1814 stream.avail_out = (uInt)length; 1815 1816 zerr = inflate(&stream, Z_SYNC_FLUSH); 1817 inflateEnd(&stream); 1818 1819 if (zerr < Z_OK) 1820 { 1821 DEBUG_printf(("2httpPeek: zerr=%d", zerr)); 1822#ifdef DEBUG 1823 http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)http->stream.avail_in); 1824#endif /* DEBUG */ 1825 1826 http->error = EIO; 1827 return (-1); 1828 } 1829 1830 bytes = (ssize_t)(length - http->stream.avail_out); 1831 1832# else 1833 DEBUG_puts("2httpPeek: No inflateCopy on this platform, httpPeek does not " 1834 "work with compressed streams."); 1835 return (-1); 1836# endif /* HAVE_INFLATECOPY */ 1837 } 1838 else 1839#endif /* HAVE_LIBZ */ 1840 if (http->used > 0) 1841 { 1842 if (length > (size_t)http->used) 1843 length = (size_t)http->used; 1844 1845 bytes = (ssize_t)length; 1846 1847 DEBUG_printf(("2httpPeek: grabbing %d bytes from input buffer...", 1848 (int)bytes)); 1849 1850 memcpy(buffer, http->buffer, length); 1851 } 1852 else 1853 bytes = 0; 1854 1855 if (bytes < 0) 1856 { 1857#ifdef WIN32 1858 if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) 1859 bytes = 0; 1860 else 1861 http->error = WSAGetLastError(); 1862#else 1863 if (errno == EINTR || errno == EAGAIN) 1864 bytes = 0; 1865 else 1866 http->error = errno; 1867#endif /* WIN32 */ 1868 } 1869 else if (bytes == 0) 1870 { 1871 http->error = EPIPE; 1872 return (0); 1873 } 1874 1875 return (bytes); 1876} 1877 1878 1879/* 1880 * 'httpPost()' - Send a POST request to the server. 1881 */ 1882 1883int /* O - Status of call (0 = success) */ 1884httpPost(http_t *http, /* I - HTTP connection */ 1885 const char *uri) /* I - URI for post */ 1886{ 1887 return (http_send(http, HTTP_STATE_POST, uri)); 1888} 1889 1890 1891/* 1892 * 'httpPrintf()' - Print a formatted string to a HTTP connection. 1893 * 1894 * @private@ 1895 */ 1896 1897int /* O - Number of bytes written */ 1898httpPrintf(http_t *http, /* I - HTTP connection */ 1899 const char *format, /* I - printf-style format string */ 1900 ...) /* I - Additional args as needed */ 1901{ 1902 ssize_t bytes; /* Number of bytes to write */ 1903 char buf[16384]; /* Buffer for formatted string */ 1904 va_list ap; /* Variable argument pointer */ 1905 1906 1907 DEBUG_printf(("2httpPrintf(http=%p, format=\"%s\", ...)", http, format)); 1908 1909 va_start(ap, format); 1910 bytes = vsnprintf(buf, sizeof(buf), format, ap); 1911 va_end(ap); 1912 1913 DEBUG_printf(("3httpPrintf: (" CUPS_LLFMT " bytes) %s", CUPS_LLCAST bytes, buf)); 1914 1915 if (http->data_encoding == HTTP_ENCODING_FIELDS) 1916 return ((int)httpWrite2(http, buf, (size_t)bytes)); 1917 else 1918 { 1919 if (http->wused) 1920 { 1921 DEBUG_puts("4httpPrintf: flushing existing data..."); 1922 1923 if (httpFlushWrite(http) < 0) 1924 return (-1); 1925 } 1926 1927 return ((int)http_write(http, buf, (size_t)bytes)); 1928 } 1929} 1930 1931 1932/* 1933 * 'httpPut()' - Send a PUT request to the server. 1934 */ 1935 1936int /* O - Status of call (0 = success) */ 1937httpPut(http_t *http, /* I - HTTP connection */ 1938 const char *uri) /* I - URI to put */ 1939{ 1940 DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", http, uri)); 1941 return (http_send(http, HTTP_STATE_PUT, uri)); 1942} 1943 1944 1945/* 1946 * 'httpRead()' - Read data from a HTTP connection. 1947 * 1948 * This function is deprecated. Use the httpRead2() function which can 1949 * read more than 2GB of data. 1950 * 1951 * @deprecated@ 1952 */ 1953 1954int /* O - Number of bytes read */ 1955httpRead(http_t *http, /* I - HTTP connection */ 1956 char *buffer, /* I - Buffer for data */ 1957 int length) /* I - Maximum number of bytes */ 1958{ 1959 return ((int)httpRead2(http, buffer, (size_t)length)); 1960} 1961 1962 1963/* 1964 * 'httpRead2()' - Read data from a HTTP connection. 1965 * 1966 * @since CUPS 1.2/OS X 10.5@ 1967 */ 1968 1969ssize_t /* O - Number of bytes read */ 1970httpRead2(http_t *http, /* I - HTTP connection */ 1971 char *buffer, /* I - Buffer for data */ 1972 size_t length) /* I - Maximum number of bytes */ 1973{ 1974 ssize_t bytes; /* Bytes read */ 1975 1976 1977#ifdef HAVE_LIBZ 1978 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT 1979 ") coding=%d data_encoding=%d data_remaining=" CUPS_LLFMT, 1980 http, buffer, CUPS_LLCAST length, 1981 http->coding, 1982 http->data_encoding, CUPS_LLCAST http->data_remaining)); 1983#else 1984 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT 1985 ") data_encoding=%d data_remaining=" CUPS_LLFMT, 1986 http, buffer, CUPS_LLCAST length, 1987 http->data_encoding, CUPS_LLCAST http->data_remaining)); 1988#endif /* HAVE_LIBZ */ 1989 1990 if (http == NULL || buffer == NULL) 1991 return (-1); 1992 1993 http->activity = time(NULL); 1994 http->error = 0; 1995 1996 if (length <= 0) 1997 return (0); 1998 1999#ifdef HAVE_LIBZ 2000 if (http->coding >= _HTTP_CODING_GUNZIP) 2001 { 2002 do 2003 { 2004 if (http->stream.avail_in > 0) 2005 { 2006 int zerr; /* Decompressor error */ 2007 2008 DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d", 2009 (int)http->stream.avail_in, (int)length)); 2010 2011 http->stream.next_out = (Bytef *)buffer; 2012 http->stream.avail_out = (uInt)length; 2013 2014 if ((zerr = inflate(&(http->stream), Z_SYNC_FLUSH)) < Z_OK) 2015 { 2016 DEBUG_printf(("2httpRead2: zerr=%d", zerr)); 2017#ifdef DEBUG 2018 http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)http->stream.avail_in); 2019#endif /* DEBUG */ 2020 2021 http->error = EIO; 2022 return (-1); 2023 } 2024 2025 bytes = (ssize_t)(length - http->stream.avail_out); 2026 2027 DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d, bytes=%d", 2028 http->stream.avail_in, http->stream.avail_out, 2029 (int)bytes)); 2030 } 2031 else 2032 bytes = 0; 2033 2034 if (bytes == 0) 2035 { 2036 ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)http->stream.avail_in; 2037 /* Additional bytes for buffer */ 2038 2039 if (buflen > 0) 2040 { 2041 if (http->stream.avail_in > 0 && 2042 http->stream.next_in > http->sbuffer) 2043 memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in); 2044 2045 http->stream.next_in = http->sbuffer; 2046 2047 DEBUG_printf(("1httpRead2: Reading up to %d more bytes of data into " 2048 "decompression buffer.", (int)buflen)); 2049 2050 if (http->data_remaining > 0) 2051 { 2052 if (buflen > http->data_remaining) 2053 buflen = (ssize_t)http->data_remaining; 2054 2055 bytes = http_read_buffered(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen); 2056 } 2057 else if (http->data_encoding == HTTP_ENCODING_CHUNKED) 2058 bytes = http_read_chunk(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen); 2059 else 2060 bytes = 0; 2061 2062 if (bytes < 0) 2063 return (bytes); 2064 else if (bytes == 0) 2065 break; 2066 2067 DEBUG_printf(("1httpRead2: Adding " CUPS_LLFMT " bytes to " 2068 "decompression buffer.", CUPS_LLCAST bytes)); 2069 2070 http->data_remaining -= bytes; 2071 http->stream.avail_in += (uInt)bytes; 2072 2073 if (http->data_remaining <= 0 && 2074 http->data_encoding == HTTP_ENCODING_CHUNKED) 2075 { 2076 /* 2077 * Read the trailing blank line now... 2078 */ 2079 2080 char len[32]; /* Length string */ 2081 2082 httpGets(len, sizeof(len), http); 2083 } 2084 2085 bytes = 0; 2086 } 2087 else 2088 return (0); 2089 } 2090 } 2091 while (bytes == 0); 2092 } 2093 else 2094#endif /* HAVE_LIBZ */ 2095 if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) 2096 { 2097 if ((bytes = http_read_chunk(http, buffer, length)) > 0) 2098 { 2099 http->data_remaining -= bytes; 2100 2101 if (http->data_remaining <= 0) 2102 { 2103 /* 2104 * Read the trailing blank line now... 2105 */ 2106 2107 char len[32]; /* Length string */ 2108 2109 httpGets(len, sizeof(len), http); 2110 } 2111 } 2112 } 2113 else if (http->data_remaining <= 0) 2114 { 2115 /* 2116 * No more data to read... 2117 */ 2118 2119 return (0); 2120 } 2121 else 2122 { 2123 DEBUG_printf(("1httpRead2: Reading up to %d bytes into buffer.", 2124 (int)length)); 2125 2126 if (length > (size_t)http->data_remaining) 2127 length = (size_t)http->data_remaining; 2128 2129 if ((bytes = http_read_buffered(http, buffer, length)) > 0) 2130 { 2131 http->data_remaining -= bytes; 2132 2133 if (http->data_remaining <= 0 && 2134 http->data_encoding == HTTP_ENCODING_CHUNKED) 2135 { 2136 /* 2137 * Read the trailing blank line now... 2138 */ 2139 2140 char len[32]; /* Length string */ 2141 2142 httpGets(len, sizeof(len), http); 2143 } 2144 } 2145 } 2146 2147 if ( 2148#ifdef HAVE_LIBZ 2149 (http->coding == _HTTP_CODING_IDENTITY || 2150 (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0)) && 2151#endif /* HAVE_LIBZ */ 2152 ((http->data_remaining <= 0 && 2153 http->data_encoding == HTTP_ENCODING_LENGTH) || 2154 (http->data_encoding == HTTP_ENCODING_CHUNKED && bytes == 0))) 2155 { 2156#ifdef HAVE_LIBZ 2157 if (http->coding >= _HTTP_CODING_GUNZIP) 2158 http_content_coding_finish(http); 2159#endif /* HAVE_LIBZ */ 2160 2161 if (http->state == HTTP_STATE_POST_RECV) 2162 http->state ++; 2163 else if (http->state == HTTP_STATE_GET_SEND || 2164 http->state == HTTP_STATE_POST_SEND) 2165 http->state = HTTP_STATE_WAITING; 2166 else 2167 http->state = HTTP_STATE_STATUS; 2168 2169 DEBUG_printf(("1httpRead2: End of content, set state to %s.", 2170 httpStateString(http->state))); 2171 } 2172 2173 return (bytes); 2174} 2175 2176 2177/* 2178 * 'httpReadRequest()' - Read a HTTP request from a connection. 2179 * 2180 * @since CUPS 1.7/OS X 10.9@ 2181 */ 2182 2183http_state_t /* O - New state of connection */ 2184httpReadRequest(http_t *http, /* I - HTTP connection */ 2185 char *uri, /* I - URI buffer */ 2186 size_t urilen) /* I - Size of URI buffer */ 2187{ 2188 char line[4096], /* HTTP request line */ 2189 *req_method, /* HTTP request method */ 2190 *req_uri, /* HTTP request URI */ 2191 *req_version; /* HTTP request version number string */ 2192 2193 2194 /* 2195 * Range check input... 2196 */ 2197 2198 DEBUG_printf(("httpReadRequest(http=%p, uri=%p, urilen=" CUPS_LLFMT ")", 2199 http, uri, CUPS_LLCAST urilen)); 2200 2201 if (uri) 2202 *uri = '\0'; 2203 2204 if (!http || !uri || urilen < 1) 2205 { 2206 DEBUG_puts("1httpReadRequest: Bad arguments, returning HTTP_STATE_ERROR."); 2207 return (HTTP_STATE_ERROR); 2208 } 2209 else if (http->state != HTTP_STATE_WAITING) 2210 { 2211 DEBUG_printf(("1httpReadRequest: Bad state %s, returning HTTP_STATE_ERROR.", 2212 httpStateString(http->state))); 2213 return (HTTP_STATE_ERROR); 2214 } 2215 2216 /* 2217 * Reset state... 2218 */ 2219 2220 httpClearFields(http); 2221 2222 http->activity = time(NULL); 2223 http->data_encoding = HTTP_ENCODING_FIELDS; 2224 http->data_remaining = 0; 2225 http->keep_alive = HTTP_KEEPALIVE_OFF; 2226 http->status = HTTP_STATUS_OK; 2227 http->version = HTTP_VERSION_1_1; 2228 2229 /* 2230 * Read a line from the socket... 2231 */ 2232 2233 if (!httpGets(line, sizeof(line), http)) 2234 { 2235 DEBUG_puts("1httpReadRequest: Unable to read, returning HTTP_STATE_ERROR"); 2236 return (HTTP_STATE_ERROR); 2237 } 2238 2239 if (!line[0]) 2240 { 2241 DEBUG_puts("1httpReadRequest: Blank line, returning HTTP_STATE_WAITING"); 2242 return (HTTP_STATE_WAITING); 2243 } 2244 2245 DEBUG_printf(("1httpReadRequest: %s", line)); 2246 2247 /* 2248 * Parse it... 2249 */ 2250 2251 req_method = line; 2252 req_uri = line; 2253 2254 while (*req_uri && !isspace(*req_uri & 255)) 2255 req_uri ++; 2256 2257 if (!*req_uri) 2258 { 2259 DEBUG_puts("1httpReadRequest: No request URI."); 2260 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No request URI."), 1); 2261 return (HTTP_STATE_ERROR); 2262 } 2263 2264 *req_uri++ = '\0'; 2265 2266 while (*req_uri && isspace(*req_uri & 255)) 2267 req_uri ++; 2268 2269 req_version = req_uri; 2270 2271 while (*req_version && !isspace(*req_version & 255)) 2272 req_version ++; 2273 2274 if (!*req_version) 2275 { 2276 DEBUG_puts("1httpReadRequest: No request protocol version."); 2277 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No request protocol version."), 1); 2278 return (HTTP_STATE_ERROR); 2279 } 2280 2281 *req_version++ = '\0'; 2282 2283 while (*req_version && isspace(*req_version & 255)) 2284 req_version ++; 2285 2286 /* 2287 * Validate... 2288 */ 2289 2290 if (!strcmp(req_method, "OPTIONS")) 2291 http->state = HTTP_STATE_OPTIONS; 2292 else if (!strcmp(req_method, "GET")) 2293 http->state = HTTP_STATE_GET; 2294 else if (!strcmp(req_method, "HEAD")) 2295 http->state = HTTP_STATE_HEAD; 2296 else if (!strcmp(req_method, "POST")) 2297 http->state = HTTP_STATE_POST; 2298 else if (!strcmp(req_method, "PUT")) 2299 http->state = HTTP_STATE_PUT; 2300 else if (!strcmp(req_method, "DELETE")) 2301 http->state = HTTP_STATE_DELETE; 2302 else if (!strcmp(req_method, "TRACE")) 2303 http->state = HTTP_STATE_TRACE; 2304 else if (!strcmp(req_method, "CONNECT")) 2305 http->state = HTTP_STATE_CONNECT; 2306 else 2307 { 2308 DEBUG_printf(("1httpReadRequest: Unknown method \"%s\".", req_method)); 2309 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown request method."), 1); 2310 return (HTTP_STATE_UNKNOWN_METHOD); 2311 } 2312 2313 DEBUG_printf(("1httpReadRequest: Set state to %s.", 2314 httpStateString(http->state))); 2315 2316 if (!strcmp(req_version, "HTTP/1.0")) 2317 { 2318 http->version = HTTP_VERSION_1_0; 2319 http->keep_alive = HTTP_KEEPALIVE_OFF; 2320 } 2321 else if (!strcmp(req_version, "HTTP/1.1")) 2322 { 2323 http->version = HTTP_VERSION_1_1; 2324 http->keep_alive = HTTP_KEEPALIVE_ON; 2325 } 2326 else 2327 { 2328 DEBUG_printf(("1httpReadRequest: Unknown version \"%s\".", req_version)); 2329 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown request version."), 1); 2330 return (HTTP_STATE_UNKNOWN_VERSION); 2331 } 2332 2333 DEBUG_printf(("1httpReadRequest: URI is \"%s\".", req_uri)); 2334 strlcpy(uri, req_uri, urilen); 2335 2336 return (http->state); 2337} 2338 2339 2340/* 2341 * 'httpReconnect()' - Reconnect to a HTTP server. 2342 * 2343 * This function is deprecated. Please use the @link httpReconnect2@ function 2344 * instead. 2345 * 2346 * @deprecated@ 2347 */ 2348 2349int /* O - 0 on success, non-zero on failure */ 2350httpReconnect(http_t *http) /* I - HTTP connection */ 2351{ 2352 DEBUG_printf(("httpReconnect(http=%p)", http)); 2353 2354 return (httpReconnect2(http, 30000, NULL)); 2355} 2356 2357 2358/* 2359 * 'httpReconnect2()' - Reconnect to a HTTP server with timeout and optional 2360 * cancel. 2361 */ 2362 2363int /* O - 0 on success, non-zero on failure */ 2364httpReconnect2(http_t *http, /* I - HTTP connection */ 2365 int msec, /* I - Timeout in milliseconds */ 2366 int *cancel) /* I - Pointer to "cancel" variable */ 2367{ 2368 http_addrlist_t *addr; /* Connected address */ 2369#ifdef DEBUG 2370 http_addrlist_t *current; /* Current address */ 2371 char temp[256]; /* Temporary address string */ 2372#endif /* DEBUG */ 2373 2374 2375 DEBUG_printf(("httpReconnect2(http=%p, msec=%d, cancel=%p)", http, msec, 2376 cancel)); 2377 2378 if (!http) 2379 { 2380 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); 2381 return (-1); 2382 } 2383 2384#ifdef HAVE_SSL 2385 if (http->tls) 2386 { 2387 DEBUG_puts("2httpReconnect2: Shutting down SSL/TLS..."); 2388 _httpTLSStop(http); 2389 } 2390#endif /* HAVE_SSL */ 2391 2392 /* 2393 * Close any previously open socket... 2394 */ 2395 2396 if (http->fd >= 0) 2397 { 2398 DEBUG_printf(("2httpReconnect2: Closing socket %d...", http->fd)); 2399 2400 httpAddrClose(NULL, http->fd); 2401 2402 http->fd = -1; 2403 } 2404 2405 /* 2406 * Reset all state (except fields, which may be reused)... 2407 */ 2408 2409 http->state = HTTP_STATE_WAITING; 2410 http->version = HTTP_VERSION_1_1; 2411 http->keep_alive = HTTP_KEEPALIVE_OFF; 2412 memset(&http->_hostaddr, 0, sizeof(http->_hostaddr)); 2413 http->data_encoding = HTTP_ENCODING_FIELDS; 2414 http->_data_remaining = 0; 2415 http->used = 0; 2416 http->data_remaining = 0; 2417 http->hostaddr = NULL; 2418 http->wused = 0; 2419 2420 /* 2421 * Connect to the server... 2422 */ 2423 2424#ifdef DEBUG 2425 for (current = http->addrlist; current; current = current->next) 2426 DEBUG_printf(("2httpReconnect2: Address %s:%d", 2427 httpAddrString(&(current->addr), temp, sizeof(temp)), 2428 httpAddrPort(&(current->addr)))); 2429#endif /* DEBUG */ 2430 2431 if ((addr = httpAddrConnect2(http->addrlist, &(http->fd), msec, 2432 cancel)) == NULL) 2433 { 2434 /* 2435 * Unable to connect... 2436 */ 2437 2438#ifdef WIN32 2439 http->error = WSAGetLastError(); 2440#else 2441 http->error = errno; 2442#endif /* WIN32 */ 2443 http->status = HTTP_STATUS_ERROR; 2444 2445 DEBUG_printf(("1httpReconnect2: httpAddrConnect failed: %s", 2446 strerror(http->error))); 2447 2448 return (-1); 2449 } 2450 2451 DEBUG_printf(("2httpReconnect2: New socket=%d", http->fd)); 2452 2453 if (http->timeout_value > 0) 2454 http_set_timeout(http->fd, http->timeout_value); 2455 2456 http->hostaddr = &(addr->addr); 2457 http->error = 0; 2458 2459#ifdef HAVE_SSL 2460 if (http->encryption == HTTP_ENCRYPTION_ALWAYS) 2461 { 2462 /* 2463 * Always do encryption via SSL. 2464 */ 2465 2466 if (_httpTLSStart(http) != 0) 2467 { 2468 httpAddrClose(NULL, http->fd); 2469 2470 return (-1); 2471 } 2472 } 2473 else if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls_upgrade) 2474 return (http_tls_upgrade(http)); 2475#endif /* HAVE_SSL */ 2476 2477 DEBUG_printf(("1httpReconnect2: Connected to %s:%d...", 2478 httpAddrString(http->hostaddr, temp, sizeof(temp)), 2479 httpAddrPort(http->hostaddr))); 2480 2481 return (0); 2482} 2483 2484 2485/* 2486 * 'httpSetAuthString()' - Set the current authorization string. 2487 * 2488 * This function just stores a copy of the current authorization string in 2489 * the HTTP connection object. You must still call httpSetField() to set 2490 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(), 2491 * httpHead(), httpOptions(), httpPost, or httpPut(). 2492 * 2493 * @since CUPS 1.3/OS X 10.5@ 2494 */ 2495 2496void 2497httpSetAuthString(http_t *http, /* I - HTTP connection */ 2498 const char *scheme, /* I - Auth scheme (NULL to clear it) */ 2499 const char *data) /* I - Auth data (NULL for none) */ 2500{ 2501 /* 2502 * Range check input... 2503 */ 2504 2505 if (!http) 2506 return; 2507 2508 if (http->authstring && http->authstring != http->_authstring) 2509 free(http->authstring); 2510 2511 http->authstring = http->_authstring; 2512 2513 if (scheme) 2514 { 2515 /* 2516 * Set the current authorization string... 2517 */ 2518 2519 size_t len = strlen(scheme) + (data ? strlen(data) + 1 : 0) + 1; 2520 char *temp; 2521 2522 if (len > sizeof(http->_authstring)) 2523 { 2524 if ((temp = malloc(len)) == NULL) 2525 len = sizeof(http->_authstring); 2526 else 2527 http->authstring = temp; 2528 } 2529 2530 if (data) 2531 snprintf(http->authstring, len, "%s %s", scheme, data); 2532 else 2533 strlcpy(http->authstring, scheme, len); 2534 } 2535 else 2536 { 2537 /* 2538 * Clear the current authorization string... 2539 */ 2540 2541 http->_authstring[0] = '\0'; 2542 } 2543} 2544 2545 2546/* 2547 * 'httpSetCredentials()' - Set the credentials associated with an encrypted 2548 * connection. 2549 * 2550 * @since CUPS 1.5/OS X 10.7@ 2551 */ 2552 2553int /* O - Status of call (0 = success) */ 2554httpSetCredentials(http_t *http, /* I - HTTP connection */ 2555 cups_array_t *credentials) /* I - Array of credentials */ 2556{ 2557 if (!http || cupsArrayCount(credentials) < 1) 2558 return (-1); 2559 2560#ifdef HAVE_SSL 2561 _httpFreeCredentials(http->tls_credentials); 2562 2563 http->tls_credentials = _httpCreateCredentials(credentials); 2564#endif /* HAVE_SSL */ 2565 2566 return (http->tls_credentials ? 0 : -1); 2567} 2568 2569 2570/* 2571 * 'httpSetCookie()' - Set the cookie value(s). 2572 * 2573 * @since CUPS 1.1.19/OS X 10.3@ 2574 */ 2575 2576void 2577httpSetCookie(http_t *http, /* I - Connection */ 2578 const char *cookie) /* I - Cookie string */ 2579{ 2580 if (!http) 2581 return; 2582 2583 if (http->cookie) 2584 free(http->cookie); 2585 2586 if (cookie) 2587 http->cookie = strdup(cookie); 2588 else 2589 http->cookie = NULL; 2590} 2591 2592 2593/* 2594 * 'httpSetDefaultField()' - Set the default value of an HTTP header. 2595 * 2596 * Currently only @code HTTP_FIELD_ACCEPT_ENCODING@, @code HTTP_FIELD_SERVER@, 2597 * and @code HTTP_FIELD_USER_AGENT@ can be set. 2598 * 2599 * @since CUPS 1.7/OS X 10.9@ 2600 */ 2601 2602void 2603httpSetDefaultField(http_t *http, /* I - HTTP connection */ 2604 http_field_t field, /* I - Field index */ 2605 const char *value)/* I - Value */ 2606{ 2607 DEBUG_printf(("httpSetDefaultField(http=%p, field=%d(%s), value=\"%s\")", 2608 http, field, http_fields[field], value)); 2609 2610 if (!http) 2611 return; 2612 2613 switch (field) 2614 { 2615 case HTTP_FIELD_ACCEPT_ENCODING : 2616 if (http->default_accept_encoding) 2617 _cupsStrFree(http->default_accept_encoding); 2618 2619 http->default_accept_encoding = value ? _cupsStrAlloc(value) : NULL; 2620 break; 2621 2622 case HTTP_FIELD_SERVER : 2623 if (http->default_server) 2624 _cupsStrFree(http->default_server); 2625 2626 http->default_server = value ? _cupsStrAlloc(value) : NULL; 2627 break; 2628 2629 case HTTP_FIELD_USER_AGENT : 2630 if (http->default_user_agent) 2631 _cupsStrFree(http->default_user_agent); 2632 2633 http->default_user_agent = value ? _cupsStrAlloc(value) : NULL; 2634 break; 2635 2636 default : 2637 DEBUG_puts("1httpSetDefaultField: Ignored."); 2638 break; 2639 } 2640} 2641 2642 2643/* 2644 * 'httpSetExpect()' - Set the Expect: header in a request. 2645 * 2646 * Currently only @code HTTP_STATUS_CONTINUE@ is supported for the "expect" 2647 * argument. 2648 * 2649 * @since CUPS 1.2/OS X 10.5@ 2650 */ 2651 2652void 2653httpSetExpect(http_t *http, /* I - HTTP connection */ 2654 http_status_t expect) /* I - HTTP status to expect 2655 (@code HTTP_STATUS_CONTINUE@) */ 2656{ 2657 DEBUG_printf(("httpSetExpect(http=%p, expect=%d)", http, expect)); 2658 2659 if (http) 2660 http->expect = expect; 2661} 2662 2663 2664/* 2665 * 'httpSetField()' - Set the value of an HTTP header. 2666 */ 2667 2668void 2669httpSetField(http_t *http, /* I - HTTP connection */ 2670 http_field_t field, /* I - Field index */ 2671 const char *value) /* I - Value */ 2672{ 2673 DEBUG_printf(("httpSetField(http=%p, field=%d(%s), value=\"%s\")", http, 2674 field, http_fields[field], value)); 2675 2676 if (http == NULL || 2677 field < HTTP_FIELD_ACCEPT_LANGUAGE || 2678 field >= HTTP_FIELD_MAX || 2679 value == NULL) 2680 return; 2681 2682 switch (field) 2683 { 2684 case HTTP_FIELD_ACCEPT_ENCODING : 2685 if (http->accept_encoding) 2686 _cupsStrFree(http->accept_encoding); 2687 2688 http->accept_encoding = _cupsStrAlloc(value); 2689 break; 2690 2691 case HTTP_FIELD_ALLOW : 2692 if (http->allow) 2693 _cupsStrFree(http->allow); 2694 2695 http->allow = _cupsStrAlloc(value); 2696 break; 2697 2698 case HTTP_FIELD_SERVER : 2699 if (http->server) 2700 _cupsStrFree(http->server); 2701 2702 http->server = _cupsStrAlloc(value); 2703 break; 2704 2705 default : 2706 strlcpy(http->fields[field], value, HTTP_MAX_VALUE); 2707 break; 2708 } 2709 2710 if (field == HTTP_FIELD_AUTHORIZATION) 2711 { 2712 /* 2713 * Special case for Authorization: as its contents can be 2714 * longer than HTTP_MAX_VALUE 2715 */ 2716 2717 if (http->field_authorization) 2718 free(http->field_authorization); 2719 2720 http->field_authorization = strdup(value); 2721 } 2722 else if (field == HTTP_FIELD_HOST) 2723 { 2724 /* 2725 * Special-case for Host: as we don't want a trailing "." on the hostname and 2726 * need to bracket IPv6 numeric addresses. 2727 */ 2728 2729 char *ptr = strchr(value, ':'); 2730 2731 if (value[0] != '[' && ptr && strchr(ptr + 1, ':')) 2732 { 2733 /* 2734 * Bracket IPv6 numeric addresses... 2735 * 2736 * This is slightly inefficient (basically copying twice), but is an edge 2737 * case and not worth optimizing... 2738 */ 2739 2740 snprintf(http->fields[HTTP_FIELD_HOST], 2741 sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value); 2742 } 2743 else 2744 { 2745 /* 2746 * Check for a trailing dot on the hostname... 2747 */ 2748 2749 ptr = http->fields[HTTP_FIELD_HOST]; 2750 2751 if (*ptr) 2752 { 2753 ptr += strlen(ptr) - 1; 2754 2755 if (*ptr == '.') 2756 *ptr = '\0'; 2757 } 2758 } 2759 } 2760#ifdef HAVE_LIBZ 2761 else if (field == HTTP_FIELD_CONTENT_ENCODING && 2762 http->data_encoding != HTTP_ENCODING_FIELDS) 2763 { 2764 DEBUG_puts("1httpSetField: Calling http_content_coding_start."); 2765 http_content_coding_start(http, value); 2766 } 2767#endif /* HAVE_LIBZ */ 2768} 2769 2770 2771/* 2772 * 'httpSetKeepAlive()' - Set the current Keep-Alive state of a connection. 2773 * 2774 * @since CUPS 2.0/OS 10.10@ 2775 */ 2776 2777void 2778httpSetKeepAlive( 2779 http_t *http, /* I - HTTP connection */ 2780 http_keepalive_t keep_alive) /* I - New Keep-Alive value */ 2781{ 2782 if (http) 2783 http->keep_alive = keep_alive; 2784} 2785 2786 2787/* 2788 * 'httpSetLength()' - Set the content-length and content-encoding. 2789 * 2790 * @since CUPS 1.2/OS X 10.5@ 2791 */ 2792 2793void 2794httpSetLength(http_t *http, /* I - HTTP connection */ 2795 size_t length) /* I - Length (0 for chunked) */ 2796{ 2797 DEBUG_printf(("httpSetLength(http=%p, length=" CUPS_LLFMT ")", http, 2798 CUPS_LLCAST length)); 2799 2800 if (!http) 2801 return; 2802 2803 if (!length) 2804 { 2805 strlcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked", 2806 HTTP_MAX_VALUE); 2807 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0'; 2808 } 2809 else 2810 { 2811 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0'; 2812 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE, 2813 CUPS_LLFMT, CUPS_LLCAST length); 2814 } 2815} 2816 2817 2818/* 2819 * 'httpSetTimeout()' - Set read/write timeouts and an optional callback. 2820 * 2821 * The optional timeout callback receives both the HTTP connection and a user 2822 * data pointer and must return 1 to continue or 0 to error (time) out. 2823 * 2824 * @since CUPS 1.5/OS X 10.7@ 2825 */ 2826 2827void 2828httpSetTimeout( 2829 http_t *http, /* I - HTTP connection */ 2830 double timeout, /* I - Number of seconds for timeout, 2831 must be greater than 0 */ 2832 http_timeout_cb_t cb, /* I - Callback function or NULL */ 2833 void *user_data) /* I - User data pointer */ 2834{ 2835 if (!http || timeout <= 0.0) 2836 return; 2837 2838 http->timeout_cb = cb; 2839 http->timeout_data = user_data; 2840 http->timeout_value = timeout; 2841 2842 if (http->fd >= 0) 2843 http_set_timeout(http->fd, timeout); 2844 2845 http_set_wait(http); 2846} 2847 2848 2849/* 2850 * 'httpShutdown()' - Shutdown one side of an HTTP connection. 2851 * 2852 * @since CUPS 2.0/OS 10.10@ 2853 */ 2854 2855void 2856httpShutdown(http_t *http) /* I - HTTP connection */ 2857{ 2858 if (!http || http->fd < 0) 2859 return; 2860 2861#ifdef HAVE_SSL 2862 if (http->tls) 2863 _httpTLSStop(http); 2864#endif /* HAVE_SSL */ 2865 2866#ifdef WIN32 2867 shutdown(http->fd, SD_RECEIVE); /* Microsoft-ism... */ 2868#else 2869 shutdown(http->fd, SHUT_RD); 2870#endif /* WIN32 */ 2871} 2872 2873 2874/* 2875 * 'httpTrace()' - Send an TRACE request to the server. 2876 */ 2877 2878int /* O - Status of call (0 = success) */ 2879httpTrace(http_t *http, /* I - HTTP connection */ 2880 const char *uri) /* I - URI for trace */ 2881{ 2882 return (http_send(http, HTTP_STATE_TRACE, uri)); 2883} 2884 2885 2886/* 2887 * '_httpUpdate()' - Update the current HTTP status for incoming data. 2888 * 2889 * Note: Unlike httpUpdate(), this function does not flush pending write data 2890 * and only retrieves a single status line from the HTTP connection. 2891 */ 2892 2893int /* O - 1 to continue, 0 to stop */ 2894_httpUpdate(http_t *http, /* I - HTTP connection */ 2895 http_status_t *status) /* O - Current HTTP status */ 2896{ 2897 char line[32768], /* Line from connection... */ 2898 *value; /* Pointer to value on line */ 2899 http_field_t field; /* Field index */ 2900 int major, minor; /* HTTP version numbers */ 2901 2902 2903 DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", http, status, 2904 httpStateString(http->state))); 2905 2906 /* 2907 * Grab a single line from the connection... 2908 */ 2909 2910 if (!httpGets(line, sizeof(line), http)) 2911 { 2912 *status = HTTP_STATUS_ERROR; 2913 return (0); 2914 } 2915 2916 DEBUG_printf(("2_httpUpdate: Got \"%s\"", line)); 2917 2918 if (line[0] == '\0') 2919 { 2920 /* 2921 * Blank line means the start of the data section (if any). Return 2922 * the result code, too... 2923 * 2924 * If we get status 100 (HTTP_STATUS_CONTINUE), then we *don't* change 2925 * states. Instead, we just return HTTP_STATUS_CONTINUE to the caller and 2926 * keep on tryin'... 2927 */ 2928 2929 if (http->status == HTTP_STATUS_CONTINUE) 2930 { 2931 *status = http->status; 2932 return (0); 2933 } 2934 2935 if (http->status < HTTP_STATUS_BAD_REQUEST) 2936 http->digest_tries = 0; 2937 2938#ifdef HAVE_SSL 2939 if (http->status == HTTP_STATUS_SWITCHING_PROTOCOLS && !http->tls) 2940 { 2941 if (_httpTLSStart(http) != 0) 2942 { 2943 httpAddrClose(NULL, http->fd); 2944 2945 *status = http->status = HTTP_STATUS_ERROR; 2946 return (0); 2947 } 2948 2949 *status = HTTP_STATUS_CONTINUE; 2950 return (0); 2951 } 2952#endif /* HAVE_SSL */ 2953 2954 if (http_set_length(http) < 0) 2955 { 2956 DEBUG_puts("1_httpUpdate: Bad Content-Length."); 2957 http->error = EINVAL; 2958 http->status = *status = HTTP_STATUS_ERROR; 2959 return (0); 2960 } 2961 2962 switch (http->state) 2963 { 2964 case HTTP_STATE_GET : 2965 case HTTP_STATE_POST : 2966 case HTTP_STATE_POST_RECV : 2967 case HTTP_STATE_PUT : 2968 http->state ++; 2969 2970 DEBUG_printf(("1_httpUpdate: Set state to %s.", 2971 httpStateString(http->state))); 2972 2973 case HTTP_STATE_POST_SEND : 2974 case HTTP_STATE_HEAD : 2975 break; 2976 2977 default : 2978 http->state = HTTP_STATE_WAITING; 2979 2980 DEBUG_puts("1_httpUpdate: Reset state to HTTP_STATE_WAITING."); 2981 break; 2982 } 2983 2984#ifdef HAVE_LIBZ 2985 DEBUG_puts("1_httpUpdate: Calling http_content_coding_start."); 2986 http_content_coding_start(http, 2987 httpGetField(http, HTTP_FIELD_CONTENT_ENCODING)); 2988#endif /* HAVE_LIBZ */ 2989 2990 *status = http->status; 2991 return (0); 2992 } 2993 else if (!strncmp(line, "HTTP/", 5)) 2994 { 2995 /* 2996 * Got the beginning of a response... 2997 */ 2998 2999 int intstatus; /* Status value as an integer */ 3000 3001 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &intstatus) != 3) 3002 { 3003 *status = http->status = HTTP_STATUS_ERROR; 3004 return (0); 3005 } 3006 3007 httpClearFields(http); 3008 3009 http->version = (http_version_t)(major * 100 + minor); 3010 *status = http->status = (http_status_t)intstatus; 3011 } 3012 else if ((value = strchr(line, ':')) != NULL) 3013 { 3014 /* 3015 * Got a value... 3016 */ 3017 3018 *value++ = '\0'; 3019 while (_cups_isspace(*value)) 3020 value ++; 3021 3022 DEBUG_printf(("1_httpUpdate: Header %s: %s", line, value)); 3023 3024 /* 3025 * Be tolerants of servers that send unknown attribute fields... 3026 */ 3027 3028 if (!_cups_strcasecmp(line, "expect")) 3029 { 3030 /* 3031 * "Expect: 100-continue" or similar... 3032 */ 3033 3034 http->expect = (http_status_t)atoi(value); 3035 } 3036 else if (!_cups_strcasecmp(line, "cookie")) 3037 { 3038 /* 3039 * "Cookie: name=value[; name=value ...]" - replaces previous cookies... 3040 */ 3041 3042 httpSetCookie(http, value); 3043 } 3044 else if ((field = httpFieldValue(line)) != HTTP_FIELD_UNKNOWN) 3045 httpSetField(http, field, value); 3046#ifdef DEBUG 3047 else 3048 DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line)); 3049#endif /* DEBUG */ 3050 } 3051 else 3052 { 3053 DEBUG_printf(("1_httpUpdate: Bad response line \"%s\"!", line)); 3054 http->error = EINVAL; 3055 http->status = *status = HTTP_STATUS_ERROR; 3056 return (0); 3057 } 3058 3059 return (1); 3060} 3061 3062 3063/* 3064 * 'httpUpdate()' - Update the current HTTP state for incoming data. 3065 */ 3066 3067http_status_t /* O - HTTP status */ 3068httpUpdate(http_t *http) /* I - HTTP connection */ 3069{ 3070 http_status_t status; /* Request status */ 3071 3072 3073 DEBUG_printf(("httpUpdate(http=%p), state=%s", http, 3074 httpStateString(http->state))); 3075 3076 /* 3077 * Flush pending data, if any... 3078 */ 3079 3080 if (http->wused) 3081 { 3082 DEBUG_puts("2httpUpdate: flushing buffer..."); 3083 3084 if (httpFlushWrite(http) < 0) 3085 return (HTTP_STATUS_ERROR); 3086 } 3087 3088 /* 3089 * If we haven't issued any commands, then there is nothing to "update"... 3090 */ 3091 3092 if (http->state == HTTP_STATE_WAITING) 3093 return (HTTP_STATUS_CONTINUE); 3094 3095 /* 3096 * Grab all of the lines we can from the connection... 3097 */ 3098 3099 while (_httpUpdate(http, &status)); 3100 3101 /* 3102 * See if there was an error... 3103 */ 3104 3105 if (http->error == EPIPE && http->status > HTTP_STATUS_CONTINUE) 3106 { 3107 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status)); 3108 return (http->status); 3109 } 3110 3111 if (http->error) 3112 { 3113 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error, 3114 strerror(http->error))); 3115 http->status = HTTP_STATUS_ERROR; 3116 return (HTTP_STATUS_ERROR); 3117 } 3118 3119 /* 3120 * Return the current status... 3121 */ 3122 3123 return (status); 3124} 3125 3126 3127/* 3128 * '_httpWait()' - Wait for data available on a connection (no flush). 3129 */ 3130 3131int /* O - 1 if data is available, 0 otherwise */ 3132_httpWait(http_t *http, /* I - HTTP connection */ 3133 int msec, /* I - Milliseconds to wait */ 3134 int usessl) /* I - Use SSL context? */ 3135{ 3136#ifdef HAVE_POLL 3137 struct pollfd pfd; /* Polled file descriptor */ 3138#else 3139 fd_set input_set; /* select() input set */ 3140 struct timeval timeout; /* Timeout */ 3141#endif /* HAVE_POLL */ 3142 int nfds; /* Result from select()/poll() */ 3143 3144 3145 DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl)); 3146 3147 if (http->fd < 0) 3148 { 3149 DEBUG_printf(("5_httpWait: Returning 0 since fd=%d", http->fd)); 3150 return (0); 3151 } 3152 3153 /* 3154 * Check the SSL/TLS buffers for data first... 3155 */ 3156 3157#ifdef HAVE_SSL 3158 if (http->tls && _httpTLSPending(http)) 3159 { 3160 DEBUG_puts("5_httpWait: Return 1 since there is pending TLS data."); 3161 return (1); 3162 } 3163#endif /* HAVE_SSL */ 3164 3165 /* 3166 * Then try doing a select() or poll() to poll the socket... 3167 */ 3168 3169#ifdef HAVE_POLL 3170 pfd.fd = http->fd; 3171 pfd.events = POLLIN; 3172 3173 do 3174 { 3175 nfds = poll(&pfd, 1, msec); 3176 } 3177 while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); 3178 3179#else 3180 do 3181 { 3182 FD_ZERO(&input_set); 3183 FD_SET(http->fd, &input_set); 3184 3185 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd)); 3186 3187 if (msec >= 0) 3188 { 3189 timeout.tv_sec = msec / 1000; 3190 timeout.tv_usec = (msec % 1000) * 1000; 3191 3192 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout); 3193 } 3194 else 3195 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL); 3196 3197 DEBUG_printf(("6_httpWait: select() returned %d...", nfds)); 3198 } 3199# ifdef WIN32 3200 while (nfds < 0 && (WSAGetLastError() == WSAEINTR || 3201 WSAGetLastError() == WSAEWOULDBLOCK)); 3202# else 3203 while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); 3204# endif /* WIN32 */ 3205#endif /* HAVE_POLL */ 3206 3207 DEBUG_printf(("5_httpWait: returning with nfds=%d, errno=%d...", nfds, 3208 errno)); 3209 3210 return (nfds > 0); 3211} 3212 3213 3214/* 3215 * 'httpWait()' - Wait for data available on a connection. 3216 * 3217 * @since CUPS 1.1.19/OS X 10.3@ 3218 */ 3219 3220int /* O - 1 if data is available, 0 otherwise */ 3221httpWait(http_t *http, /* I - HTTP connection */ 3222 int msec) /* I - Milliseconds to wait */ 3223{ 3224 /* 3225 * First see if there is data in the buffer... 3226 */ 3227 3228 DEBUG_printf(("2httpWait(http=%p, msec=%d)", http, msec)); 3229 3230 if (http == NULL) 3231 return (0); 3232 3233 if (http->used) 3234 { 3235 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready."); 3236 return (1); 3237 } 3238 3239#ifdef HAVE_LIBZ 3240 if (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in > 0) 3241 { 3242 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready."); 3243 return (1); 3244 } 3245#endif /* HAVE_LIBZ */ 3246 3247 /* 3248 * Flush pending data, if any... 3249 */ 3250 3251 if (http->wused) 3252 { 3253 DEBUG_puts("3httpWait: Flushing write buffer."); 3254 3255 if (httpFlushWrite(http) < 0) 3256 return (0); 3257 } 3258 3259 /* 3260 * If not, check the SSL/TLS buffers and do a select() on the connection... 3261 */ 3262 3263 return (_httpWait(http, msec, 1)); 3264} 3265 3266 3267/* 3268 * 'httpWrite()' - Write data to a HTTP connection. 3269 * 3270 * This function is deprecated. Use the httpWrite2() function which can 3271 * write more than 2GB of data. 3272 * 3273 * @deprecated@ 3274 */ 3275 3276int /* O - Number of bytes written */ 3277httpWrite(http_t *http, /* I - HTTP connection */ 3278 const char *buffer, /* I - Buffer for data */ 3279 int length) /* I - Number of bytes to write */ 3280{ 3281 return ((int)httpWrite2(http, buffer, (size_t)length)); 3282} 3283 3284 3285/* 3286 * 'httpWrite2()' - Write data to a HTTP connection. 3287 * 3288 * @since CUPS 1.2/OS X 10.5@ 3289 */ 3290 3291ssize_t /* O - Number of bytes written */ 3292httpWrite2(http_t *http, /* I - HTTP connection */ 3293 const char *buffer, /* I - Buffer for data */ 3294 size_t length) /* I - Number of bytes to write */ 3295{ 3296 ssize_t bytes; /* Bytes written */ 3297 3298 3299 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http, 3300 buffer, CUPS_LLCAST length)); 3301 3302 /* 3303 * Range check input... 3304 */ 3305 3306 if (!http || !buffer) 3307 { 3308 DEBUG_puts("1httpWrite2: Returning -1 due to bad input."); 3309 return (-1); 3310 } 3311 3312 /* 3313 * Mark activity on the connection... 3314 */ 3315 3316 http->activity = time(NULL); 3317 3318 /* 3319 * Buffer small writes for better performance... 3320 */ 3321 3322#ifdef HAVE_LIBZ 3323 if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE) 3324 { 3325 DEBUG_printf(("1httpWrite2: http->coding=%d", http->coding)); 3326 3327 if (length == 0) 3328 { 3329 http_content_coding_finish(http); 3330 bytes = 0; 3331 } 3332 else 3333 { 3334 size_t slen; /* Bytes to write */ 3335 ssize_t sret; /* Bytes written */ 3336 3337 http->stream.next_in = (Bytef *)buffer; 3338 http->stream.avail_in = (uInt)length; 3339 3340 while (deflate(&(http->stream), Z_NO_FLUSH) == Z_OK) 3341 { 3342 DEBUG_printf(("1httpWrite2: avail_out=%d", http->stream.avail_out)); 3343 3344 if (http->stream.avail_out > 0) 3345 continue; 3346 3347 slen = _HTTP_MAX_SBUFFER - http->stream.avail_out; 3348 3349 DEBUG_printf(("1httpWrite2: Writing intermediate chunk, len=%d", (int)slen)); 3350 3351 if (slen > 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) 3352 sret = http_write_chunk(http, (char *)http->sbuffer, slen); 3353 else if (slen > 0) 3354 sret = http_write(http, (char *)http->sbuffer, slen); 3355 else 3356 sret = 0; 3357 3358 if (sret < 0) 3359 { 3360 DEBUG_puts("1httpWrite2: Unable to write, returning -1."); 3361 return (-1); 3362 } 3363 3364 http->stream.next_out = (Bytef *)http->sbuffer; 3365 http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; 3366 } 3367 3368 bytes = (ssize_t)length; 3369 } 3370 } 3371 else 3372#endif /* HAVE_LIBZ */ 3373 if (length > 0) 3374 { 3375 if (http->wused && (length + (size_t)http->wused) > sizeof(http->wbuffer)) 3376 { 3377 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length=" 3378 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length)); 3379 3380 httpFlushWrite(http); 3381 } 3382 3383 if ((length + (size_t)http->wused) <= sizeof(http->wbuffer) && length < sizeof(http->wbuffer)) 3384 { 3385 /* 3386 * Write to buffer... 3387 */ 3388 3389 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...", 3390 CUPS_LLCAST length)); 3391 3392 memcpy(http->wbuffer + http->wused, buffer, length); 3393 http->wused += (int)length; 3394 bytes = (ssize_t)length; 3395 } 3396 else 3397 { 3398 /* 3399 * Otherwise write the data directly... 3400 */ 3401 3402 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...", 3403 CUPS_LLCAST length)); 3404 3405 if (http->data_encoding == HTTP_ENCODING_CHUNKED) 3406 bytes = (ssize_t)http_write_chunk(http, buffer, length); 3407 else 3408 bytes = (ssize_t)http_write(http, buffer, length); 3409 3410 DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...", 3411 CUPS_LLCAST bytes)); 3412 } 3413 3414 if (http->data_encoding == HTTP_ENCODING_LENGTH) 3415 http->data_remaining -= bytes; 3416 } 3417 else 3418 bytes = 0; 3419 3420 /* 3421 * Handle end-of-request processing... 3422 */ 3423 3424 if ((http->data_encoding == HTTP_ENCODING_CHUNKED && length == 0) || 3425 (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0)) 3426 { 3427 /* 3428 * Finished with the transfer; unless we are sending POST or PUT 3429 * data, go idle... 3430 */ 3431 3432#ifdef HAVE_LIBZ 3433 if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE) 3434 http_content_coding_finish(http); 3435#endif /* HAVE_LIBZ */ 3436 3437 if (http->wused) 3438 { 3439 if (httpFlushWrite(http) < 0) 3440 return (-1); 3441 } 3442 3443 if (http->data_encoding == HTTP_ENCODING_CHUNKED) 3444 { 3445 /* 3446 * Send a 0-length chunk at the end of the request... 3447 */ 3448 3449 http_write(http, "0\r\n\r\n", 5); 3450 3451 /* 3452 * Reset the data state... 3453 */ 3454 3455 http->data_encoding = HTTP_ENCODING_FIELDS; 3456 http->data_remaining = 0; 3457 } 3458 3459 if (http->state == HTTP_STATE_POST_RECV) 3460 http->state ++; 3461 else if (http->state == HTTP_STATE_POST_SEND || 3462 http->state == HTTP_STATE_GET_SEND) 3463 http->state = HTTP_STATE_WAITING; 3464 else 3465 http->state = HTTP_STATE_STATUS; 3466 3467 DEBUG_printf(("2httpWrite2: Changed state to %s.", 3468 httpStateString(http->state))); 3469 } 3470 3471 DEBUG_printf(("1httpWrite2: Returning " CUPS_LLFMT ".", CUPS_LLCAST bytes)); 3472 3473 return (bytes); 3474} 3475 3476 3477/* 3478 * 'httpWriteResponse()' - Write a HTTP response to a client connection. 3479 * 3480 * @since CUPS 1.7/OS X 10.9@ 3481 */ 3482 3483int /* O - 0 on success, -1 on error */ 3484httpWriteResponse(http_t *http, /* I - HTTP connection */ 3485 http_status_t status) /* I - Status code */ 3486{ 3487 http_encoding_t old_encoding; /* Old data_encoding value */ 3488 off_t old_remaining; /* Old data_remaining value */ 3489 3490 3491 /* 3492 * Range check input... 3493 */ 3494 3495 DEBUG_printf(("httpWriteResponse(http=%p, status=%d)", http, status)); 3496 3497 if (!http || status < HTTP_STATUS_CONTINUE) 3498 { 3499 DEBUG_puts("1httpWriteResponse: Bad input."); 3500 return (-1); 3501 } 3502 3503 /* 3504 * Set the various standard fields if they aren't already... 3505 */ 3506 3507 if (!http->fields[HTTP_FIELD_DATE][0]) 3508 httpSetField(http, HTTP_FIELD_DATE, httpGetDateString(time(NULL))); 3509 3510 if (status >= HTTP_STATUS_BAD_REQUEST && http->keep_alive) 3511 { 3512 http->keep_alive = HTTP_KEEPALIVE_OFF; 3513 httpSetField(http, HTTP_FIELD_KEEP_ALIVE, ""); 3514 } 3515 3516 if (http->version == HTTP_VERSION_1_1) 3517 { 3518 if (!http->fields[HTTP_FIELD_CONNECTION][0]) 3519 { 3520 if (http->keep_alive) 3521 httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive"); 3522 else 3523 httpSetField(http, HTTP_FIELD_CONNECTION, "close"); 3524 } 3525 3526 if (http->keep_alive && !http->fields[HTTP_FIELD_KEEP_ALIVE][0]) 3527 httpSetField(http, HTTP_FIELD_KEEP_ALIVE, "timeout=10"); 3528 } 3529 3530#ifdef HAVE_SSL 3531 if (status == HTTP_STATUS_UPGRADE_REQUIRED || 3532 status == HTTP_STATUS_SWITCHING_PROTOCOLS) 3533 { 3534 if (!http->fields[HTTP_FIELD_CONNECTION][0]) 3535 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); 3536 3537 if (!http->fields[HTTP_FIELD_UPGRADE][0]) 3538 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); 3539 3540 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) 3541 httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, "0"); 3542 } 3543#endif /* HAVE_SSL */ 3544 3545 if (!http->server) 3546 httpSetField(http, HTTP_FIELD_SERVER, 3547 http->default_server ? http->default_server : CUPS_MINIMAL); 3548 3549 /* 3550 * Set the Accept-Encoding field if it isn't already... 3551 */ 3552 3553 if (!http->accept_encoding) 3554 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, 3555 http->default_accept_encoding ? http->default_accept_encoding : 3556#ifdef HAVE_LIBZ 3557 "gzip, deflate, identity"); 3558#else 3559 "identity"); 3560#endif /* HAVE_LIBZ */ 3561 3562 /* 3563 * Send the response header... 3564 */ 3565 3566 old_encoding = http->data_encoding; 3567 old_remaining = http->data_remaining; 3568 http->data_encoding = HTTP_ENCODING_FIELDS; 3569 3570 if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100, 3571 http->version % 100, (int)status, httpStatus(status)) < 0) 3572 { 3573 http->status = HTTP_STATUS_ERROR; 3574 return (-1); 3575 } 3576 3577 if (status != HTTP_STATUS_CONTINUE) 3578 { 3579 /* 3580 * 100 Continue doesn't have the rest of the response headers... 3581 */ 3582 3583 int i; /* Looping var */ 3584 const char *value; /* Field value */ 3585 3586 for (i = 0; i < HTTP_FIELD_MAX; i ++) 3587 { 3588 if ((value = httpGetField(http, i)) != NULL && *value) 3589 { 3590 if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1) 3591 { 3592 http->status = HTTP_STATUS_ERROR; 3593 return (-1); 3594 } 3595 } 3596 } 3597 3598 if (http->cookie) 3599 { 3600 if (strchr(http->cookie, ';')) 3601 { 3602 if (httpPrintf(http, "Set-Cookie: %s\r\n", http->cookie) < 1) 3603 { 3604 http->status = HTTP_STATUS_ERROR; 3605 return (-1); 3606 } 3607 } 3608 else if (httpPrintf(http, "Set-Cookie: %s; path=/; httponly;%s\r\n", http->cookie, http->tls ? " secure;" : "") < 1) 3609 { 3610 http->status = HTTP_STATUS_ERROR; 3611 return (-1); 3612 } 3613 } 3614 } 3615 3616 if (httpWrite2(http, "\r\n", 2) < 2) 3617 { 3618 http->status = HTTP_STATUS_ERROR; 3619 return (-1); 3620 } 3621 3622 if (httpFlushWrite(http) < 0) 3623 { 3624 http->status = HTTP_STATUS_ERROR; 3625 return (-1); 3626 } 3627 3628 if (status == HTTP_STATUS_CONTINUE || 3629 status == HTTP_STATUS_SWITCHING_PROTOCOLS) 3630 { 3631 /* 3632 * Restore the old data_encoding and data_length values... 3633 */ 3634 3635 http->data_encoding = old_encoding; 3636 http->data_remaining = old_remaining; 3637 3638 if (old_remaining <= INT_MAX) 3639 http->_data_remaining = (int)old_remaining; 3640 else 3641 http->_data_remaining = INT_MAX; 3642 } 3643 else if (http->state == HTTP_STATE_OPTIONS || 3644 http->state == HTTP_STATE_HEAD || 3645 http->state == HTTP_STATE_PUT || 3646 http->state == HTTP_STATE_TRACE || 3647 http->state == HTTP_STATE_CONNECT || 3648 http->state == HTTP_STATE_STATUS) 3649 { 3650 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, " 3651 "was %s.", httpStateString(http->state))); 3652 http->state = HTTP_STATE_WAITING; 3653 } 3654 else 3655 { 3656 /* 3657 * Force data_encoding and data_length to be set according to the response 3658 * headers... 3659 */ 3660 3661 http_set_length(http); 3662 3663 if (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0) 3664 { 3665 DEBUG_printf(("1httpWriteResponse: Resetting state to HTTP_STATE_WAITING, " 3666 "was %s.", httpStateString(http->state))); 3667 http->state = HTTP_STATE_WAITING; 3668 return (0); 3669 } 3670 3671#ifdef HAVE_LIBZ 3672 /* 3673 * Then start any content encoding... 3674 */ 3675 3676 DEBUG_puts("1httpWriteResponse: Calling http_content_coding_start."); 3677 http_content_coding_start(http, 3678 httpGetField(http, HTTP_FIELD_CONTENT_ENCODING)); 3679#endif /* HAVE_LIBZ */ 3680 3681 } 3682 3683 return (0); 3684} 3685 3686 3687#ifdef HAVE_LIBZ 3688/* 3689 * 'http_content_coding_finish()' - Finish doing any content encoding. 3690 */ 3691 3692static void 3693http_content_coding_finish( 3694 http_t *http) /* I - HTTP connection */ 3695{ 3696 int zerr; /* Compression status */ 3697 Byte dummy[1]; /* Dummy read buffer */ 3698 size_t bytes; /* Number of bytes to write */ 3699 3700 3701 DEBUG_printf(("http_content_coding_finish(http=%p)", http)); 3702 DEBUG_printf(("1http_content_coding_finishing: http->coding=%d", http->coding)); 3703 3704 switch (http->coding) 3705 { 3706 case _HTTP_CODING_DEFLATE : 3707 case _HTTP_CODING_GZIP : 3708 http->stream.next_in = dummy; 3709 http->stream.avail_in = 0; 3710 3711 do 3712 { 3713 zerr = deflate(&(http->stream), Z_FINISH); 3714 bytes = _HTTP_MAX_SBUFFER - http->stream.avail_out; 3715 3716 if (bytes > 0) 3717 { 3718 DEBUG_printf(("1http_content_coding_finish: Writing trailing chunk, len=%d", (int)bytes)); 3719 3720 if (http->data_encoding == HTTP_ENCODING_CHUNKED) 3721 http_write_chunk(http, (char *)http->sbuffer, bytes); 3722 else 3723 http_write(http, (char *)http->sbuffer, bytes); 3724 } 3725 3726 http->stream.next_out = (Bytef *)http->sbuffer; 3727 http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; 3728 } 3729 while (zerr == Z_OK); 3730 3731 deflateEnd(&(http->stream)); 3732 3733 free(http->sbuffer); 3734 http->sbuffer = NULL; 3735 3736 if (http->wused) 3737 httpFlushWrite(http); 3738 break; 3739 3740 case _HTTP_CODING_INFLATE : 3741 case _HTTP_CODING_GUNZIP : 3742 inflateEnd(&(http->stream)); 3743 free(http->sbuffer); 3744 http->sbuffer = NULL; 3745 break; 3746 3747 default : 3748 break; 3749 } 3750 3751 http->coding = _HTTP_CODING_IDENTITY; 3752} 3753 3754 3755/* 3756 * 'http_content_coding_start()' - Start doing content encoding. 3757 */ 3758 3759static void 3760http_content_coding_start( 3761 http_t *http, /* I - HTTP connection */ 3762 const char *value) /* I - Value of Content-Encoding */ 3763{ 3764 int zerr; /* Error/status */ 3765 _http_coding_t coding; /* Content coding value */ 3766 3767 3768 DEBUG_printf(("http_content_coding_start(http=%p, value=\"%s\")", http, 3769 value)); 3770 3771 if (http->coding != _HTTP_CODING_IDENTITY) 3772 { 3773 DEBUG_printf(("1http_content_coding_start: http->coding already %d.", 3774 http->coding)); 3775 return; 3776 } 3777 else if (!strcmp(value, "x-gzip") || !strcmp(value, "gzip")) 3778 { 3779 if (http->state == HTTP_STATE_GET_SEND || 3780 http->state == HTTP_STATE_POST_SEND) 3781 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_GZIP : 3782 _HTTP_CODING_GUNZIP; 3783 else if (http->state == HTTP_STATE_POST_RECV || 3784 http->state == HTTP_STATE_PUT_RECV) 3785 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_GZIP : 3786 _HTTP_CODING_GUNZIP; 3787 else 3788 { 3789 DEBUG_puts("1http_content_coding_start: Not doing content coding."); 3790 return; 3791 } 3792 } 3793 else if (!strcmp(value, "x-deflate") || !strcmp(value, "deflate")) 3794 { 3795 if (http->state == HTTP_STATE_GET_SEND || 3796 http->state == HTTP_STATE_POST_SEND) 3797 coding = http->mode == _HTTP_MODE_SERVER ? _HTTP_CODING_DEFLATE : 3798 _HTTP_CODING_INFLATE; 3799 else if (http->state == HTTP_STATE_POST_RECV || 3800 http->state == HTTP_STATE_PUT_RECV) 3801 coding = http->mode == _HTTP_MODE_CLIENT ? _HTTP_CODING_DEFLATE : 3802 _HTTP_CODING_INFLATE; 3803 else 3804 { 3805 DEBUG_puts("1http_content_coding_start: Not doing content coding."); 3806 return; 3807 } 3808 } 3809 else 3810 { 3811 DEBUG_puts("1http_content_coding_start: Not doing content coding."); 3812 return; 3813 } 3814 3815 memset(&(http->stream), 0, sizeof(http->stream)); 3816 3817 switch (coding) 3818 { 3819 case _HTTP_CODING_DEFLATE : 3820 case _HTTP_CODING_GZIP : 3821 if (http->wused) 3822 httpFlushWrite(http); 3823 3824 if ((http->sbuffer = malloc(_HTTP_MAX_SBUFFER)) == NULL) 3825 { 3826 http->status = HTTP_STATUS_ERROR; 3827 http->error = errno; 3828 return; 3829 } 3830 3831 /* 3832 * Window size for compression is 11 bits - optimal based on PWG Raster 3833 * sample files on pwg.org. -11 is raw deflate, 27 is gzip, per ZLIB 3834 * documentation. 3835 */ 3836 3837 if ((zerr = deflateInit2(&(http->stream), Z_DEFAULT_COMPRESSION, 3838 Z_DEFLATED, 3839 coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7, 3840 Z_DEFAULT_STRATEGY)) < Z_OK) 3841 { 3842 http->status = HTTP_STATUS_ERROR; 3843 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; 3844 return; 3845 } 3846 3847 http->stream.next_out = (Bytef *)http->sbuffer; 3848 http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; 3849 break; 3850 3851 case _HTTP_CODING_INFLATE : 3852 case _HTTP_CODING_GUNZIP : 3853 if ((http->sbuffer = malloc(_HTTP_MAX_SBUFFER)) == NULL) 3854 { 3855 http->status = HTTP_STATUS_ERROR; 3856 http->error = errno; 3857 return; 3858 } 3859 3860 /* 3861 * Window size for decompression is up to 15 bits (maximum supported). 3862 * -15 is raw inflate, 31 is gunzip, per ZLIB documentation. 3863 */ 3864 3865 if ((zerr = inflateInit2(&(http->stream), 3866 coding == _HTTP_CODING_INFLATE ? -15 : 31)) 3867 < Z_OK) 3868 { 3869 free(http->sbuffer); 3870 http->sbuffer = NULL; 3871 http->status = HTTP_STATUS_ERROR; 3872 http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; 3873 return; 3874 } 3875 3876 http->stream.avail_in = 0; 3877 http->stream.next_in = http->sbuffer; 3878 break; 3879 3880 default : 3881 break; 3882 } 3883 3884 http->coding = coding; 3885 3886 DEBUG_printf(("1http_content_coding_start: http->coding now %d.", 3887 http->coding)); 3888} 3889#endif /* HAVE_LIBZ */ 3890 3891 3892/* 3893 * 'http_create()' - Create an unconnected HTTP connection. 3894 */ 3895 3896static http_t * /* O - HTTP connection */ 3897http_create( 3898 const char *host, /* I - Hostname */ 3899 int port, /* I - Port number */ 3900 http_addrlist_t *addrlist, /* I - Address list or NULL */ 3901 int family, /* I - Address family or AF_UNSPEC */ 3902 http_encryption_t encryption, /* I - Encryption to use */ 3903 int blocking, /* I - 1 for blocking mode */ 3904 _http_mode_t mode) /* I - _HTTP_MODE_CLIENT or _SERVER */ 3905{ 3906 http_t *http; /* New HTTP connection */ 3907 char service[255]; /* Service name */ 3908 http_addrlist_t *myaddrlist = NULL; /* My address list */ 3909 3910 3911 DEBUG_printf(("4http_create(host=\"%s\", port=%d, addrlist=%p, family=%d, " 3912 "encryption=%d, blocking=%d, mode=%d)", host, port, addrlist, 3913 family, encryption, blocking, mode)); 3914 3915 if (!host && mode == _HTTP_MODE_CLIENT) 3916 return (NULL); 3917 3918 httpInitialize(); 3919 3920 /* 3921 * Lookup the host... 3922 */ 3923 3924 if (addrlist) 3925 { 3926 myaddrlist = httpAddrCopyList(addrlist); 3927 } 3928 else 3929 { 3930 snprintf(service, sizeof(service), "%d", port); 3931 3932 myaddrlist = httpAddrGetList(host, family, service); 3933 } 3934 3935 if (!myaddrlist) 3936 return (NULL); 3937 3938 /* 3939 * Allocate memory for the structure... 3940 */ 3941 3942 if ((http = calloc(sizeof(http_t), 1)) == NULL) 3943 { 3944 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); 3945 httpAddrFreeList(addrlist); 3946 return (NULL); 3947 } 3948 3949 /* 3950 * Initialize the HTTP data... 3951 */ 3952 3953 http->mode = mode; 3954 http->activity = time(NULL); 3955 http->addrlist = myaddrlist; 3956 http->blocking = blocking; 3957 http->fd = -1; 3958#ifdef HAVE_GSSAPI 3959 http->gssctx = GSS_C_NO_CONTEXT; 3960 http->gssname = GSS_C_NO_NAME; 3961#endif /* HAVE_GSSAPI */ 3962 http->status = HTTP_STATUS_CONTINUE; 3963 http->version = HTTP_VERSION_1_1; 3964 3965 if (host) 3966 strlcpy(http->hostname, host, sizeof(http->hostname)); 3967 3968 if (port == 443) /* Always use encryption for https */ 3969 http->encryption = HTTP_ENCRYPTION_ALWAYS; 3970 else 3971 http->encryption = encryption; 3972 3973 http_set_wait(http); 3974 3975 /* 3976 * Return the new structure... 3977 */ 3978 3979 return (http); 3980} 3981 3982 3983#ifdef DEBUG 3984/* 3985 * 'http_debug_hex()' - Do a hex dump of a buffer. 3986 */ 3987 3988static void 3989http_debug_hex(const char *prefix, /* I - Prefix for line */ 3990 const char *buffer, /* I - Buffer to dump */ 3991 int bytes) /* I - Bytes to dump */ 3992{ 3993 int i, j, /* Looping vars */ 3994 ch; /* Current character */ 3995 char line[255], /* Line buffer */ 3996 *start, /* Start of line after prefix */ 3997 *ptr; /* Pointer into line */ 3998 3999 4000 if (_cups_debug_fd < 0 || _cups_debug_level < 6) 4001 return; 4002 4003 DEBUG_printf(("6%s: %d bytes:", prefix, bytes)); 4004 4005 snprintf(line, sizeof(line), "6%s: ", prefix); 4006 start = line + strlen(line); 4007 4008 for (i = 0; i < bytes; i += 16) 4009 { 4010 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2) 4011 sprintf(ptr, "%02X", buffer[i + j] & 255); 4012 4013 while (j < 16) 4014 { 4015 memcpy(ptr, " ", 3); 4016 ptr += 2; 4017 j ++; 4018 } 4019 4020 memcpy(ptr, " ", 3); 4021 ptr += 2; 4022 4023 for (j = 0; j < 16 && (i + j) < bytes; j ++) 4024 { 4025 ch = buffer[i + j] & 255; 4026 4027 if (ch < ' ' || ch >= 127) 4028 ch = '.'; 4029 4030 *ptr++ = (char)ch; 4031 } 4032 4033 *ptr = '\0'; 4034 DEBUG_puts(line); 4035 } 4036} 4037#endif /* DEBUG */ 4038 4039 4040/* 4041 * 'http_read()' - Read a buffer from a HTTP connection. 4042 * 4043 * This function does the low-level read from the socket, retrying and timing 4044 * out as needed. 4045 */ 4046 4047static ssize_t /* O - Number of bytes read or -1 on error */ 4048http_read(http_t *http, /* I - HTTP connection */ 4049 char *buffer, /* I - Buffer */ 4050 size_t length) /* I - Maximum bytes to read */ 4051{ 4052 ssize_t bytes; /* Bytes read */ 4053 4054 4055 DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http, 4056 buffer, CUPS_LLCAST length)); 4057 4058 if (!http->blocking) 4059 { 4060 while (!httpWait(http, http->wait_value)) 4061 { 4062 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 4063 continue; 4064 4065 DEBUG_puts("2http_read: Timeout."); 4066 return (0); 4067 } 4068 } 4069 4070 DEBUG_printf(("2http_read: Reading %d bytes into buffer.", (int)length)); 4071 4072 do 4073 { 4074#ifdef HAVE_SSL 4075 if (http->tls) 4076 bytes = _httpTLSRead(http, buffer, (int)length); 4077 else 4078#endif /* HAVE_SSL */ 4079 bytes = recv(http->fd, buffer, length, 0); 4080 4081 if (bytes < 0) 4082 { 4083#ifdef WIN32 4084 if (WSAGetLastError() != WSAEINTR) 4085 { 4086 http->error = WSAGetLastError(); 4087 return (-1); 4088 } 4089 else if (WSAGetLastError() == WSAEWOULDBLOCK) 4090 { 4091 if (!http->timeout_cb || 4092 !(*http->timeout_cb)(http, http->timeout_data)) 4093 { 4094 http->error = WSAEWOULDBLOCK; 4095 return (-1); 4096 } 4097 } 4098#else 4099 DEBUG_printf(("2http_read: %s", strerror(errno))); 4100 4101 if (errno == EWOULDBLOCK || errno == EAGAIN) 4102 { 4103 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data)) 4104 { 4105 http->error = errno; 4106 return (-1); 4107 } 4108 else if (!http->timeout_cb && errno != EAGAIN) 4109 { 4110 http->error = errno; 4111 return (-1); 4112 } 4113 } 4114 else if (errno != EINTR) 4115 { 4116 http->error = errno; 4117 return (-1); 4118 } 4119#endif /* WIN32 */ 4120 } 4121 } 4122 while (bytes < 0); 4123 4124 DEBUG_printf(("2http_read: Read " CUPS_LLFMT " bytes into buffer.", 4125 CUPS_LLCAST bytes)); 4126#ifdef DEBUG 4127 if (bytes > 0) 4128 http_debug_hex("http_read", buffer, (int)bytes); 4129#endif /* DEBUG */ 4130 4131 if (bytes < 0) 4132 { 4133#ifdef WIN32 4134 if (WSAGetLastError() == WSAEINTR) 4135 bytes = 0; 4136 else 4137 http->error = WSAGetLastError(); 4138#else 4139 if (errno == EINTR || (errno == EAGAIN && !http->timeout_cb)) 4140 bytes = 0; 4141 else 4142 http->error = errno; 4143#endif /* WIN32 */ 4144 } 4145 else if (bytes == 0) 4146 { 4147 http->error = EPIPE; 4148 return (0); 4149 } 4150 4151 return (bytes); 4152} 4153 4154 4155/* 4156 * 'http_read_buffered()' - Do a buffered read from a HTTP connection. 4157 * 4158 * This function reads data from the HTTP buffer or from the socket, as needed. 4159 */ 4160 4161static ssize_t /* O - Number of bytes read or -1 on error */ 4162http_read_buffered(http_t *http, /* I - HTTP connection */ 4163 char *buffer, /* I - Buffer */ 4164 size_t length) /* I - Maximum bytes to read */ 4165{ 4166 ssize_t bytes; /* Bytes read */ 4167 4168 4169 DEBUG_printf(("http_read_buffered(http=%p, buffer=%p, length=" CUPS_LLFMT 4170 ") used=%d", 4171 http, buffer, CUPS_LLCAST length, http->used)); 4172 4173 if (http->used > 0) 4174 { 4175 if (length > (size_t)http->used) 4176 bytes = (ssize_t)http->used; 4177 else 4178 bytes = (ssize_t)length; 4179 4180 DEBUG_printf(("2http_read: Grabbing %d bytes from input buffer.", 4181 (int)bytes)); 4182 4183 memcpy(buffer, http->buffer, (size_t)bytes); 4184 http->used -= (int)bytes; 4185 4186 if (http->used > 0) 4187 memmove(http->buffer, http->buffer + bytes, (size_t)http->used); 4188 } 4189 else 4190 bytes = http_read(http, buffer, length); 4191 4192 return (bytes); 4193} 4194 4195 4196/* 4197 * 'http_read_chunk()' - Read a chunk from a HTTP connection. 4198 * 4199 * This function reads and validates the chunk length, then does a buffered read 4200 * returning the number of bytes placed in the buffer. 4201 */ 4202 4203static ssize_t /* O - Number of bytes read or -1 on error */ 4204http_read_chunk(http_t *http, /* I - HTTP connection */ 4205 char *buffer, /* I - Buffer */ 4206 size_t length) /* I - Maximum bytes to read */ 4207{ 4208 DEBUG_printf(("http_read_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")", 4209 http, buffer, CUPS_LLCAST length)); 4210 4211 if (http->data_remaining <= 0) 4212 { 4213 char len[32]; /* Length string */ 4214 4215 if (!httpGets(len, sizeof(len), http)) 4216 { 4217 DEBUG_puts("1http_read_chunk: Could not get chunk length."); 4218 return (0); 4219 } 4220 4221 if (!len[0]) 4222 { 4223 DEBUG_puts("1http_read_chunk: Blank chunk length, trying again..."); 4224 if (!httpGets(len, sizeof(len), http)) 4225 { 4226 DEBUG_puts("1http_read_chunk: Could not get chunk length."); 4227 return (0); 4228 } 4229 } 4230 4231 http->data_remaining = strtoll(len, NULL, 16); 4232 4233 if (http->data_remaining < 0) 4234 { 4235 DEBUG_printf(("1http_read_chunk: Negative chunk length \"%s\" (" 4236 CUPS_LLFMT ")", len, CUPS_LLCAST http->data_remaining)); 4237 return (0); 4238 } 4239 4240 DEBUG_printf(("2http_read_chunk: Got chunk length \"%s\" (" CUPS_LLFMT ")", 4241 len, CUPS_LLCAST http->data_remaining)); 4242 4243 if (http->data_remaining == 0) 4244 { 4245 /* 4246 * 0-length chunk, grab trailing blank line... 4247 */ 4248 4249 httpGets(len, sizeof(len), http); 4250 } 4251 } 4252 4253 DEBUG_printf(("2http_read_chunk: data_remaining=" CUPS_LLFMT, 4254 CUPS_LLCAST http->data_remaining)); 4255 4256 if (http->data_remaining <= 0) 4257 return (0); 4258 else if (length > (size_t)http->data_remaining) 4259 length = (size_t)http->data_remaining; 4260 4261 return (http_read_buffered(http, buffer, length)); 4262} 4263 4264 4265/* 4266 * 'http_send()' - Send a request with all fields and the trailing blank line. 4267 */ 4268 4269static int /* O - 0 on success, non-zero on error */ 4270http_send(http_t *http, /* I - HTTP connection */ 4271 http_state_t request, /* I - Request code */ 4272 const char *uri) /* I - URI */ 4273{ 4274 int i; /* Looping var */ 4275 char buf[1024]; /* Encoded URI buffer */ 4276 const char *value; /* Field value */ 4277 static const char * const codes[] = /* Request code strings */ 4278 { 4279 NULL, 4280 "OPTIONS", 4281 "GET", 4282 NULL, 4283 "HEAD", 4284 "POST", 4285 NULL, 4286 NULL, 4287 "PUT", 4288 NULL, 4289 "DELETE", 4290 "TRACE", 4291 "CLOSE", 4292 NULL, 4293 NULL 4294 }; 4295 4296 4297 DEBUG_printf(("4http_send(http=%p, request=HTTP_%s, uri=\"%s\")", 4298 http, codes[request], uri)); 4299 4300 if (http == NULL || uri == NULL) 4301 return (-1); 4302 4303 /* 4304 * Set the User-Agent field if it isn't already... 4305 */ 4306 4307 if (!http->fields[HTTP_FIELD_USER_AGENT][0]) 4308 { 4309 if (http->default_user_agent) 4310 httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_user_agent); 4311 else 4312 httpSetField(http, HTTP_FIELD_USER_AGENT, cupsUserAgent()); 4313 } 4314 4315 /* 4316 * Set the Accept-Encoding field if it isn't already... 4317 */ 4318 4319 if (!http->accept_encoding && http->default_accept_encoding) 4320 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, 4321 http->default_accept_encoding); 4322 4323 /* 4324 * Encode the URI as needed... 4325 */ 4326 4327 _httpEncodeURI(buf, uri, sizeof(buf)); 4328 4329 /* 4330 * See if we had an error the last time around; if so, reconnect... 4331 */ 4332 4333 if (http->fd < 0 || http->status == HTTP_STATUS_ERROR || 4334 http->status >= HTTP_STATUS_BAD_REQUEST) 4335 { 4336 DEBUG_printf(("5http_send: Reconnecting, fd=%d, status=%d, tls_upgrade=%d", 4337 http->fd, http->status, http->tls_upgrade)); 4338 4339 if (httpReconnect2(http, 30000, NULL)) 4340 return (-1); 4341 } 4342 4343 /* 4344 * Flush any written data that is pending... 4345 */ 4346 4347 if (http->wused) 4348 { 4349 if (httpFlushWrite(http) < 0) 4350 if (httpReconnect2(http, 30000, NULL)) 4351 return (-1); 4352 } 4353 4354 /* 4355 * Send the request header... 4356 */ 4357 4358 http->state = request; 4359 http->data_encoding = HTTP_ENCODING_FIELDS; 4360 4361 if (request == HTTP_STATE_POST || request == HTTP_STATE_PUT) 4362 http->state ++; 4363 4364 http->status = HTTP_STATUS_CONTINUE; 4365 4366#ifdef HAVE_SSL 4367 if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls) 4368 { 4369 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); 4370 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); 4371 } 4372#endif /* HAVE_SSL */ 4373 4374 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1) 4375 { 4376 http->status = HTTP_STATUS_ERROR; 4377 return (-1); 4378 } 4379 4380 for (i = 0; i < HTTP_FIELD_MAX; i ++) 4381 if ((value = httpGetField(http, i)) != NULL && *value) 4382 { 4383 DEBUG_printf(("5http_send: %s: %s", http_fields[i], value)); 4384 4385 if (i == HTTP_FIELD_HOST) 4386 { 4387 if (httpPrintf(http, "Host: %s:%d\r\n", value, 4388 httpAddrPort(http->hostaddr)) < 1) 4389 { 4390 http->status = HTTP_STATUS_ERROR; 4391 return (-1); 4392 } 4393 } 4394 else if (httpPrintf(http, "%s: %s\r\n", http_fields[i], value) < 1) 4395 { 4396 http->status = HTTP_STATUS_ERROR; 4397 return (-1); 4398 } 4399 } 4400 4401 if (http->cookie) 4402 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1) 4403 { 4404 http->status = HTTP_STATUS_ERROR; 4405 return (-1); 4406 } 4407 4408 DEBUG_printf(("5http_send: expect=%d, mode=%d, state=%d", http->expect, 4409 http->mode, http->state)); 4410 4411 if (http->expect == HTTP_STATUS_CONTINUE && http->mode == _HTTP_MODE_CLIENT && 4412 (http->state == HTTP_STATE_POST_RECV || 4413 http->state == HTTP_STATE_PUT_RECV)) 4414 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1) 4415 { 4416 http->status = HTTP_STATUS_ERROR; 4417 return (-1); 4418 } 4419 4420 if (httpPrintf(http, "\r\n") < 1) 4421 { 4422 http->status = HTTP_STATUS_ERROR; 4423 return (-1); 4424 } 4425 4426 if (httpFlushWrite(http) < 0) 4427 return (-1); 4428 4429 http_set_length(http); 4430 httpClearFields(http); 4431 4432 /* 4433 * The Kerberos and AuthRef authentication strings can only be used once... 4434 */ 4435 4436 if (http->field_authorization && http->authstring && 4437 (!strncmp(http->authstring, "Negotiate", 9) || 4438 !strncmp(http->authstring, "AuthRef", 7))) 4439 { 4440 http->_authstring[0] = '\0'; 4441 4442 if (http->authstring != http->_authstring) 4443 free(http->authstring); 4444 4445 http->authstring = http->_authstring; 4446 } 4447 4448 return (0); 4449} 4450 4451 4452/* 4453 * 'http_set_length()' - Set the data_encoding and data_remaining values. 4454 */ 4455 4456static off_t /* O - Remainder or -1 on error */ 4457http_set_length(http_t *http) /* I - Connection */ 4458{ 4459 off_t remaining; /* Remainder */ 4460 4461 4462 DEBUG_printf(("http_set_length(http=%p) mode=%d state=%s", http, http->mode, 4463 httpStateString(http->state))); 4464 4465 if ((remaining = httpGetLength2(http)) >= 0) 4466 { 4467 if (http->mode == _HTTP_MODE_SERVER && 4468 http->state != HTTP_STATE_GET_SEND && 4469 http->state != HTTP_STATE_PUT && 4470 http->state != HTTP_STATE_POST && 4471 http->state != HTTP_STATE_POST_SEND) 4472 { 4473 DEBUG_puts("1http_set_length: Not setting data_encoding/remaining."); 4474 return (remaining); 4475 } 4476 4477 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], 4478 "chunked")) 4479 { 4480 DEBUG_puts("1http_set_length: Setting data_encoding to " 4481 "HTTP_ENCODING_CHUNKED."); 4482 http->data_encoding = HTTP_ENCODING_CHUNKED; 4483 } 4484 else 4485 { 4486 DEBUG_puts("1http_set_length: Setting data_encoding to " 4487 "HTTP_ENCODING_LENGTH."); 4488 http->data_encoding = HTTP_ENCODING_LENGTH; 4489 } 4490 4491 DEBUG_printf(("1http_set_length: Setting data_remaining to " CUPS_LLFMT ".", 4492 CUPS_LLCAST remaining)); 4493 http->data_remaining = remaining; 4494 4495 if (remaining <= INT_MAX) 4496 http->_data_remaining = (int)remaining; 4497 else 4498 http->_data_remaining = INT_MAX; 4499 } 4500 4501 return (remaining); 4502} 4503 4504/* 4505 * 'http_set_timeout()' - Set the socket timeout values. 4506 */ 4507 4508static void 4509http_set_timeout(int fd, /* I - File descriptor */ 4510 double timeout) /* I - Timeout in seconds */ 4511{ 4512#ifdef WIN32 4513 DWORD tv = (DWORD)(timeout * 1000); 4514 /* Timeout in milliseconds */ 4515 4516 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv)); 4517 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv)); 4518 4519#else 4520 struct timeval tv; /* Timeout in secs and usecs */ 4521 4522 tv.tv_sec = (int)timeout; 4523 tv.tv_usec = (int)(1000000 * fmod(timeout, 1.0)); 4524 4525 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv)); 4526 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv)); 4527#endif /* WIN32 */ 4528} 4529 4530 4531/* 4532 * 'http_set_wait()' - Set the default wait value for reads. 4533 */ 4534 4535static void 4536http_set_wait(http_t *http) /* I - HTTP connection */ 4537{ 4538 if (http->blocking) 4539 { 4540 http->wait_value = (int)(http->timeout_value * 1000); 4541 4542 if (http->wait_value <= 0) 4543 http->wait_value = 60000; 4544 } 4545 else 4546 http->wait_value = 10000; 4547} 4548 4549 4550#ifdef HAVE_SSL 4551/* 4552 * 'http_tls_upgrade()' - Force upgrade to TLS encryption. 4553 */ 4554 4555static int /* O - Status of connection */ 4556http_tls_upgrade(http_t *http) /* I - HTTP connection */ 4557{ 4558 int ret; /* Return value */ 4559 http_t myhttp; /* Local copy of HTTP data */ 4560 4561 4562 DEBUG_printf(("7http_tls_upgrade(%p)", http)); 4563 4564 /* 4565 * Flush the connection to make sure any previous "Upgrade" message 4566 * has been read. 4567 */ 4568 4569 httpFlush(http); 4570 4571 /* 4572 * Copy the HTTP data to a local variable so we can do the OPTIONS 4573 * request without interfering with the existing request data... 4574 */ 4575 4576 memcpy(&myhttp, http, sizeof(myhttp)); 4577 4578 /* 4579 * Send an OPTIONS request to the server, requiring SSL or TLS 4580 * encryption on the link... 4581 */ 4582 4583 http->tls_upgrade = 1; 4584 http->field_authorization = NULL; /* Don't free the auth string */ 4585 4586 httpClearFields(http); 4587 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade"); 4588 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); 4589 4590 if ((ret = httpOptions(http, "*")) == 0) 4591 { 4592 /* 4593 * Wait for the secure connection... 4594 */ 4595 4596 while (httpUpdate(http) == HTTP_STATUS_CONTINUE); 4597 } 4598 4599 /* 4600 * Restore the HTTP request data... 4601 */ 4602 4603 memcpy(http->fields, myhttp.fields, sizeof(http->fields)); 4604 http->data_encoding = myhttp.data_encoding; 4605 http->data_remaining = myhttp.data_remaining; 4606 http->_data_remaining = myhttp._data_remaining; 4607 http->expect = myhttp.expect; 4608 http->field_authorization = myhttp.field_authorization; 4609 http->digest_tries = myhttp.digest_tries; 4610 http->tls_upgrade = 0; 4611 4612 /* 4613 * See if we actually went secure... 4614 */ 4615 4616 if (!http->tls) 4617 { 4618 /* 4619 * Server does not support HTTP upgrade... 4620 */ 4621 4622 DEBUG_puts("8http_tls_upgrade: Server does not support HTTP upgrade!"); 4623 4624 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, _("Encryption is not supported."), 1); 4625 httpAddrClose(NULL, http->fd); 4626 4627 http->fd = -1; 4628 4629 return (-1); 4630 } 4631 else 4632 return (ret); 4633} 4634#endif /* HAVE_SSL */ 4635 4636 4637/* 4638 * 'http_write()' - Write a buffer to a HTTP connection. 4639 */ 4640 4641static ssize_t /* O - Number of bytes written */ 4642http_write(http_t *http, /* I - HTTP connection */ 4643 const char *buffer, /* I - Buffer for data */ 4644 size_t length) /* I - Number of bytes to write */ 4645{ 4646 ssize_t tbytes, /* Total bytes sent */ 4647 bytes; /* Bytes sent */ 4648 4649 4650 DEBUG_printf(("2http_write(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http, 4651 buffer, CUPS_LLCAST length)); 4652 http->error = 0; 4653 tbytes = 0; 4654 4655 while (length > 0) 4656 { 4657 DEBUG_printf(("3http_write: About to write %d bytes.", (int)length)); 4658 4659 if (http->timeout_cb) 4660 { 4661#ifdef HAVE_POLL 4662 struct pollfd pfd; /* Polled file descriptor */ 4663#else 4664 fd_set output_set; /* Output ready for write? */ 4665 struct timeval timeout; /* Timeout value */ 4666#endif /* HAVE_POLL */ 4667 int nfds; /* Result from select()/poll() */ 4668 4669 do 4670 { 4671#ifdef HAVE_POLL 4672 pfd.fd = http->fd; 4673 pfd.events = POLLOUT; 4674 4675 while ((nfds = poll(&pfd, 1, http->wait_value)) < 0 && 4676 (errno == EINTR || errno == EAGAIN)) 4677 /* do nothing */; 4678 4679#else 4680 do 4681 { 4682 FD_ZERO(&output_set); 4683 FD_SET(http->fd, &output_set); 4684 4685 timeout.tv_sec = http->wait_value / 1000; 4686 timeout.tv_usec = 1000 * (http->wait_value % 1000); 4687 4688 nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout); 4689 } 4690# ifdef WIN32 4691 while (nfds < 0 && (WSAGetLastError() == WSAEINTR || 4692 WSAGetLastError() == WSAEWOULDBLOCK)); 4693# else 4694 while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); 4695# endif /* WIN32 */ 4696#endif /* HAVE_POLL */ 4697 4698 if (nfds < 0) 4699 { 4700 http->error = errno; 4701 return (-1); 4702 } 4703 else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data)) 4704 { 4705#ifdef WIN32 4706 http->error = WSAEWOULDBLOCK; 4707#else 4708 http->error = EWOULDBLOCK; 4709#endif /* WIN32 */ 4710 return (-1); 4711 } 4712 } 4713 while (nfds <= 0); 4714 } 4715 4716#ifdef HAVE_SSL 4717 if (http->tls) 4718 bytes = _httpTLSWrite(http, buffer, (int)length); 4719 else 4720#endif /* HAVE_SSL */ 4721 bytes = send(http->fd, buffer, length, 0); 4722 4723 DEBUG_printf(("3http_write: Write of " CUPS_LLFMT " bytes returned " 4724 CUPS_LLFMT ".", CUPS_LLCAST length, CUPS_LLCAST bytes)); 4725 4726 if (bytes < 0) 4727 { 4728#ifdef WIN32 4729 if (WSAGetLastError() == WSAEINTR) 4730 continue; 4731 else if (WSAGetLastError() == WSAEWOULDBLOCK) 4732 { 4733 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 4734 continue; 4735 4736 http->error = WSAGetLastError(); 4737 } 4738 else if (WSAGetLastError() != http->error && 4739 WSAGetLastError() != WSAECONNRESET) 4740 { 4741 http->error = WSAGetLastError(); 4742 continue; 4743 } 4744 4745#else 4746 if (errno == EINTR) 4747 continue; 4748 else if (errno == EWOULDBLOCK || errno == EAGAIN) 4749 { 4750 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 4751 continue; 4752 else if (!http->timeout_cb && errno == EAGAIN) 4753 continue; 4754 4755 http->error = errno; 4756 } 4757 else if (errno != http->error && errno != ECONNRESET) 4758 { 4759 http->error = errno; 4760 continue; 4761 } 4762#endif /* WIN32 */ 4763 4764 DEBUG_printf(("3http_write: error writing data (%s).", 4765 strerror(http->error))); 4766 4767 return (-1); 4768 } 4769 4770 buffer += bytes; 4771 tbytes += bytes; 4772 length -= (size_t)bytes; 4773 } 4774 4775#ifdef DEBUG 4776 http_debug_hex("http_write", buffer - tbytes, (int)tbytes); 4777#endif /* DEBUG */ 4778 4779 DEBUG_printf(("3http_write: Returning " CUPS_LLFMT ".", CUPS_LLCAST tbytes)); 4780 4781 return (tbytes); 4782} 4783 4784 4785/* 4786 * 'http_write_chunk()' - Write a chunked buffer. 4787 */ 4788 4789static ssize_t /* O - Number bytes written */ 4790http_write_chunk(http_t *http, /* I - HTTP connection */ 4791 const char *buffer, /* I - Buffer to write */ 4792 size_t length) /* I - Length of buffer */ 4793{ 4794 char header[16]; /* Chunk header */ 4795 ssize_t bytes; /* Bytes written */ 4796 4797 4798 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=" CUPS_LLFMT ")", 4799 http, buffer, CUPS_LLCAST length)); 4800 4801 /* 4802 * Write the chunk header, data, and trailer. 4803 */ 4804 4805 snprintf(header, sizeof(header), "%x\r\n", (unsigned)length); 4806 if (http_write(http, header, strlen(header)) < 0) 4807 { 4808 DEBUG_puts("8http_write_chunk: http_write of length failed."); 4809 return (-1); 4810 } 4811 4812 if ((bytes = http_write(http, buffer, length)) < 0) 4813 { 4814 DEBUG_puts("8http_write_chunk: http_write of buffer failed."); 4815 return (-1); 4816 } 4817 4818 if (http_write(http, "\r\n", 2) < 0) 4819 { 4820 DEBUG_puts("8http_write_chunk: http_write of CR LF failed."); 4821 return (-1); 4822 } 4823 4824 return (bytes); 4825} 4826 4827 4828/* 4829 * End of "$Id: http.c 12131 2014-08-28 23:38:16Z msweet $". 4830 */ 4831