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;
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 */
}
}
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);
}
php_url_free(phpurl);
+ if (request != buf) {efree(request);}
xmlFree(buf);
return TRUE;
}
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);
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: ");
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;
}
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);
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");
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;