dmitry Wed Feb 25 09:04:43 2004 EDT Modified files: /php-src/ext/soap TODO php_http.c php_soap.h soap.c Log: HTTP compression support (gzip and deflate)
http://cvs.php.net/diff.php/php-src/ext/soap/TODO?r1=1.48&r2=1.49&ty=u Index: php-src/ext/soap/TODO diff -u php-src/ext/soap/TODO:1.48 php-src/ext/soap/TODO:1.49 --- php-src/ext/soap/TODO:1.48 Tue Feb 24 10:35:53 2004 +++ php-src/ext/soap/TODO Wed Feb 25 09:04:41 2004 @@ -88,7 +88,7 @@ --------- ? HTTP status codes ? HTTP chunked Transfer-Encoding -- support for HTTP compression (gzip,x-gzip,defalte) +? support for HTTP compression (gzip,x-gzip,defalte) - transport abstraction layer??? Interop Testing http://cvs.php.net/diff.php/php-src/ext/soap/php_http.c?r1=1.45&r2=1.46&ty=u Index: php-src/ext/soap/php_http.c diff -u php-src/ext/soap/php_http.c:1.45 php-src/ext/soap/php_http.c:1.46 --- php-src/ext/soap/php_http.c:1.45 Fri Feb 20 10:38:39 2004 +++ php-src/ext/soap/php_http.c Wed Feb 25 09:04:41 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_http.c,v 1.45 2004/02/20 15:38:39 dmitry Exp $ */ +/* $Id: php_http.c,v 1.46 2004/02/25 14:04:41 dmitry Exp $ */ #include "php_soap.h" #include "ext/standard/base64.h" @@ -173,9 +173,9 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *soapaction, int soap_version TSRMLS_DC) { - xmlChar *buf; + xmlChar *buf, *request; smart_str soap_headers = {0}; - int buf_size,err; + int buf_size, request_size, err; php_url *phpurl = NULL; php_stream *stream; zval **trace, **tmp; @@ -305,8 +305,62 @@ smart_str_append_const(&soap_headers, "\"\r\n"); } } + + request = buf; + request_size = buf_size; + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "compression", sizeof("compression"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) { + int level = Z_LVAL_PP(tmp) & 0x0f; + int kind = Z_LVAL_PP(tmp) & SOAP_COMPRESSION_DEFLATE; + + if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) { + smart_str_append_const(&soap_headers,"Accept-Encoding: gzip, deflate\r\n"); + } + if (level > 0) { + zval func; + zval retval; + zval param1, param2, param3; + zval *params[3]; + int n; + + + params[0] = ¶m1; + INIT_PZVAL(params[0]); + params[1] = ¶m2; + INIT_PZVAL(params[1]); + params[2] = ¶m3; + INIT_PZVAL(params[2]); + ZVAL_STRINGL(params[0], buf, buf_size, 0); + ZVAL_LONG(params[1], level); + if (kind == SOAP_COMPRESSION_DEFLATE) { + n = 2; + ZVAL_STRING(&func, "gzcompress", 0); + smart_str_append_const(&soap_headers,"Content-Encoding: deflate\r\n"); + } else { + n = 3; + ZVAL_STRING(&func, "gzencode", 0); + smart_str_append_const(&soap_headers,"Content-Encoding: gzip\r\n"); + ZVAL_LONG(params[2], 1); + /* (SOAP_COMPRESSION_GZIP */ + } + if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, n, params TSRMLS_CC) == SUCCESS && + Z_TYPE(retval) == IS_STRING) { + request = Z_STRVAL(retval); + request_size = Z_STRLEN(retval); + } else { + php_url_free(phpurl); + if (request != buf) {efree(request);} + xmlFree(buf); + smart_str_free(&soap_headers); + php_stream_close(stream); + zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")); + zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")); + add_soap_fault(this_ptr, "HTTP", "Compression Failed", NULL, NULL TSRMLS_CC); + return FALSE; + } + } + } smart_str_append_const(&soap_headers,"Content-Length: "); - smart_str_append_long(&soap_headers, buf_size); + smart_str_append_long(&soap_headers, request_size); smart_str_append_const(&soap_headers, "\r\n"); /* HTTP Authentication */ @@ -358,12 +412,13 @@ } } smart_str_append_const(&soap_headers, "\r\n"); - smart_str_appendl(&soap_headers, buf, buf_size); + smart_str_appendl(&soap_headers, request, request_size); smart_str_0(&soap_headers); err = php_stream_write(stream, soap_headers.c, soap_headers.len); if (err != soap_headers.len) { php_url_free(phpurl); + if (request != buf) {efree(request);} xmlFree(buf); smart_str_free(&soap_headers); php_stream_close(stream); @@ -376,6 +431,7 @@ } php_url_free(phpurl); + if (request != buf) {efree(request);} xmlFree(buf); return TRUE; } @@ -386,9 +442,10 @@ int http_header_size, http_body_size, http_close; php_stream *stream; zval **trace, **tmp; - char* connection; + char *connection; int http_1_1 = 0; int http_status = 0; + char *content_encoding; if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"), (void **)&tmp) == SUCCESS) { php_stream_from_zval_no_verify(stream,tmp); @@ -473,11 +530,6 @@ return FALSE; } - if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS && - Z_LVAL_PP(trace) > 0) { - add_property_stringl(this_ptr, "__last_response", http_body, http_body_size, 1); - } - /* See if the server requested a close */ http_close = TRUE; connection = get_http_header_value(http_headers,"Proxy-Connection: "); @@ -591,8 +643,55 @@ efree(cookie); } - *buffer = http_body; - *buffer_len = http_body_size; + content_encoding = get_http_header_value(http_headers,"Content-Encoding: "); + if (content_encoding) { + zval func; + zval retval; + zval param; + zval *params[1]; + + if ((strcmp(content_encoding,"gzip") == 0 || + strcmp(content_encoding,"x-gzip") == 0) && + zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) { + ZVAL_STRING(&func, "gzinflate", 0); + params[0] = ¶m; + ZVAL_STRINGL(params[0], http_body+10, http_body_size-10, 0); + INIT_PZVAL(params[0]); + } else if (strcmp(content_encoding,"deflate") == 0 && + zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) { + ZVAL_STRING(&func, "gzuncompress", 0); + params[0] = ¶m; + ZVAL_STRINGL(params[0], http_body, http_body_size, 0); + INIT_PZVAL(params[0]); + } else { + efree(content_encoding); + efree(http_headers); + efree(http_body); + add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL TSRMLS_CC); + return FALSE; + } + if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS && + Z_TYPE(retval) == IS_STRING) { + efree(http_body); + *buffer = Z_STRVAL(retval); + *buffer_len = Z_STRLEN(retval); + } else { + efree(content_encoding); + efree(http_headers); + efree(http_body); + add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL TSRMLS_CC); + return FALSE; + } + efree(content_encoding); + } else { + *buffer = http_body; + *buffer_len = http_body_size; + } + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS && + Z_LVAL_PP(trace) > 0) { + add_property_stringl(this_ptr, "__last_response", *buffer, *buffer_len, 1); + } + efree(http_headers); return TRUE; } http://cvs.php.net/diff.php/php-src/ext/soap/php_soap.h?r1=1.30&r2=1.31&ty=u Index: php-src/ext/soap/php_soap.h diff -u php-src/ext/soap/php_soap.h:1.30 php-src/ext/soap/php_soap.h:1.31 --- php-src/ext/soap/php_soap.h:1.30 Fri Feb 13 06:03:58 2004 +++ php-src/ext/soap/php_soap.h Wed Feb 25 09:04:41 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_soap.h,v 1.30 2004/02/13 11:03:58 dmitry Exp $ */ +/* $Id: php_soap.h,v 1.31 2004/02/25 14:04:41 dmitry Exp $ */ #ifndef PHP_SOAP_H #define PHP_SOAP_H @@ -138,6 +138,10 @@ #define SOAP_1_2_ACTOR_NONE "http://www.w3.org/2003/05/soap-envelope/role/none" #define SOAP_1_2_ACTOR_UNLIMATERECEIVER "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver" +#define SOAP_COMPRESSION_ACCEPT 0x20 +#define SOAP_COMPRESSION_GZIP 0x00 +#define SOAP_COMPRESSION_DEFLATE 0x10 + ZEND_BEGIN_MODULE_GLOBALS(soap) HashTable defEncNs; /* mapping of default namespaces to prefixes */ HashTable defEnc; http://cvs.php.net/diff.php/php-src/ext/soap/soap.c?r1=1.91&r2=1.92&ty=u Index: php-src/ext/soap/soap.c diff -u php-src/ext/soap/soap.c:1.91 php-src/ext/soap/soap.c:1.92 --- php-src/ext/soap/soap.c:1.91 Tue Feb 24 10:06:41 2004 +++ php-src/ext/soap/soap.c Wed Feb 25 09:04:41 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: soap.c,v 1.91 2004/02/24 15:06:41 dmitry Exp $ */ +/* $Id: soap.c,v 1.92 2004/02/25 14:04:41 dmitry Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -505,6 +505,10 @@ REGISTER_LONG_CONSTANT("SOAP_ACTOR_NONE", SOAP_ACTOR_NONE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_ACTOR_UNLIMATERECEIVER", SOAP_ACTOR_UNLIMATERECEIVER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_ACCEPT", SOAP_COMPRESSION_ACCEPT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_GZIP", SOAP_COMPRESSION_GZIP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_DEFLATE", SOAP_COMPRESSION_DEFLATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("UNKNOWN_TYPE", UNKNOWN_TYPE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSD_STRING", XSD_STRING, CONST_CS | CONST_PERSISTENT); @@ -1251,7 +1255,42 @@ if (ZEND_NUM_ARGS() == 0) { if (zend_hash_find(&EG(symbol_table), HTTP_RAW_POST_DATA, sizeof(HTTP_RAW_POST_DATA), (void **) &raw_post)!=FAILURE && ((*raw_post)->type==IS_STRING)) { - doc_request = soap_xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post)); + zval **server_vars, **encoding; + + if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS && + Z_TYPE_PP(server_vars) == IS_ARRAY && + zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS && + Z_TYPE_PP(encoding) == IS_STRING) { + zval func; + zval retval; + zval param; + zval *params[1]; + + if ((strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 || + strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0) && + zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) { + ZVAL_STRING(&func, "gzinflate", 0); + params[0] = ¶m; + ZVAL_STRINGL(params[0], Z_STRVAL_PP(raw_post)+10, Z_STRLEN_PP(raw_post)-10, 0); + INIT_PZVAL(params[0]); + } else if (strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 && + zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) { + ZVAL_STRING(&func, "gzuncompress", 0); + params[0] = ¶m; + ZVAL_STRINGL(params[0], Z_STRVAL_PP(raw_post), Z_STRLEN_PP(raw_post), 0); + INIT_PZVAL(params[0]); + } else { + php_error(E_ERROR,"Request is compressed with unknown compression '%s'",Z_STRVAL_PP(encoding)); + } + if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS && + Z_TYPE(retval) == IS_STRING) { + doc_request = soap_xmlParseMemory(Z_STRVAL(retval),Z_STRLEN(retval)); + } else { + php_error(E_ERROR,"Can't uncompress compressed request"); + } + } else { + doc_request = soap_xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post)); + } } else { if (!zend_ini_long("always_populate_raw_post_data", sizeof("always_populate_raw_post_data"), 0)) { php_error(E_ERROR, "PHP-SOAP requires 'always_populate_raw_post_data' to be on please check your php.ini file"); @@ -1774,6 +1813,15 @@ add_property_bool(this_ptr, "_exceptions", 0); } #endif + if (zend_hash_find(ht, "compression", sizeof("compression"), (void**)&tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_LONG && + zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate")) && + zend_hash_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")) && + zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")) && + zend_hash_exists(EG(function_table), "gzcompress", sizeof("gzcompress")) && + zend_hash_exists(EG(function_table), "gzencode", sizeof("gzencode"))) { + add_property_long(this_ptr, "compression", Z_LVAL_PP(tmp)); + } } else if (wsdl == NULL) { php_error(E_ERROR, "Can't create SoapClient. 'location' and 'uri' options are requred in nonWSDL mode."); return;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php