diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 5a887bd1e1e0..8b87487017e2 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -532,6 +532,8 @@ int make_http_soap_request(zval *this_ptr, } PG(allow_url_fopen) = old_allow_url_fopen; + bool client_trace = Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE; + if (stream) { zval *cookies, *login, *password; zend_resource *ret = zend_register_resource(phpurl, le_url); @@ -863,7 +865,7 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, "\r\n"); smart_str_0(&soap_headers); - if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) { + if (client_trace) { zval_ptr_dtor(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr)); /* Need to copy the string here, as we continue appending to soap_headers below. */ ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr), @@ -892,65 +894,78 @@ int make_http_soap_request(zval *this_ptr, return FALSE; } - if (!return_value) { - php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); - smart_str_free(&soap_headers_z); - return TRUE; - } + http_headers = NULL; + if (return_value || client_trace) { + do { + http_headers = get_http_headers(stream); + if (!http_headers) { + if (request != buf) { + zend_string_release_ex(request, 0); + } + php_stream_close(stream); + convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); + convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL); + smart_str_free(&soap_headers_z); + return FALSE; + } - do { - http_headers = get_http_headers(stream); - if (!http_headers) { - if (request != buf) { - zend_string_release_ex(request, 0); + if (client_trace) { + zval_ptr_dtor(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr)); + ZVAL_STR_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr), http_headers); } - php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); - add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL); - smart_str_free(&soap_headers_z); - return FALSE; - } - if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) { - zval_ptr_dtor(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr)); - ZVAL_STR_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr), http_headers); - } + /* Check to see what HTTP status was sent */ + http_1_1 = 0; + http_status = 0; + http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/"); + if (http_version) { + char *tmp; - /* Check to see what HTTP status was sent */ - http_1_1 = 0; - http_status = 0; - http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/"); - if (http_version) { - char *tmp; + if (!strncmp(http_version,"1.1", 3)) { + http_1_1 = 1; + } - if (!strncmp(http_version,"1.1", 3)) { - http_1_1 = 1; - } + tmp = strstr(http_version," "); + if (tmp != NULL) { + tmp++; + http_status = atoi(tmp); + } + tmp = strstr(tmp," "); + if (tmp != NULL) { + tmp++; + if (http_msg) { + efree(http_msg); + } + http_msg = estrdup(tmp); + } + efree(http_version); - tmp = strstr(http_version," "); - if (tmp != NULL) { - tmp++; - http_status = atoi(tmp); - } - tmp = strstr(tmp," "); - if (tmp != NULL) { - tmp++; - if (http_msg) { - efree(http_msg); + /* Try and get headers again */ + if (http_status == 100) { + zend_string_release_ex(http_headers, 0); } - http_msg = estrdup(tmp); } - efree(http_version); + } while (http_status == 100); + } - /* Try and get headers again */ - if (http_status == 100) { - zend_string_release_ex(http_headers, 0); - } + if (!return_value) { + /* In this case, the headers were only fetched because client_trace was true. */ + if (request != buf) { + zend_string_release_ex(request, 0); + } + php_stream_close(stream); + if (http_headers) { + zend_string_release_ex(http_headers, 0); + } + convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); + convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + if (http_msg) { + efree(http_msg); } - } while (http_status == 100); + smart_str_free(&soap_headers_z); + return true; + } /* Grab and send back every cookie */ diff --git a/ext/soap/tests/bugs/bug49278.phpt b/ext/soap/tests/bugs/bug49278.phpt new file mode 100644 index 000000000000..ddac60807a4d --- /dev/null +++ b/ext/soap/tests/bugs/bug49278.phpt @@ -0,0 +1,59 @@ +--TEST-- +Bug #49278 (SoapClient::__getLastResponseHeaders returns NULL if wsdl operation !has output) +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +--SKIPIF-- + +--FILE-- +1]);' . + <<<'PHP' + function Add() {} + $server->addFunction('Add'); + $server->handle(); + PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(__DIR__ . '/bug49278.wsdl', array('location' => "http://".PHP_CLI_SERVER_ADDRESS, 'trace' => 1)); +$client->Add(); +var_dump($client->__getLastResponse()); +var_dump($client->__getLastResponse()); +var_dump($client->__getLastRequestHeaders()); +var_dump($client->__getLastResponseHeaders()); + +?> +--EXPECTF-- +string(0) "" +string(0) "" +string(177) "POST / HTTP/1.1 +Host: %s +Connection: Keep-Alive +User-Agent: PHP-SOAP/8.4.0-dev +Content-Type: text/xml; charset=utf-8 +SOAPAction: "Add" +Content-Length: %d + +" +string(165) "HTTP/1.1 200 OK +Host: %s +Date: %s +Connection: close +X-Powered-By: PHP/8.4.0-dev +Content-type: text/html; charset=UTF-8 +" diff --git a/ext/soap/tests/bugs/bug49278.wsdl b/ext/soap/tests/bugs/bug49278.wsdl new file mode 100644 index 000000000000..5cbeb36c7c14 --- /dev/null +++ b/ext/soap/tests/bugs/bug49278.wsdl @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +