PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - soap - php_http.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 754
Code covered: 3.3 % Executed lines: 25
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 5                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
      16                 :   |          Shane Caraveo <shane@caraveo.com>                           |
      17                 :   |          Dmitry Stogov <dmitry@zend.com>                             |
      18                 :   +----------------------------------------------------------------------+
      19                 : */
      20                 : /* $Id: php_http.c 281592 2009-06-03 12:41:46Z iliaa $ */
      21                 : 
      22                 : #include "php_soap.h"
      23                 : #include "ext/standard/base64.h"
      24                 : #include "ext/standard/md5.h"
      25                 : #include "ext/standard/php_rand.h"
      26                 : 
      27                 : static char *get_http_header_value(char *headers, char *type);
      28                 : static int get_http_body(php_stream *socketd, int close, char *headers,  char **response, int *out_size TSRMLS_DC);
      29                 : static int get_http_headers(php_stream *socketd,char **response, int *out_size TSRMLS_DC);
      30                 : 
      31                 : #define smart_str_append_const(str, const) \
      32                 :         smart_str_appendl(str,const,sizeof(const)-1)
      33                 : 
      34                 : static int stream_alive(php_stream *stream  TSRMLS_DC)
      35               0 : {
      36                 :         int socket;
      37                 :         char buf;
      38                 : 
      39                 :         /* maybe better to use:
      40                 :          * php_stream_set_option(stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL)
      41                 :          * here instead */
      42                 : 
      43               0 :         if (stream == NULL || stream->eof || php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void**)&socket, 0) != SUCCESS) {
      44               0 :                 return FALSE;
      45                 :         }
      46               0 :         if (socket == -1) {
      47               0 :                 return FALSE;
      48                 :         } else {
      49               0 :                 if (php_pollfd_for_ms(socket, PHP_POLLREADABLE, 0) > 0) {
      50               0 :                         if (0 == recv(socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
      51               0 :                                 return FALSE;
      52                 :                         }
      53                 :                 }
      54                 :         }
      55               0 :         return TRUE;
      56                 : }
      57                 : 
      58                 : /* Proxy HTTP Authentication */
      59                 : void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
      60               0 : {
      61                 :         zval **login, **password;
      62                 : 
      63               0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
      64                 :                 unsigned char* buf;
      65                 :                 int len;
      66               0 :                 smart_str auth = {0};
      67                 : 
      68               0 :                 smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
      69               0 :                 smart_str_appendc(&auth, ':');
      70               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password"), (void **)&password) == SUCCESS) {
      71               0 :                         smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
      72                 :                 }
      73               0 :                 smart_str_0(&auth);
      74               0 :                 buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
      75               0 :                 smart_str_append_const(soap_headers, "Proxy-Authorization: Basic ");
      76               0 :                 smart_str_appendl(soap_headers, (char*)buf, len);
      77               0 :                 smart_str_append_const(soap_headers, "\r\n");
      78               0 :                 efree(buf);
      79               0 :                 smart_str_free(&auth);
      80                 :         }
      81               0 : }
      82                 : 
      83                 : /* HTTP Authentication */
      84                 : void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
      85             695 : {
      86                 :         zval **login, **password;
      87                 : 
      88             695 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
      89                 :                         !zend_hash_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"))) {
      90                 :                 unsigned char* buf;
      91                 :                 int len;
      92               0 :                 smart_str auth = {0};
      93                 : 
      94               0 :                 smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
      95               0 :                 smart_str_appendc(&auth, ':');
      96               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS) {
      97               0 :                         smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
      98                 :                 }
      99               0 :                 smart_str_0(&auth);
     100               0 :                 buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
     101               0 :                 smart_str_append_const(soap_headers, "Authorization: Basic ");
     102               0 :                 smart_str_appendl(soap_headers, (char*)buf, len);
     103               0 :                 smart_str_append_const(soap_headers, "\r\n");
     104               0 :                 efree(buf);
     105               0 :                 smart_str_free(&auth);
     106                 :         }
     107             695 : }
     108                 : 
     109                 : static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, int *use_proxy TSRMLS_DC)
     110               0 : {
     111                 :         php_stream *stream;
     112                 :         zval **proxy_host, **proxy_port, **tmp;
     113                 :         char *host;
     114               0 :         php_stream_context *context = NULL;
     115                 :         char *name;
     116                 :         long namelen;
     117                 :         int port;
     118                 :         int old_error_reporting;
     119                 :         struct timeval tv;
     120               0 :         struct timeval *timeout = NULL;
     121                 : 
     122               0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
     123                 :             Z_TYPE_PP(proxy_host) == IS_STRING &&
     124                 :             zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
     125                 :             Z_TYPE_PP(proxy_port) == IS_LONG) {
     126               0 :                 host = Z_STRVAL_PP(proxy_host);
     127               0 :                 port = Z_LVAL_PP(proxy_port);
     128               0 :                 *use_proxy = 1;
     129                 :         } else {
     130               0 :                 host = phpurl->host;
     131               0 :                 port = phpurl->port;
     132                 :         }
     133               0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_connection_timeout", sizeof("_connection_timeout"), (void **) &tmp) == SUCCESS &&
     134                 :             Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) > 0) {
     135               0 :           tv.tv_sec = Z_LVAL_PP(tmp);
     136               0 :           tv.tv_usec = 0;
     137               0 :                 timeout = &tv;
     138                 :         }
     139                 : 
     140               0 :         old_error_reporting = EG(error_reporting);
     141               0 :         EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
     142                 : 
     143               0 :         if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
     144                 :                         "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
     145               0 :                 context = php_stream_context_from_zval(*tmp, 0);
     146                 :         }
     147                 : 
     148               0 :         namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
     149                 : 
     150               0 :         stream = php_stream_xport_create(name, namelen,
     151                 :                 ENFORCE_SAFE_MODE | REPORT_ERRORS,
     152                 :                 STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
     153                 :                 NULL /*persistent_id*/,
     154                 :                 timeout,
     155                 :                 context,
     156                 :                 NULL, NULL);
     157               0 :         efree(name);
     158                 : 
     159                 :         /* SSL & proxy */
     160               0 :         if (stream && *use_proxy && use_ssl) {
     161               0 :                 smart_str soap_headers = {0};
     162                 :                 char *http_headers;
     163                 :                 int http_header_size;
     164                 : 
     165               0 :                 smart_str_append_const(&soap_headers, "CONNECT ");
     166               0 :                 smart_str_appends(&soap_headers, phpurl->host);
     167               0 :                 smart_str_appendc(&soap_headers, ':');
     168               0 :                 smart_str_append_unsigned(&soap_headers, phpurl->port);
     169               0 :                 smart_str_append_const(&soap_headers, " HTTP/1.1\r\n");
     170               0 :                 proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
     171               0 :                 smart_str_append_const(&soap_headers, "\r\n");
     172               0 :                 if (php_stream_write(stream, soap_headers.c, soap_headers.len) != soap_headers.len) {
     173               0 :                         php_stream_close(stream);
     174               0 :                         stream = NULL;
     175                 :                 }
     176               0 :                 smart_str_free(&soap_headers);
     177                 : 
     178               0 :                 if (stream) {
     179               0 :                         if (!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC) || http_headers == NULL) {
     180               0 :                                 php_stream_close(stream);
     181               0 :                                 stream = NULL;
     182                 :                         }
     183               0 :                         if (http_headers) {
     184               0 :                                 efree(http_headers);
     185                 :                         }
     186                 :                 }
     187                 :                 /* enable SSL transport layer */
     188               0 :                 if (stream) {
     189               0 :                         if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
     190                 :                             php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
     191               0 :                                 php_stream_close(stream);
     192               0 :                                 stream = NULL;
     193                 :                         }
     194                 :                 }
     195                 :         }
     196                 : 
     197               0 :         EG(error_reporting) = old_error_reporting;
     198               0 :         return stream;
     199                 : }
     200                 : 
     201                 : static int in_domain(const char *host, const char *domain)
     202               0 : {
     203               0 :   if (domain[0] == '.') {
     204               0 :     int l1 = strlen(host);
     205               0 :     int l2 = strlen(domain);
     206               0 :     if (l1 > l2) {
     207               0 :         return strcmp(host+l1-l2,domain) == 0;
     208                 :     } else {
     209               0 :       return 0;
     210                 :     }
     211                 :   } else {
     212               0 :     return strcmp(host,domain) == 0;
     213                 :   }
     214                 : }
     215                 : 
     216                 : int make_http_soap_request(zval  *this_ptr,
     217                 :                            char  *buf,
     218                 :                            int    buf_size,
     219                 :                            char  *location,
     220                 :                            char  *soapaction,
     221                 :                            int    soap_version,
     222                 :                            char **buffer,
     223                 :                            int   *buffer_len TSRMLS_DC)
     224             315 : {
     225                 :         char *request;
     226             315 :         smart_str soap_headers = {0};
     227             315 :         smart_str soap_headers_z = {0};
     228                 :         int request_size, err;
     229             315 :         php_url *phpurl = NULL;
     230                 :         php_stream *stream;
     231                 :         zval **trace, **tmp;
     232             315 :         int use_proxy = 0;
     233                 :         int use_ssl;
     234                 :         char *http_headers, *http_body, *content_type, *http_version, *cookie_itt;
     235                 :         int http_header_size, http_body_size, http_close;
     236                 :         char *connection;
     237                 :         int http_1_1;
     238                 :         int http_status;
     239             315 :         int content_type_xml = 0;
     240                 :         char *content_encoding;
     241             315 :         char *http_msg = NULL;
     242                 :         zend_bool old_allow_url_fopen;
     243                 : 
     244             315 :         if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) {
     245               0 :                 return FALSE;
     246                 :         }
     247                 : 
     248             315 :   request = buf;
     249             315 :   request_size = buf_size;
     250                 :         /* Compress request */
     251             315 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "compression", sizeof("compression"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
     252               0 :                 int level = Z_LVAL_PP(tmp) & 0x0f;
     253               0 :                 int kind  = Z_LVAL_PP(tmp) & SOAP_COMPRESSION_DEFLATE;
     254                 : 
     255               0 :                 if (level > 9) {level = 9;}
     256                 :                 
     257               0 :           if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) {
     258               0 :                         smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n");
     259                 :           }
     260               0 :           if (level > 0) {
     261                 :                         zval func;
     262                 :                         zval retval;
     263                 :                         zval param1, param2, param3;
     264                 :                         zval *params[3];
     265                 :                         int n;
     266                 : 
     267               0 :                         params[0] = &param1;
     268               0 :                         INIT_PZVAL(params[0]);
     269               0 :                         params[1] = &param2;
     270               0 :                         INIT_PZVAL(params[1]);
     271               0 :                         params[2] = &param3;
     272               0 :                         INIT_PZVAL(params[2]);
     273               0 :                         ZVAL_STRINGL(params[0], buf, buf_size, 0);
     274               0 :                         ZVAL_LONG(params[1], level);
     275               0 :             if (kind == SOAP_COMPRESSION_DEFLATE) {
     276               0 :                 n = 2;
     277               0 :                                 ZVAL_STRING(&func, "gzcompress", 0);
     278               0 :                                 smart_str_append_const(&soap_headers_z,"Content-Encoding: deflate\r\n");
     279                 :             } else {
     280               0 :               n = 3;
     281               0 :                                 ZVAL_STRING(&func, "gzencode", 0);
     282               0 :                                 smart_str_append_const(&soap_headers_z,"Content-Encoding: gzip\r\n");
     283               0 :                                 ZVAL_LONG(params[2], 1);
     284                 :             }
     285               0 :                         if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, n, params TSRMLS_CC) == SUCCESS &&
     286                 :                             Z_TYPE(retval) == IS_STRING) {
     287               0 :                                 request = Z_STRVAL(retval);
     288               0 :                                 request_size = Z_STRLEN(retval);
     289                 :                         } else {
     290               0 :                                 if (request != buf) {efree(request);}
     291               0 :                                 smart_str_free(&soap_headers_z);
     292               0 :                                 return FALSE;
     293                 :                         }
     294                 :           }
     295                 :         }
     296                 : 
     297             315 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"), (void **)&tmp) == SUCCESS) {
     298               0 :                 php_stream_from_zval_no_verify(stream,tmp);
     299               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
     300               0 :                         use_proxy = Z_LVAL_PP(tmp);
     301                 :                 }
     302                 :         } else {
     303             315 :                 stream = NULL;
     304                 :         }
     305                 : 
     306             315 :         if (location != NULL && location[0] != '\000') {
     307             315 :                 phpurl = php_url_parse(location);
     308                 :         }
     309                 : 
     310             315 : try_again:
     311             315 :         if (phpurl == NULL || phpurl->host == NULL) {
     312             315 :           if (phpurl != NULL) {php_url_free(phpurl);}
     313             315 :                 if (request != buf) {efree(request);}
     314             315 :                 add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL TSRMLS_CC);
     315             315 :                 smart_str_free(&soap_headers_z);
     316             315 :                 return FALSE;
     317                 :         }
     318                 : 
     319               0 :         use_ssl = 0;
     320               0 :         if (phpurl->scheme != NULL && strcmp(phpurl->scheme, "https") == 0) {
     321               0 :                 use_ssl = 1;
     322               0 :         } else if (phpurl->scheme == NULL || strcmp(phpurl->scheme, "http") != 0) {
     323               0 :                 php_url_free(phpurl);
     324               0 :                 if (request != buf) {efree(request);}
     325               0 :                 add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL TSRMLS_CC);
     326               0 :                 smart_str_free(&soap_headers_z);
     327               0 :                 return FALSE;
     328                 :         }
     329                 : 
     330               0 :         old_allow_url_fopen = PG(allow_url_fopen);
     331               0 :         PG(allow_url_fopen) = 1;
     332               0 :         if (use_ssl && php_stream_locate_url_wrapper("https://", NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) == NULL) {
     333               0 :                 php_url_free(phpurl);
     334               0 :                 if (request != buf) {efree(request);}
     335               0 :                 add_soap_fault(this_ptr, "HTTP", "SSL support is not available in this build", NULL, NULL TSRMLS_CC);
     336               0 :                 PG(allow_url_fopen) = old_allow_url_fopen;
     337               0 :                 smart_str_free(&soap_headers_z);
     338               0 :                 return FALSE;
     339                 :         }
     340                 : 
     341               0 :         if (phpurl->port == 0) {
     342               0 :                 phpurl->port = use_ssl ? 443 : 80;
     343                 :         }
     344                 : 
     345                 :         /* Check if request to the same host */
     346               0 :         if (stream != NULL) {
     347                 :           php_url *orig;
     348               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"), (void **)&tmp) == SUCCESS &&
     349                 :                     (orig = (php_url *) zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url)) != NULL &&
     350                 :                     ((use_proxy && !use_ssl) ||
     351                 :                      (((use_ssl && orig->scheme != NULL && strcmp(orig->scheme, "https") == 0) ||
     352                 :                       (!use_ssl && orig->scheme == NULL) ||
     353                 :                       (!use_ssl && strcmp(orig->scheme, "https") != 0)) &&
     354                 :                      strcmp(orig->host, phpurl->host) == 0 &&
     355                 :                      orig->port == phpurl->port))) {
     356                 :     } else {
     357               0 :                         php_stream_close(stream);
     358               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
     359               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     360               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     361               0 :                         stream = NULL;
     362               0 :                         use_proxy = 0;
     363                 :     }
     364                 :         }
     365                 : 
     366                 :         /* Check if keep-alive connection is still opened */
     367               0 :         if (stream != NULL && !stream_alive(stream TSRMLS_CC)) {
     368               0 :                 php_stream_close(stream);
     369               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
     370               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     371               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     372               0 :                 stream = NULL;
     373               0 :                 use_proxy = 0;
     374                 :         }
     375                 : 
     376               0 :         if (!stream) {
     377               0 :                 stream = http_connect(this_ptr, phpurl, use_ssl, &use_proxy TSRMLS_CC);
     378               0 :                 if (stream) {
     379                 :                         php_stream_auto_cleanup(stream);
     380               0 :                         add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream));
     381               0 :                         add_property_long(this_ptr, "_use_proxy", use_proxy);
     382                 :                 } else {
     383               0 :                         php_url_free(phpurl);
     384               0 :                         if (request != buf) {efree(request);}
     385               0 :                         add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL TSRMLS_CC);
     386               0 :                         PG(allow_url_fopen) = old_allow_url_fopen;
     387               0 :                         smart_str_free(&soap_headers_z);
     388               0 :                         return FALSE;
     389                 :                 }
     390                 :         }
     391               0 :         PG(allow_url_fopen) = old_allow_url_fopen;
     392                 : 
     393               0 :         if (stream) {
     394                 :                 zval **cookies, **login, **password;
     395               0 :           int ret = zend_list_insert(phpurl, le_url);
     396                 : 
     397               0 :                 add_property_resource(this_ptr, "httpurl", ret);
     398                 :                 /*zend_list_addref(ret);*/
     399                 : 
     400               0 :                 smart_str_append_const(&soap_headers, "POST ");
     401               0 :                 if (use_proxy && !use_ssl) {
     402               0 :                         smart_str_appends(&soap_headers, phpurl->scheme);
     403               0 :                         smart_str_append_const(&soap_headers, "://");
     404               0 :                         smart_str_appends(&soap_headers, phpurl->host);
     405               0 :                         smart_str_appendc(&soap_headers, ':');
     406               0 :                         smart_str_append_unsigned(&soap_headers, phpurl->port);
     407                 :                 }
     408               0 :                 if (phpurl->path) {
     409               0 :                         smart_str_appends(&soap_headers, phpurl->path);
     410                 :                 } else {
     411               0 :                         smart_str_appendc(&soap_headers, '/');
     412                 :                 }
     413               0 :                 if (phpurl->query) {
     414               0 :                         smart_str_appendc(&soap_headers, '?');
     415               0 :                         smart_str_appends(&soap_headers, phpurl->query);
     416                 :                 }
     417               0 :                 if (phpurl->fragment) {
     418               0 :                         smart_str_appendc(&soap_headers, '#');
     419               0 :                         smart_str_appends(&soap_headers, phpurl->fragment);
     420                 :                 }
     421               0 :                 smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"
     422                 :                         "Host: ");
     423               0 :                 smart_str_appends(&soap_headers, phpurl->host);
     424               0 :                 if (phpurl->port != (use_ssl?443:80)) {
     425               0 :                         smart_str_appendc(&soap_headers, ':');
     426               0 :                         smart_str_append_unsigned(&soap_headers, phpurl->port);
     427                 :                 }
     428               0 :                 smart_str_append_const(&soap_headers, "\r\n"
     429                 :                         "Connection: Keep-Alive\r\n");
     430                 : /*
     431                 :                         "Connection: close\r\n"
     432                 :                         "Accept: text/html; text/xml; text/plain\r\n"
     433                 : */
     434               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **)&tmp) == SUCCESS &&
     435                 :                     Z_TYPE_PP(tmp) == IS_STRING) {
     436               0 :                         if (Z_STRLEN_PP(tmp) > 0) {
     437               0 :                                 smart_str_append_const(&soap_headers, "User-Agent: ");
     438               0 :                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     439               0 :                                 smart_str_append_const(&soap_headers, "\r\n");
     440                 :                         }
     441               0 :                 } else if (FG(user_agent)) {
     442               0 :                         smart_str_append_const(&soap_headers, "User-Agent: ");
     443               0 :                         smart_str_appends(&soap_headers, FG(user_agent));
     444               0 :                         smart_str_append_const(&soap_headers, "\r\n");
     445                 :                 } else {
     446               0 :                         smart_str_append_const(&soap_headers, "User-Agent: PHP-SOAP/"PHP_VERSION"\r\n");
     447                 :                 }
     448                 : 
     449               0 :                 smart_str_append(&soap_headers, &soap_headers_z);
     450                 : 
     451               0 :                 if (soap_version == SOAP_1_2) {
     452               0 :                         smart_str_append_const(&soap_headers,"Content-Type: application/soap+xml; charset=utf-8");
     453               0 :                         if (soapaction) {
     454               0 :                                 smart_str_append_const(&soap_headers,"; action=\"");
     455               0 :                                 smart_str_appends(&soap_headers, soapaction);
     456               0 :                                 smart_str_append_const(&soap_headers,"\"");
     457                 :                         }
     458               0 :                         smart_str_append_const(&soap_headers,"\r\n");
     459                 :                 } else {
     460               0 :                         smart_str_append_const(&soap_headers,"Content-Type: text/xml; charset=utf-8\r\n");
     461               0 :                         if (soapaction) {
     462               0 :                                 smart_str_append_const(&soap_headers, "SOAPAction: \"");
     463               0 :                                 smart_str_appends(&soap_headers, soapaction);
     464               0 :                                 smart_str_append_const(&soap_headers, "\"\r\n");
     465                 :                         }
     466                 :                 }
     467               0 :                 smart_str_append_const(&soap_headers,"Content-Length: ");
     468               0 :                 smart_str_append_long(&soap_headers, request_size);
     469               0 :                 smart_str_append_const(&soap_headers, "\r\n");
     470                 : 
     471                 :                 /* HTTP Authentication */
     472               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
     473                 :                     Z_TYPE_PP(login) == IS_STRING) {
     474                 :                         zval **digest;
     475                 : 
     476               0 :                         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == SUCCESS) {
     477               0 :                                 if (Z_TYPE_PP(digest) == IS_ARRAY) {
     478                 :                                         char          HA1[33], HA2[33], response[33], cnonce[33], nc[9];
     479                 :                                         PHP_MD5_CTX   md5ctx;
     480                 :                                         unsigned char hash[16];
     481                 : 
     482               0 :                                         PHP_MD5Init(&md5ctx);
     483               0 :                                         snprintf(cnonce, sizeof(cnonce), "%ld", php_rand(TSRMLS_C));
     484               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce));
     485               0 :                                         PHP_MD5Final(hash, &md5ctx);
     486               0 :                                         make_digest(cnonce, hash);
     487                 : 
     488               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "nc", sizeof("nc"), (void **)&tmp) == SUCCESS &&
     489                 :                                             Z_TYPE_PP(tmp) == IS_LONG) {
     490               0 :                                                 Z_LVAL_PP(tmp)++;
     491               0 :                                                 snprintf(nc, sizeof(nc), "%08ld", Z_LVAL_PP(tmp));
     492                 :                                         } else {
     493               0 :                                                 add_assoc_long(*digest, "nc", 1);
     494               0 :                                                 strcpy(nc, "00000001");
     495                 :                                         }
     496                 : 
     497               0 :                                         PHP_MD5Init(&md5ctx);
     498               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(login), Z_STRLEN_PP(login));
     499               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     500               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
     501                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     502               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     503                 :                                         }
     504               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     505               0 :                                         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
     506                 :                                             Z_TYPE_PP(password) == IS_STRING) {
     507               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(password), Z_STRLEN_PP(password));
     508                 :                                         }
     509               0 :                                         PHP_MD5Final(hash, &md5ctx);
     510               0 :                                         make_digest(HA1, hash);
     511               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "algorithm", sizeof("algorithm"), (void **)&tmp) == SUCCESS &&
     512                 :                                             Z_TYPE_PP(tmp) == IS_STRING &&
     513                 :                                             Z_STRLEN_PP(tmp) == sizeof("md5-sess")-1 &&
     514                 :                                             stricmp(Z_STRVAL_PP(tmp), "md5-sess") == 0) {
     515               0 :                                                 PHP_MD5Init(&md5ctx);
     516               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
     517               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     518               0 :                                                 if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
     519                 :                                                     Z_TYPE_PP(tmp) == IS_STRING) {
     520               0 :                                                         PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     521                 :                                                 }
     522               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     523               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
     524               0 :                                                 PHP_MD5Final(hash, &md5ctx);
     525               0 :                                                 make_digest(HA1, hash);
     526                 :                                         }
     527                 : 
     528               0 :                                         PHP_MD5Init(&md5ctx);
     529               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)"POST:", sizeof("POST:")-1);
     530               0 :                                         if (phpurl->path) {
     531               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)phpurl->path, strlen(phpurl->path));
     532                 :                                         } else {
     533               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)"/", 1);
     534                 :                                         }
     535               0 :                                         if (phpurl->query) {
     536               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)"?", 1);
     537               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)phpurl->query, strlen(phpurl->query));
     538                 :                                         }
     539                 : 
     540                 :                                         /* TODO: Support for qop="auth-int" */
     541                 : /*
     542                 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
     543                 :                                             Z_TYPE_PP(tmp) == IS_STRING &&
     544                 :                                             Z_STRLEN_PP(tmp) == sizeof("auth-int")-1 &&
     545                 :                                             stricmp(Z_STRVAL_PP(tmp), "auth-int") == 0) {
     546                 :                                                 PHP_MD5Update(&md5ctx, ":", 1);
     547                 :                                                 PHP_MD5Update(&md5ctx, HEntity, HASHHEXLEN);
     548                 :                                         }
     549                 : */
     550               0 :                                         PHP_MD5Final(hash, &md5ctx);
     551               0 :                                         make_digest(HA2, hash);
     552                 : 
     553               0 :                                         PHP_MD5Init(&md5ctx);
     554               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
     555               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     556               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
     557                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     558               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     559                 :                                         }
     560               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     561               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
     562                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     563               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)nc, 8);
     564               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     565               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
     566               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     567                 :                                                 /* TODO: Support for qop="auth-int" */
     568               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)"auth", sizeof("auth")-1);
     569               0 :                                                 PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
     570                 :                                         }
     571               0 :                                         PHP_MD5Update(&md5ctx, (unsigned char*)HA2, 32);
     572               0 :                                         PHP_MD5Final(hash, &md5ctx);
     573               0 :                                         make_digest(response, hash);
     574                 :         
     575               0 :                                         smart_str_append_const(&soap_headers, "Authorization: Digest username=\"");
     576               0 :                                         smart_str_appendl(&soap_headers, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
     577               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
     578                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     579               0 :                                                 smart_str_append_const(&soap_headers, "\", realm=\"");
     580               0 :                                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     581                 :                                         }
     582               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
     583                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     584               0 :                                                 smart_str_append_const(&soap_headers, "\", nonce=\"");
     585               0 :                                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     586                 :                                         }
     587               0 :                                         smart_str_append_const(&soap_headers, "\", uri=\"");
     588               0 :                                         if (phpurl->path) {
     589               0 :                                                 smart_str_appends(&soap_headers, phpurl->path);
     590                 :                                         } else {
     591               0 :                                                 smart_str_appendc(&soap_headers, '/');
     592                 :                                         } 
     593               0 :                                         if (phpurl->query) {
     594               0 :                                                 smart_str_appendc(&soap_headers, '?');
     595               0 :                                                 smart_str_appends(&soap_headers, phpurl->query);
     596                 :                                         }
     597               0 :                                         if (phpurl->fragment) {
     598               0 :                                                 smart_str_appendc(&soap_headers, '#');
     599               0 :                                                 smart_str_appends(&soap_headers, phpurl->fragment);
     600                 :                                         }
     601               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
     602                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     603                 :                                         /* TODO: Support for qop="auth-int" */
     604               0 :                                                 smart_str_append_const(&soap_headers, "\", qop=\"auth");
     605               0 :                                                 smart_str_append_const(&soap_headers, "\", nc=\"");
     606               0 :                                                 smart_str_appendl(&soap_headers, nc, 8);
     607               0 :                                                 smart_str_append_const(&soap_headers, "\", cnonce=\"");
     608               0 :                                                 smart_str_appendl(&soap_headers, cnonce, 8);
     609                 :                                         }
     610               0 :                                         smart_str_append_const(&soap_headers, "\", response=\"");
     611               0 :                                         smart_str_appendl(&soap_headers, response, 32);
     612               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "opaque", sizeof("opaque"), (void **)&tmp) == SUCCESS &&
     613                 :                                             Z_TYPE_PP(tmp) == IS_STRING) {
     614               0 :                                                 smart_str_append_const(&soap_headers, "\", opaque=\"");
     615               0 :                                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     616                 :                                         }
     617               0 :                                         if (zend_hash_find(Z_ARRVAL_PP(digest), "algorithm", sizeof("algorithm"), (void **)&tmp) == SUCCESS &&
     618                 :                                                 Z_TYPE_PP(tmp) == IS_STRING) {
     619               0 :                                                 smart_str_append_const(&soap_headers, "\", algorithm=\"");
     620               0 :                                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     621                 :                                         }
     622               0 :                                         smart_str_append_const(&soap_headers, "\"\r\n");
     623                 :                                 }
     624                 :                         } else {
     625                 :                                 unsigned char* buf;
     626                 :                                 int len;
     627                 : 
     628               0 :                                 smart_str auth = {0};
     629               0 :                                 smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
     630               0 :                                 smart_str_appendc(&auth, ':');
     631               0 :                                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
     632                 :                                     Z_TYPE_PP(password) == IS_STRING) {
     633               0 :                                         smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
     634                 :                                 }
     635               0 :                                 smart_str_0(&auth);
     636               0 :                                 buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
     637               0 :                                 smart_str_append_const(&soap_headers, "Authorization: Basic ");
     638               0 :                                 smart_str_appendl(&soap_headers, (char*)buf, len);
     639               0 :                                 smart_str_append_const(&soap_headers, "\r\n");
     640               0 :                                 efree(buf);
     641               0 :                                 smart_str_free(&auth);
     642                 :                         }
     643                 :                 }
     644                 : 
     645                 :                 /* Proxy HTTP Authentication */
     646               0 :                 if (use_proxy && !use_ssl) {
     647               0 :                         proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
     648                 :                 }
     649                 : 
     650                 :                 /* Send cookies along with request */
     651               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
     652                 :                         zval **data;
     653                 :                         char *key;
     654                 :                         int i, n;
     655                 : 
     656               0 :                         n = zend_hash_num_elements(Z_ARRVAL_PP(cookies));
     657               0 :                         if (n > 0) {
     658               0 :                                 zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
     659               0 :                                 smart_str_append_const(&soap_headers, "Cookie: ");
     660               0 :                                 for (i = 0; i < n; i++) {
     661               0 :                                         zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
     662               0 :                                         zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
     663                 : 
     664               0 :                                         if (Z_TYPE_PP(data) == IS_ARRAY) {
     665                 :                                           zval** value;
     666                 : 
     667               0 :                                                 if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS &&
     668                 :                                                     Z_TYPE_PP(value) == IS_STRING) {
     669                 :                                                   zval **tmp;
     670               0 :                                                   if ((zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == FAILURE ||
     671                 :                                                        strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0) &&
     672                 :                                                       (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE ||
     673                 :                                                        in_domain(phpurl->host,Z_STRVAL_PP(tmp))) &&
     674                 :                                                       (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) {
     675               0 :                                                                 smart_str_appendl(&soap_headers, key, strlen(key));
     676               0 :                                                                 smart_str_appendc(&soap_headers, '=');
     677               0 :                                                                 smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
     678               0 :                                                                 smart_str_appendc(&soap_headers, ';');
     679                 :                                                         }
     680                 :                                                 }
     681                 :                                         }
     682               0 :                                         zend_hash_move_forward(Z_ARRVAL_PP(cookies));
     683                 :                                 }
     684               0 :                                 smart_str_append_const(&soap_headers, "\r\n");
     685                 :                         }
     686                 :                 }
     687               0 :                 smart_str_append_const(&soap_headers, "\r\n");
     688               0 :                 smart_str_0(&soap_headers);
     689               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
     690                 :                     Z_LVAL_PP(trace) > 0) {
     691               0 :                         add_property_stringl(this_ptr, "__last_request_headers", soap_headers.c, soap_headers.len, 1);
     692                 :                 }
     693               0 :                 smart_str_appendl(&soap_headers, request, request_size);
     694               0 :                 smart_str_0(&soap_headers);
     695                 : 
     696               0 :                 err = php_stream_write(stream, soap_headers.c, soap_headers.len);
     697               0 :                 if (err != soap_headers.len) {
     698               0 :                         if (request != buf) {efree(request);}
     699               0 :                         smart_str_free(&soap_headers);
     700               0 :                         php_stream_close(stream);
     701               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
     702               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     703               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     704               0 :                         add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
     705               0 :                         return FALSE;
     706                 :                 }
     707               0 :                 smart_str_free(&soap_headers);
     708                 : 
     709                 :         } else {
     710               0 :                 add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL TSRMLS_CC);
     711               0 :                 smart_str_free(&soap_headers_z);
     712               0 :                 return FALSE;
     713                 :         }
     714                 : 
     715               0 :         if (!buffer) {
     716               0 :                 php_stream_close(stream);
     717               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     718               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     719               0 :                 smart_str_free(&soap_headers_z);
     720               0 :                 return TRUE;
     721                 :         }
     722                 : 
     723                 :         do {
     724               0 :                 if (!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) {
     725               0 :                         if (http_headers) {efree(http_headers);}
     726               0 :                         if (request != buf) {efree(request);}
     727               0 :                         php_stream_close(stream);
     728               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     729               0 :                         zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     730               0 :                         add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
     731               0 :                         smart_str_free(&soap_headers_z);
     732               0 :                         return FALSE;
     733                 :                 }
     734                 : 
     735               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
     736                 :                     Z_LVAL_PP(trace) > 0) {
     737               0 :                         add_property_stringl(this_ptr, "__last_response_headers", http_headers, http_header_size, 1);
     738                 :                 }
     739                 : 
     740                 :                 /* Check to see what HTTP status was sent */
     741               0 :                 http_1_1 = 0;
     742               0 :                 http_status = 0;
     743               0 :                 http_version = get_http_header_value(http_headers,"HTTP/");
     744               0 :                 if (http_version) {
     745                 :                         char *tmp;
     746                 : 
     747               0 :                         if (!strncmp(http_version,"1.1", 3)) {
     748               0 :                                 http_1_1 = 1;
     749                 :                         }
     750                 : 
     751               0 :                         tmp = strstr(http_version," ");
     752               0 :                         if (tmp != NULL) {
     753               0 :                                 tmp++;
     754               0 :                                 http_status = atoi(tmp);
     755                 :                         }
     756               0 :                         tmp = strstr(tmp," ");
     757               0 :                         if (tmp != NULL) {
     758               0 :                                 tmp++;
     759               0 :                                 if (http_msg) {
     760               0 :                                         efree(http_msg);
     761                 :                                 }
     762               0 :                                 http_msg = estrdup(tmp);
     763                 :                         }
     764               0 :                         efree(http_version);
     765                 : 
     766                 :                         /* Try and get headers again */
     767               0 :                         if (http_status == 100) {
     768               0 :                                 efree(http_headers);
     769                 :                         }
     770                 :                 }
     771               0 :         } while (http_status == 100);
     772                 : 
     773                 :         /* Grab and send back every cookie */
     774                 : 
     775                 :         /* Not going to worry about Path: because
     776                 :            we shouldn't be changing urls so path dont
     777                 :            matter too much
     778                 :         */
     779               0 :         cookie_itt = strstr(http_headers,"Set-Cookie: ");
     780               0 :         while (cookie_itt) {
     781                 :                 char *end_pos, *cookie;
     782                 :                 char *eqpos, *sempos;
     783                 :                 zval **cookies;
     784                 : 
     785               0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
     786                 :                         zval *tmp_cookies;
     787               0 :                         MAKE_STD_ZVAL(tmp_cookies);
     788               0 :                         array_init(tmp_cookies);
     789               0 :                         zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
     790                 :                 }
     791                 : 
     792               0 :                 end_pos = strstr(cookie_itt,"\r\n");
     793               0 :                 cookie = get_http_header_value(cookie_itt,"Set-Cookie: ");
     794                 : 
     795               0 :                 eqpos = strstr(cookie, "=");
     796               0 :                 sempos = strstr(cookie, ";");
     797               0 :                 if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) {
     798               0 :                         smart_str name = {0};
     799                 :                         int cookie_len;
     800                 :                         zval *zcookie;
     801                 : 
     802               0 :                         if (sempos != NULL) {
     803               0 :                                 cookie_len = sempos-(eqpos+1);
     804                 :                         } else {
     805               0 :                                 cookie_len = strlen(cookie)-(eqpos-cookie)-1;
     806                 :                         }
     807                 : 
     808               0 :                         smart_str_appendl(&name, cookie, eqpos - cookie);
     809               0 :                         smart_str_0(&name);
     810                 : 
     811               0 :                         ALLOC_INIT_ZVAL(zcookie);
     812               0 :                         array_init(zcookie);
     813               0 :                         add_index_stringl(zcookie, 0, eqpos + 1, cookie_len, 1);
     814                 : 
     815               0 :                         if (sempos != NULL) {
     816               0 :                                 char *options = cookie + cookie_len+1;
     817               0 :                                 while (*options) {
     818               0 :                                         while (*options == ' ') {options++;}
     819               0 :                                         sempos = strstr(options, ";");
     820               0 :                                         if (strstr(options,"path=") == options) {
     821               0 :                                                 eqpos = options + sizeof("path=")-1;
     822               0 :                                                 add_index_stringl(zcookie, 1, eqpos, sempos?(sempos-eqpos):strlen(eqpos), 1);
     823               0 :                                         } else if (strstr(options,"domain=") == options) {
     824               0 :                                                 eqpos = options + sizeof("domain=")-1;
     825               0 :                                                 add_index_stringl(zcookie, 2, eqpos, sempos?(sempos-eqpos):strlen(eqpos), 1);
     826               0 :                                         } else if (strstr(options,"secure") == options) {
     827               0 :                                                 add_index_bool(zcookie, 3, 1);
     828                 :                                         }
     829               0 :                                         if (sempos != NULL) {
     830               0 :                                                 options = sempos+1;
     831                 :                                         } else {
     832               0 :                                           break;
     833                 :                                         }
     834                 :                                 }
     835                 :                         }
     836               0 :                         if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 1)) {
     837               0 :                                 char *t = phpurl->path?phpurl->path:"/";
     838               0 :                                 char *c = strrchr(t, '/');
     839               0 :                                 if (c) {
     840               0 :                                         add_index_stringl(zcookie, 1, t, c-t, 1);
     841                 :                                 }
     842                 :                         }
     843               0 :                         if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 2)) {
     844               0 :                                 add_index_string(zcookie, 2, phpurl->host, 1);
     845                 :                         }
     846                 : 
     847               0 :                         add_assoc_zval_ex(*cookies, name.c, name.len+1, zcookie);
     848               0 :                         smart_str_free(&name);
     849                 :                 }
     850                 : 
     851               0 :                 cookie_itt = strstr(cookie_itt + sizeof("Set-Cookie: "), "Set-Cookie: ");
     852               0 :                 efree(cookie);
     853                 :         }
     854                 : 
     855               0 :         if (http_1_1) {
     856               0 :                 http_close = FALSE;
     857               0 :                 if (use_proxy && !use_ssl) {
     858               0 :                         connection = get_http_header_value(http_headers,"Proxy-Connection: ");
     859               0 :                         if (connection) {
     860               0 :                                 if (strncasecmp(connection, "close", sizeof("close")-1) == 0) {
     861               0 :                                         http_close = TRUE;
     862                 :                                 }
     863               0 :                                 efree(connection);
     864                 :                         }
     865                 :                 }
     866                 :         } else {
     867               0 :                 http_close = TRUE;
     868                 :         }       
     869                 : 
     870               0 :         if (!get_http_body(stream, http_close, http_headers, &http_body, &http_body_size TSRMLS_CC)) {
     871               0 :                 if (request != buf) {efree(request);}
     872               0 :                 php_stream_close(stream);
     873               0 :                 efree(http_headers);
     874               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     875               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     876               0 :                 add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL TSRMLS_CC);
     877               0 :                 if (http_msg) {
     878               0 :                         efree(http_msg);
     879                 :                 }
     880               0 :                 smart_str_free(&soap_headers_z);
     881               0 :                 return FALSE;
     882                 :         }
     883                 : 
     884               0 :         if (request != buf) {efree(request);}
     885                 : 
     886                 :         /* See if the server requested a close */
     887               0 :         http_close = TRUE;
     888               0 :         connection = get_http_header_value(http_headers,"Proxy-Connection: ");
     889               0 :         if (connection) {
     890               0 :                 if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
     891               0 :                         http_close = FALSE;
     892                 :                 }
     893               0 :                 efree(connection);
     894                 : /*
     895                 :         } else if (http_1_1) {
     896                 :                 http_close = FALSE;
     897                 : */
     898                 :         }
     899               0 :         connection = get_http_header_value(http_headers,"Connection: ");
     900               0 :         if (connection) {
     901               0 :                 if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
     902               0 :                         http_close = FALSE;
     903                 :                 }
     904               0 :                 efree(connection);
     905                 : /*
     906                 :         } else if (http_1_1) {
     907                 :                 http_close = FALSE;
     908                 : */
     909                 :         }
     910                 : 
     911               0 :         if (http_close) {
     912               0 :                 php_stream_close(stream);
     913               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
     914               0 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
     915               0 :                 stream = NULL;
     916                 :         }
     917                 : 
     918                 :         /* Process HTTP status codes */
     919               0 :         if (http_status >= 300 && http_status < 400) {
     920                 :                 char *loc;
     921                 : 
     922               0 :                 if ((loc = get_http_header_value(http_headers,"Location: ")) != NULL) {
     923               0 :                         php_url *new_url  = php_url_parse(loc);
     924                 : 
     925               0 :                         if (new_url != NULL) {
     926               0 :                                 efree(http_headers);
     927               0 :                                 efree(http_body);
     928               0 :                                 efree(loc);
     929               0 :                                 if (new_url->scheme == NULL && new_url->path != NULL) {
     930               0 :                                         new_url->scheme = phpurl->scheme ? estrdup(phpurl->scheme) : NULL;
     931               0 :                                         new_url->host = phpurl->host ? estrdup(phpurl->host) : NULL;
     932               0 :                                         new_url->port = phpurl->port;
     933               0 :                                         if (new_url->path && new_url->path[0] != '/') {
     934               0 :                                                 char *t = phpurl->path;
     935               0 :                                                 char *p = strrchr(t, '/');
     936               0 :                                                 if (p) {
     937               0 :                                                         char *s = emalloc((p - t) + strlen(new_url->path) + 2);
     938               0 :                                                         strncpy(s, t, (p - t) + 1);
     939               0 :                                                         s[(p - t) + 1] = 0;
     940               0 :                                                         strcat(s, new_url->path);
     941               0 :                                                         efree(new_url->path);
     942               0 :                                                         new_url->path = s;
     943                 :                                                 }
     944                 :                                         }
     945                 :                                 }
     946               0 :                                 phpurl = new_url;
     947                 : 
     948               0 :                                 goto try_again;
     949                 :                         }
     950                 :                 }
     951               0 :         } else if (http_status == 401) {
     952                 :                 /* Digest authentication */
     953                 :                 zval **digest, **login, **password;
     954               0 :                 char *auth = get_http_header_value(http_headers, "WWW-Authenticate: ");
     955                 : 
     956               0 :                 if (auth &&
     957                 :                                 strstr(auth, "Digest") == auth &&
     958                 :                     (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == FAILURE ||
     959                 :                      Z_TYPE_PP(digest) != IS_ARRAY) &&
     960                 :                     zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
     961                 :                     Z_TYPE_PP(login) == IS_STRING &&
     962                 :                     zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
     963                 :                     Z_TYPE_PP(password) == IS_STRING) {
     964                 :                         char *s;
     965               0 :                         zval *digest = NULL;
     966                 : 
     967               0 :                         s = auth + sizeof("Digest")-1;
     968               0 :                         while (*s != '\0') {
     969                 :                                 char *name, *val;
     970               0 :                                 while (*s == ' ') ++s;
     971               0 :                                 name = s;
     972               0 :                                 while (*s != '\0' && *s != '=') ++s;
     973               0 :                                 if (*s == '=') {
     974               0 :                                         *s = '\0';
     975               0 :                                         ++s;
     976               0 :                                         if (*s == '"') {
     977               0 :                                                 ++s;
     978               0 :                                                 val = s;
     979               0 :                                                 while (*s != '\0' && *s != '"') ++s;
     980                 :                                         } else {
     981               0 :                                                 val = s;
     982               0 :                                                 while (*s != '\0' && *s != ' ' && *s != ',') ++s;
     983                 :                                         }
     984               0 :                                         if (*s != '\0') {
     985               0 :                                                 if (*s != ',') {
     986               0 :                                                         *s = '\0';
     987               0 :                                                         ++s;
     988               0 :                                                         while (*s != '\0' && *s != ',') ++s;
     989               0 :                                                         if (*s != '\0') ++s;
     990                 :                                                 } else {
     991               0 :                                                         *s = '\0';
     992               0 :                                                         ++s;
     993                 :                                                 }
     994                 :                                         }
     995               0 :                                         if (digest == NULL) {
     996               0 :                                                 ALLOC_INIT_ZVAL(digest);
     997               0 :                                                 array_init(digest);
     998                 :                                         }
     999               0 :                                         add_assoc_string(digest, name, val ,1);
    1000                 :                                 }
    1001                 :                         }
    1002                 : 
    1003               0 :                         if (digest != NULL) {
    1004               0 :                                 php_url *new_url  = emalloc(sizeof(php_url));
    1005                 : 
    1006               0 :                                 digest->refcount--;
    1007               0 :                                 add_property_zval_ex(this_ptr, "_digest", sizeof("_digest"), digest TSRMLS_CC);
    1008                 : 
    1009               0 :                                 *new_url = *phpurl;
    1010               0 :                                 if (phpurl->scheme) phpurl->scheme = estrdup(phpurl->scheme);
    1011               0 :                                 if (phpurl->user) phpurl->user = estrdup(phpurl->user);
    1012               0 :                                 if (phpurl->pass) phpurl->pass = estrdup(phpurl->pass);
    1013               0 :                                 if (phpurl->host) phpurl->host = estrdup(phpurl->host);
    1014               0 :                                 if (phpurl->path) phpurl->path = estrdup(phpurl->path);
    1015               0 :                                 if (phpurl->query) phpurl->query = estrdup(phpurl->query);
    1016               0 :                                 if (phpurl->fragment) phpurl->fragment = estrdup(phpurl->fragment);
    1017               0 :                                 phpurl = new_url;
    1018                 : 
    1019               0 :                                 efree(auth);
    1020               0 :                                 efree(http_headers);
    1021               0 :                                 efree(http_body);
    1022                 : 
    1023               0 :                                 goto try_again;
    1024                 :                         }
    1025                 :                 }
    1026               0 :                 if (auth) efree(auth);
    1027                 :         }
    1028               0 :         smart_str_free(&soap_headers_z);
    1029                 : 
    1030                 :         /* Check and see if the server even sent a xml document */
    1031               0 :         content_type = get_http_header_value(http_headers,"Content-Type: ");
    1032               0 :         if (content_type) {
    1033               0 :                 char *pos = NULL;
    1034                 :                 int cmplen;
    1035               0 :                 pos = strstr(content_type,";");
    1036               0 :                 if (pos != NULL) {
    1037               0 :                         cmplen = pos - content_type;
    1038                 :                 } else {
    1039               0 :                         cmplen = strlen(content_type);
    1040                 :                 }
    1041               0 :                 if (strncmp(content_type, "text/xml", cmplen) == 0 ||
    1042                 :                     strncmp(content_type, "application/soap+xml", cmplen) == 0) {
    1043               0 :                         content_type_xml = 1;
    1044                 : /*
    1045                 :                         if (strncmp(http_body, "<?xml", 5)) {
    1046                 :                                 zval *err;
    1047                 :                                 MAKE_STD_ZVAL(err);
    1048                 :                                 ZVAL_STRINGL(err, http_body, http_body_size, 1);
    1049                 :                                 add_soap_fault(this_ptr, "HTTP", "Didn't recieve an xml document", NULL, err TSRMLS_CC);
    1050                 :                                 efree(content_type);
    1051                 :                                 efree(http_headers);
    1052                 :                                 efree(http_body);
    1053                 :                                 return FALSE;
    1054                 :                         }
    1055                 : */
    1056                 :                 }
    1057               0 :                 efree(content_type);
    1058                 :         }
    1059                 : 
    1060                 :         /* Decompress response */
    1061               0 :         content_encoding = get_http_header_value(http_headers,"Content-Encoding: ");
    1062               0 :         if (content_encoding) {
    1063                 :                 zval func;
    1064                 :                 zval retval;
    1065                 :           zval param;
    1066                 :                 zval *params[1];
    1067                 : 
    1068               0 :                 if ((strcmp(content_encoding,"gzip") == 0 ||
    1069                 :                      strcmp(content_encoding,"x-gzip") == 0) &&
    1070                 :                      zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) {
    1071               0 :                         ZVAL_STRING(&func, "gzinflate", 0);
    1072               0 :                         params[0] = &param;
    1073               0 :                         ZVAL_STRINGL(params[0], http_body+10, http_body_size-10, 0);
    1074               0 :                         INIT_PZVAL(params[0]);
    1075               0 :                 } else if (strcmp(content_encoding,"deflate") == 0 &&
    1076                 :                            zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) {
    1077               0 :                         ZVAL_STRING(&func, "gzuncompress", 0);
    1078               0 :                         params[0] = &param;
    1079               0 :                         ZVAL_STRINGL(params[0], http_body, http_body_size, 0);
    1080               0 :                         INIT_PZVAL(params[0]);
    1081                 :                 } else {
    1082               0 :                         efree(content_encoding);
    1083               0 :                         efree(http_headers);
    1084               0 :                         efree(http_body);
    1085               0 :                         if (http_msg) {
    1086               0 :                                 efree(http_msg);
    1087                 :                         }
    1088               0 :                         add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL TSRMLS_CC);
    1089               0 :                         return FALSE;
    1090                 :                 }
    1091               0 :                 if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS &&
    1092                 :                     Z_TYPE(retval) == IS_STRING) {
    1093               0 :                         efree(http_body);
    1094               0 :                         *buffer = Z_STRVAL(retval);
    1095               0 :                         *buffer_len = Z_STRLEN(retval);
    1096                 :                 } else {
    1097               0 :                         efree(content_encoding);
    1098               0 :                         efree(http_headers);
    1099               0 :                         efree(http_body);
    1100               0 :                         add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL TSRMLS_CC);
    1101               0 :                         if (http_msg) {
    1102               0 :                                 efree(http_msg);
    1103                 :                         }
    1104               0 :                         return FALSE;
    1105                 :                 }
    1106               0 :                 efree(content_encoding);
    1107                 :         } else {
    1108               0 :                 *buffer = http_body;
    1109               0 :                 *buffer_len = http_body_size;
    1110                 :         }
    1111                 : 
    1112               0 :         efree(http_headers);
    1113                 : 
    1114               0 :         if (http_status >= 400) {
    1115               0 :                 int error = 0;
    1116                 : 
    1117               0 :                 if (*buffer_len == 0) {
    1118               0 :                         error = 1;
    1119               0 :                 } else if (*buffer_len > 0) {
    1120               0 :                         if (!content_type_xml) {
    1121               0 :                                 char *s = *buffer;
    1122                 : 
    1123               0 :                                 while (*s != '\0' && *s < ' ') {
    1124               0 :                                         s++;
    1125                 :                                 }
    1126               0 :                                 if (strncmp(s, "<?xml", 5)) {
    1127               0 :                                         error = 1;
    1128                 :                                 }
    1129                 :                         }
    1130                 :                 }
    1131                 : 
    1132               0 :                 if (error) {
    1133               0 :                         efree(*buffer);
    1134               0 :                         add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL TSRMLS_CC);
    1135               0 :                         efree(http_msg);
    1136               0 :                         return FALSE;
    1137                 :                 }
    1138                 :         }
    1139                 : 
    1140               0 :         if (http_msg) {
    1141               0 :                 efree(http_msg);
    1142                 :         }
    1143                 : 
    1144               0 :         return TRUE;
    1145                 : }
    1146                 : 
    1147                 : static char *get_http_header_value(char *headers, char *type)
    1148               0 : {
    1149               0 :         char *pos, *tmp = NULL;
    1150                 :         int typelen, headerslen;
    1151                 : 
    1152               0 :         typelen = strlen(type);
    1153               0 :         headerslen = strlen(headers);
    1154                 : 
    1155                 :         /* header `titles' can be lower case, or any case combination, according
    1156                 :          * to the various RFC's. */
    1157               0 :         pos = headers;
    1158                 :         do {
    1159                 :                 /* start of buffer or start of line */
    1160               0 :                 if (strncasecmp(pos, type, typelen) == 0) {
    1161                 :                         char *eol;
    1162                 : 
    1163                 :                         /* match */
    1164               0 :                         tmp = pos + typelen;
    1165               0 :                         eol = strchr(tmp, '\n');
    1166               0 :                         if (eol == NULL) {
    1167               0 :                                 eol = headers + headerslen;
    1168               0 :                         } else if (eol > tmp && *(eol-1) == '\r') {
    1169               0 :                                 eol--;
    1170                 :                         }
    1171               0 :                         return estrndup(tmp, eol - tmp);
    1172                 :                 }
    1173                 : 
    1174                 :                 /* find next line */
    1175               0 :                 pos = strchr(pos, '\n');
    1176               0 :                 if (pos) {
    1177               0 :                         pos++;
    1178                 :                 }
    1179                 : 
    1180               0 :         } while (pos);
    1181                 : 
    1182               0 :         return NULL;
    1183                 : }
    1184                 : 
    1185                 : static int get_http_body(php_stream *stream, int close, char *headers,  char **response, int *out_size TSRMLS_DC)
    1186               0 : {
    1187               0 :         char *header, *http_buf = NULL;
    1188               0 :         int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0;
    1189                 : 
    1190               0 :         if (!close) {
    1191               0 :                 header = get_http_header_value(headers, "Connection: ");
    1192               0 :                 if (header) {
    1193               0 :                         if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1;
    1194               0 :                         efree(header);
    1195                 :                 }
    1196                 :         }
    1197               0 :         header = get_http_header_value(headers, "Transfer-Encoding: ");
    1198               0 :         if (header) {
    1199               0 :                 if(!strncasecmp(header, "chunked", sizeof("chunked")-1)) header_chunked = 1;
    1200               0 :                 efree(header);
    1201                 :         }
    1202               0 :         header = get_http_header_value(headers, "Content-Length: ");
    1203               0 :         if (header) {
    1204               0 :                 header_length = atoi(header);
    1205               0 :                 efree(header);
    1206               0 :                 if (!header_length && !header_chunked) {
    1207                 :                         /* Empty response */
    1208               0 :                         http_buf = emalloc(1);
    1209               0 :                         http_buf[0] = '\0';
    1210               0 :                         (*response) = http_buf;
    1211               0 :                         (*out_size) = 0;
    1212               0 :                         return TRUE;
    1213                 :                 }
    1214                 :         }
    1215                 : 
    1216               0 :         if (header_chunked) {
    1217                 :                 char ch, done, chunk_size[10], headerbuf[8192];
    1218                 : 
    1219               0 :                 done = FALSE;
    1220                 : 
    1221               0 :                 while (!done) {
    1222               0 :                         int buf_size = 0;
    1223                 : 
    1224               0 :                         php_stream_gets(stream, chunk_size, sizeof(chunk_size));
    1225               0 :                         if (sscanf(chunk_size, "%x", &buf_size) > 0 ) {
    1226               0 :                                 if (buf_size > 0) {
    1227               0 :                                         int len_size = 0;
    1228                 : 
    1229               0 :                                         if (http_buf_size + buf_size + 1 < 0) {
    1230               0 :                                                 efree(http_buf);
    1231               0 :                                                 return FALSE;
    1232                 :                                         }
    1233               0 :                                         http_buf = erealloc(http_buf, http_buf_size + buf_size + 1);
    1234                 : 
    1235               0 :                                         while (len_size < buf_size) {
    1236               0 :                                                 int len_read = php_stream_read(stream, http_buf + http_buf_size, buf_size - len_size);
    1237               0 :                                                 if (len_read <= 0) {
    1238                 :                                                         /* Error or EOF */
    1239               0 :                                                         done = TRUE;
    1240               0 :                                                   break;
    1241                 :                                                 }
    1242               0 :                                                 len_size += len_read;
    1243               0 :                                                 http_buf_size += len_read;
    1244                 :                                         }
    1245                 : 
    1246                 :                                         /* Eat up '\r' '\n' */
    1247               0 :                                         ch = php_stream_getc(stream);
    1248               0 :                                         if (ch == '\r') {
    1249               0 :                                                 ch = php_stream_getc(stream);
    1250                 :                                         }
    1251               0 :                                         if (ch != '\n') {
    1252                 :                                                 /* Somthing wrong in chunked encoding */
    1253               0 :                                                 if (http_buf) {
    1254               0 :                                                         efree(http_buf);
    1255                 :                                                 }
    1256               0 :                                                 return FALSE;
    1257                 :                                         }
    1258                 :                                 }
    1259                 :                         } else {
    1260                 :                                 /* Somthing wrong in chunked encoding */
    1261               0 :                                 if (http_buf) {
    1262               0 :                                         efree(http_buf);
    1263                 :                                 }
    1264               0 :                                 return FALSE;
    1265                 :                         }
    1266               0 :                         if (buf_size == 0) {
    1267               0 :                                 done = TRUE;
    1268                 :                         }
    1269                 :                 }
    1270                 : 
    1271                 :                 /* Ignore trailer headers */
    1272                 :                 while (1) {
    1273               0 :                         if (!php_stream_gets(stream, headerbuf, sizeof(headerbuf))) {
    1274               0 :                                 break;
    1275                 :                         }
    1276                 : 
    1277               0 :                         if ((headerbuf[0] == '\r' && headerbuf[1] == '\n') ||
    1278                 :                             (headerbuf[0] == '\n')) {
    1279                 :                                 /* empty line marks end of headers */
    1280                 :                                 break;
    1281                 :                         }
    1282               0 :                 }
    1283                 : 
    1284               0 :                 if (http_buf == NULL) {
    1285               0 :                         http_buf = emalloc(1);
    1286                 :                 }
    1287                 : 
    1288               0 :         } else if (header_length) {
    1289               0 :                 if (header_length < 0) {
    1290               0 :                         return FALSE;
    1291                 :                 }
    1292               0 :                 http_buf = emalloc(header_length + 1);
    1293               0 :                 while (http_buf_size < header_length) {
    1294               0 :                         int len_read = php_stream_read(stream, http_buf + http_buf_size, header_length - http_buf_size);
    1295               0 :                         if (len_read <= 0) {
    1296               0 :                                 break;
    1297                 :                         }
    1298               0 :                         http_buf_size += len_read;
    1299                 :                 }
    1300               0 :         } else if (header_close) {
    1301                 :                 do {
    1302                 :                         int len_read;
    1303               0 :                         http_buf = erealloc(http_buf, http_buf_size + 4096 + 1);
    1304               0 :                         len_read = php_stream_read(stream, http_buf + http_buf_size, 4096);
    1305               0 :                         if (len_read > 0) {
    1306               0 :                                 http_buf_size += len_read;
    1307                 :                         }
    1308               0 :                 } while(!php_stream_eof(stream));
    1309                 :         } else {
    1310               0 :                 return FALSE;
    1311                 :         }
    1312                 : 
    1313               0 :         http_buf[http_buf_size] = '\0';
    1314               0 :         (*response) = http_buf;
    1315               0 :         (*out_size) = http_buf_size;
    1316               0 :         return TRUE;
    1317                 : }
    1318                 : 
    1319                 : static int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_DC)
    1320               0 : {
    1321               0 :         int done = FALSE;
    1322               0 :         smart_str tmp_response = {0};
    1323                 :         char headerbuf[8192];
    1324                 : 
    1325               0 :         while (!done) {
    1326               0 :                 if (!php_stream_gets(stream, headerbuf, sizeof(headerbuf))) {
    1327               0 :                         break;
    1328                 :                 }
    1329                 : 
    1330               0 :                 if ((headerbuf[0] == '\r' && headerbuf[1] == '\n') ||
    1331                 :                     (headerbuf[0] == '\n')) {
    1332                 :                         /* empty line marks end of headers */
    1333               0 :                         done = TRUE;
    1334               0 :                         break;
    1335                 :                 }
    1336                 : 
    1337                 :                 /* add header to collection */
    1338               0 :                 smart_str_appends(&tmp_response, headerbuf);
    1339                 :         }
    1340               0 :         smart_str_0(&tmp_response);
    1341               0 :         (*response) = tmp_response.c;
    1342               0 :         (*out_size) = tmp_response.len;
    1343               0 :         return done;
    1344                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:19 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.