--- embedaddon/php/ext/soap/php_http.c 2012/02/21 23:48:01 1.1.1.1 +++ embedaddon/php/ext/soap/php_http.c 2012/05/29 12:34:42 1.1.1.2 @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_http.c,v 1.1.1.1 2012/02/21 23:48:01 misho Exp $ */ +/* $Id: php_http.c,v 1.1.1.2 2012/05/29 12:34:42 misho Exp $ */ #include "php_soap.h" #include "ext/standard/base64.h" @@ -32,7 +32,7 @@ static int get_http_headers(php_stream *socketd,char * smart_str_appendl(str,const,sizeof(const)-1) /* Proxy HTTP Authentication */ -void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC) +int proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC) { zval **login, **password; @@ -53,11 +53,13 @@ void proxy_authentication(zval* this_ptr, smart_str* s smart_str_append_const(soap_headers, "\r\n"); efree(buf); smart_str_free(&auth); + return 1; } + return 0; } /* HTTP Authentication */ -void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC) +int basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC) { zval **login, **password; @@ -79,9 +81,81 @@ void basic_authentication(zval* this_ptr, smart_str* s smart_str_append_const(soap_headers, "\r\n"); efree(buf); smart_str_free(&auth); + return 1; } + return 0; } +/* Additional HTTP headers */ +void http_context_headers(php_stream_context* context, + zend_bool has_authorization, + zend_bool has_proxy_authorization, + zend_bool has_cookies, + smart_str* soap_headers TSRMLS_DC) +{ + zval **tmp; + + if (context && + php_stream_context_get_option(context, "http", "header", &tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp)) { + char *s = Z_STRVAL_PP(tmp); + char *p; + int name_len; + + while (*s) { + /* skip leading newlines and spaces */ + while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') { + s++; + } + /* extract header name */ + p = s; + name_len = -1; + while (*p) { + if (*p == ':') { + if (name_len < 0) name_len = p - s; + break; + } else if (*p == ' ' || *p == '\t') { + if (name_len < 0) name_len = p - s; + } else if (*p == '\r' || *p == '\n') { + break; + } + p++; + } + if (*p == ':') { + /* extract header value */ + while (*p && *p != '\r' && *p != '\n') { + p++; + } + /* skip some predefined headers */ + if ((name_len != sizeof("host")-1 || + strncasecmp(s, "host", sizeof("host")-1) != 0) && + (name_len != sizeof("connection")-1 || + strncasecmp(s, "connection", sizeof("connection")-1) != 0) && + (name_len != sizeof("user-agent")-1 || + strncasecmp(s, "user-agent", sizeof("user-agent")-1) != 0) && + (name_len != sizeof("content-length")-1 || + strncasecmp(s, "content-length", sizeof("content-length")-1) != 0) && + (name_len != sizeof("content-type")-1 || + strncasecmp(s, "content-type", sizeof("content-type")-1) != 0) && + (!has_cookies || + name_len != sizeof("cookie")-1 || + strncasecmp(s, "cookie", sizeof("cookie")-1) != 0) && + (!has_authorization || + name_len != sizeof("authorization")-1 || + strncasecmp(s, "authorization", sizeof("authorization")-1) != 0) && + (!has_proxy_authorization || + name_len != sizeof("proxy-authorization")-1 || + strncasecmp(s, "proxy-authorization", sizeof("proxy-authorization")-1) != 0)) { + /* add header */ + smart_str_appendl(soap_headers, s, p-s); + smart_str_append_const(soap_headers, "\r\n"); + } + } + s = (*p) ? (p + 1) : p; + } + } +} + static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, php_stream_context *context, int *use_proxy TSRMLS_DC) { php_stream *stream; @@ -118,7 +192,7 @@ static php_stream* http_connect(zval* this_ptr, php_ur namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port); stream = php_stream_xport_create(name, namelen, - ENFORCE_SAFE_MODE | REPORT_ERRORS, + REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL /*persistent_id*/, timeout, @@ -387,7 +461,7 @@ try_again: if (stream) { zval **cookies, **login, **password; - int ret = zend_list_insert(phpurl, le_url); + int ret = zend_list_insert(phpurl, le_url TSRMLS_CC); add_property_resource(this_ptr, "httpurl", ret); /*zend_list_addref(ret);*/ @@ -433,12 +507,14 @@ try_again: smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, phpurl->port); } - if (http_1_1) { + if (!http_1_1 || + (zend_hash_find(Z_OBJPROP_P(this_ptr), "_keep_alive", sizeof("_keep_alive"), (void **)&tmp) == SUCCESS && + Z_LVAL_PP(tmp) == 0)) { smart_str_append_const(&soap_headers, "\r\n" - "Connection: Keep-Alive\r\n"); + "Connection: close\r\n"); } else { smart_str_append_const(&soap_headers, "\r\n" - "Connection: close\r\n"); + "Connection: Keep-Alive\r\n"); } if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) { @@ -662,8 +738,7 @@ try_again: /* Proxy HTTP Authentication */ if (use_proxy && !use_ssl) { - has_proxy_authorization = 1; - proxy_authentication(this_ptr, &soap_headers TSRMLS_CC); + has_proxy_authorization = proxy_authentication(this_ptr, &soap_headers TSRMLS_CC); } /* Send cookies along with request */ @@ -705,66 +780,8 @@ try_again: } } - if (context && - php_stream_context_get_option(context, "http", "header", &tmp) == SUCCESS && - Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp)) { - char *s = Z_STRVAL_PP(tmp); - char *p; - int name_len; + http_context_headers(context, has_authorization, has_proxy_authorization, has_cookies, &soap_headers TSRMLS_CC); - while (*s) { - /* skip leading newlines and spaces */ - while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') { - s++; - } - /* extract header name */ - p = s; - name_len = -1; - while (*p) { - if (*p == ':') { - if (name_len < 0) name_len = p - s; - break; - } else if (*p == ' ' || *p == '\t') { - if (name_len < 0) name_len = p - s; - } else if (*p == '\r' || *p == '\n') { - break; - } - p++; - } - if (*p == ':') { - /* extract header value */ - while (*p && *p != '\r' && *p != '\n') { - p++; - } - /* skip some predefined headers */ - if ((name_len != sizeof("host")-1 || - strncasecmp(s, "host", sizeof("host")-1) != 0) && - (name_len != sizeof("connection")-1 || - strncasecmp(s, "connection", sizeof("connection")-1) != 0) && - (name_len != sizeof("user-agent")-1 || - strncasecmp(s, "user-agent", sizeof("user-agent")-1) != 0) && - (name_len != sizeof("content-length")-1 || - strncasecmp(s, "content-length", sizeof("content-length")-1) != 0) && - (name_len != sizeof("content-type")-1 || - strncasecmp(s, "content-type", sizeof("content-type")-1) != 0) && - (!has_cookies || - name_len != sizeof("cookie")-1 || - strncasecmp(s, "cookie", sizeof("cookie")-1) != 0) && - (!has_authorization || - name_len != sizeof("authorization")-1 || - strncasecmp(s, "authorization", sizeof("authorization")-1) != 0) && - (!has_proxy_authorization || - name_len != sizeof("proxy-authorization")-1 || - strncasecmp(s, "proxy-authorization", sizeof("proxy-authorization")-1) != 0)) { - /* add header */ - smart_str_appendl(&soap_headers, s, p-s); - smart_str_append_const(&soap_headers, "\r\n"); - } - } - s = (*p) ? (p + 1) : p; - } - } - smart_str_append_const(&soap_headers, "\r\n"); smart_str_0(&soap_headers); if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS && @@ -1311,15 +1328,15 @@ static int get_http_body(php_stream *stream, int close } if (header_chunked) { - char ch, done, chunk_size[10], headerbuf[8192]; + char ch, done, headerbuf[8192]; done = FALSE; while (!done) { int buf_size = 0; - php_stream_gets(stream, chunk_size, sizeof(chunk_size)); - if (sscanf(chunk_size, "%x", &buf_size) > 0 ) { + php_stream_gets(stream, headerbuf, sizeof(headerbuf)); + if (sscanf(headerbuf, "%x", &buf_size) > 0 ) { if (buf_size > 0) { int len_size = 0; @@ -1386,7 +1403,7 @@ static int get_http_body(php_stream *stream, int close if (header_length < 0 || header_length >= INT_MAX) { return FALSE; } - http_buf = emalloc(header_length + 1); + http_buf = safe_emalloc(1, header_length, 1); while (http_buf_size < header_length) { int len_read = php_stream_read(stream, http_buf + http_buf_size, header_length - http_buf_size); if (len_read <= 0) {