22static char *get_http_header_value_nodup(
char *headers,
char *
type,
size_t *
len);
23static char *get_http_header_value(
char *headers,
char *
type);
27#define smart_str_append_const(str, const) \
28 smart_str_appendl(str,const,sizeof(const)-1)
36 smart_str_append(&auth,
Z_STR_P(login));
37 smart_str_appendc(&auth,
':');
41 smart_str_append(&auth,
Z_STR_P(password));
46 smart_str_append(soap_headers,
buf);
49 smart_str_free(&auth);
62 smart_str_append(&auth,
Z_STR_P(login));
63 smart_str_appendc(&auth,
':');
67 smart_str_append(&auth,
Z_STR_P(password));
72 smart_str_append(soap_headers,
buf);
75 smart_str_free(&auth);
81static void http_context_add_header(
const char *
s,
82 bool has_authorization,
83 bool has_proxy_authorization,
92 while (*
s ==
' ' || *
s ==
'\t' || *
s ==
'\r' || *
s ==
'\n') {
100 if (name_len < 0) name_len =
p -
s;
102 }
else if (*
p ==
' ' || *
p ==
'\t') {
103 if (name_len < 0) name_len =
p -
s;
104 }
else if (*
p ==
'\r' || *
p ==
'\n') {
111 while (*
p && *
p !=
'\r' && *
p !=
'\n') {
115 if ((name_len !=
sizeof(
"host")-1 ||
117 (name_len !=
sizeof(
"connection")-1 ||
118 strncasecmp(
s,
"connection",
sizeof(
"connection")-1) != 0) &&
119 (name_len !=
sizeof(
"user-agent")-1 ||
120 strncasecmp(
s,
"user-agent",
sizeof(
"user-agent")-1) != 0) &&
121 (name_len !=
sizeof(
"content-length")-1 ||
122 strncasecmp(
s,
"content-length",
sizeof(
"content-length")-1) != 0) &&
123 (name_len !=
sizeof(
"content-type")-1 ||
124 strncasecmp(
s,
"content-type",
sizeof(
"content-type")-1) != 0) &&
126 name_len !=
sizeof(
"cookie")-1 ||
128 (!has_authorization ||
129 name_len !=
sizeof(
"authorization")-1 ||
130 strncasecmp(
s,
"authorization",
sizeof(
"authorization")-1) != 0) &&
131 (!has_proxy_authorization ||
132 name_len !=
sizeof(
"proxy-authorization")-1 ||
133 strncasecmp(
s,
"proxy-authorization",
sizeof(
"proxy-authorization")-1) != 0)) {
135 smart_str_appendl(soap_headers,
s,
p-
s);
139 s = (*p) ? (
p + 1) :
p;
145 bool has_authorization,
146 bool has_proxy_authorization,
153 http_context_add_header(
Z_STRVAL_P(tmp), has_authorization, has_proxy_authorization, has_cookies, soap_headers);
158 http_context_add_header(
Z_STRVAL_P(
value), has_authorization, has_proxy_authorization, has_cookies, soap_headers);
168 zval *tmp, ssl_proxy_peer_name;
174 int old_error_reporting;
176 struct timeval *timeout =
NULL;
200 if (use_ssl && !*use_proxy) {
245 if (stream && *use_proxy && use_ssl) {
256 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
host));
257 smart_str_appendc(&soap_headers,
':');
258 smart_str_append_unsigned(&soap_headers, phpurl->
port);
261 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
host));
262 if (phpurl->
port != 80) {
263 smart_str_appendc(&soap_headers,
':');
264 smart_str_append_unsigned(&soap_headers, phpurl->
port);
273 smart_str_free(&soap_headers);
276 zend_string *http_headers = get_http_headers(stream);
278 zend_string_free(http_headers);
334 return zend_string_equals(host,domain);
355 char *content_type, *http_version, *cookie_itt;
362 int content_type_xml = 0;
364 char *content_encoding;
365 char *http_msg =
NULL;
366 bool old_allow_url_fopen;
368 bool has_authorization = 0;
369 bool has_proxy_authorization = 0;
370 bool has_cookies = 0;
383 if (level > 9) {level = 9;}
414 if (request !=
buf) {
417 smart_str_free(&soap_headers_z);
434 if (location !=
NULL && location[0] !=
'\000') {
454 if (request !=
buf) {
458 smart_str_free(&soap_headers_z);
468 if (request !=
buf) {
472 smart_str_free(&soap_headers_z);
477 old_allow_url_fopen =
PG(allow_url_fopen);
478 PG(allow_url_fopen) = 1;
481 if (request !=
buf) {
485 PG(allow_url_fopen) = old_allow_url_fopen;
486 smart_str_free(&soap_headers_z);
491 if (phpurl->
port == 0) {
492 phpurl->
port = use_ssl ? 443 : 80;
496 if (stream !=
NULL) {
501 ((use_proxy && !use_ssl) ||
505 zend_string_equals(orig->
host, phpurl->
host) &&
528 stream = http_connect(this_ptr, phpurl, use_ssl,
context, &use_proxy);
536 if (request !=
buf) {
540 PG(allow_url_fopen) = old_allow_url_fopen;
541 smart_str_free(&soap_headers_z);
546 PG(allow_url_fopen) = old_allow_url_fopen;
551 zval *cookies, *login, *password;
560 url_obj->
url = phpurl;
572 if (use_proxy && !use_ssl) {
575 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
host));
576 smart_str_appendc(&soap_headers,
':');
577 smart_str_append_unsigned(&soap_headers, phpurl->
port);
580 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
path));
582 smart_str_appendc(&soap_headers,
'/');
585 smart_str_appendc(&soap_headers,
'?');
589 smart_str_appendc(&soap_headers,
'#');
598 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
host));
599 if (phpurl->
port != (use_ssl?443:80)) {
600 smart_str_appendc(&soap_headers,
':');
601 smart_str_append_unsigned(&soap_headers, phpurl->
port);
605 "Connection: close\r\n");
608 "Connection: Keep-Alive\r\n");
625 }
else if (
FG(user_agent)) {
627 smart_str_appends(&soap_headers,
FG(user_agent));
633 smart_str_append_smart_str(&soap_headers, &soap_headers_z);
648 smart_str_appends(&soap_headers, soapaction);
666 smart_str_appends(&soap_headers, soapaction);
671 smart_str_append_long(&soap_headers, request->
len);
679 has_authorization = 1;
681 char HA1[33], HA2[33], response[33], cnonce[33], nc[9];
682 unsigned char nonce[16];
684 unsigned char hash[16];
692 smart_str_free(&soap_headers_z);
693 smart_str_free(&soap_headers);
698 php_hash_bin2hex(cnonce, nonce,
sizeof(nonce));
706 add_assoc_long(digest,
"nc", 1);
707 strcpy(nc,
"00000001");
742 PHP_MD5Update(&md5ctx, (
unsigned char*)
"POST:",
sizeof(
"POST:")-1);
771 PHP_MD5Update(&md5ctx, (
unsigned char*)
"auth",
sizeof(
"auth")-1);
792 smart_str_appends(&soap_headers,
ZSTR_VAL(phpurl->
path));
794 smart_str_appendc(&soap_headers,
'/');
797 smart_str_appendc(&soap_headers,
'?');
801 smart_str_appendc(&soap_headers,
'#');
809 smart_str_appendl(&soap_headers, nc, 8);
811 smart_str_appendl(&soap_headers, cnonce, 8);
814 smart_str_appendl(&soap_headers, response, 32);
830 smart_str_append(&auth,
Z_STR_P(login));
831 smart_str_appendc(&auth,
':');
834 smart_str_append(&auth,
Z_STR_P(password));
839 smart_str_append(&soap_headers,
buf);
842 smart_str_free(&auth);
847 if (use_proxy && !use_ssl) {
858 bool first_cookie =
true;
875 smart_str_appends(&soap_headers,
"; ");
877 first_cookie =
false;
878 smart_str_append(&soap_headers,
key);
879 smart_str_appendc(&soap_headers,
'=');
891 smart_str_0(&soap_headers);
898 smart_str_appendl(&soap_headers, request->
val, request->
len);
899 smart_str_0(&soap_headers);
903 if (request !=
buf) {
911 smart_str_free(&soap_headers_z);
915 smart_str_free(&soap_headers);
918 smart_str_free(&soap_headers_z);
926 http_headers = get_http_headers(stream);
928 if (request !=
buf) {
935 smart_str_free(&soap_headers_z);
948 http_version = get_http_header_value(
ZSTR_VAL(http_headers),
"HTTP/");
952 if (!
strncmp(http_version,
"1.1", 3)) {
956 tmp =
strstr(http_version,
" ");
959 http_status = atoi(tmp);
972 if (http_status == 100) {
976 }
while (http_status == 100);
981 if (request !=
buf) {
993 smart_str_free(&soap_headers_z);
1003 cookie_itt =
ZSTR_VAL(http_headers);
1005 while ((cookie_itt = get_http_header_value_nodup(cookie_itt,
"Set-Cookie:", &cookie_len))) {
1009 char *cookie =
estrndup(cookie_itt, cookie_len);
1010 char *eqpos =
strstr(cookie,
"=");
1011 char *sempos =
strstr(cookie,
";");
1012 if (eqpos !=
NULL && (sempos ==
NULL || sempos > eqpos)) {
1017 if (sempos !=
NULL) {
1018 cookie_len = sempos-(eqpos+1);
1020 cookie_len =
strlen(cookie)-(eqpos-cookie)-1;
1023 smart_str_appendl(&
name, cookie, eqpos - cookie);
1029 if (sempos !=
NULL) {
1030 char *
options = cookie + cookie_len+1;
1035 eqpos =
options +
sizeof(
"path=")-1;
1038 eqpos =
options +
sizeof(
"domain=")-1;
1043 if (sempos !=
NULL) {
1050 if (!zend_hash_index_exists(
Z_ARRVAL(zcookie), 1)) {
1057 if (!zend_hash_index_exists(
Z_ARRVAL(zcookie), 2)) {
1063 smart_str_free(&
name);
1066 cookie_itt = cookie_itt + cookie_len;
1073 if (use_proxy && !use_ssl) {
1074 connection = get_http_header_value(
ZSTR_VAL(http_headers),
"Proxy-Connection:");
1076 if (
strncasecmp(connection,
"close",
sizeof(
"close")-1) == 0) {
1082 if (http_close ==
FALSE) {
1083 connection = get_http_header_value(
ZSTR_VAL(http_headers),
"Connection:");
1085 if (
strncasecmp(connection,
"close",
sizeof(
"close")-1) == 0) {
1093 if (use_proxy && !use_ssl) {
1094 connection = get_http_header_value(
ZSTR_VAL(http_headers),
"Proxy-Connection:");
1096 if (
strncasecmp(connection,
"Keep-Alive",
sizeof(
"Keep-Alive")-1) == 0) {
1102 if (http_close ==
TRUE) {
1103 connection = get_http_header_value(
ZSTR_VAL(http_headers),
"Connection:");
1105 if (
strncasecmp(connection,
"Keep-Alive",
sizeof(
"Keep-Alive")-1) == 0) {
1114 http_body = get_http_body(stream, http_close,
ZSTR_VAL(http_headers));
1116 if (request !=
buf) {
1123 add_soap_fault(this_ptr,
"HTTP",
"Error Fetching http body, No Content-Length, connection closed or chunked data",
NULL,
NULL);
1127 smart_str_free(&soap_headers_z);
1131 if (request !=
buf) {
1143 if (http_status >= 300 && http_status < 400) {
1146 if ((loc = get_http_header_value(
ZSTR_VAL(http_headers),
"Location:")) !=
NULL) {
1149 if (new_url !=
NULL) {
1181 if (--redirect_max < 1) {
1183 smart_str_free(&soap_headers_z);
1191 }
else if (http_status == 401) {
1196 char *auth = get_http_header_value(
ZSTR_VAL(http_headers),
"WWW-Authenticate:");
1203 s = auth +
sizeof(
"Digest")-1;
1204 while (*
s !=
'\0') {
1206 while (*
s ==
' ') ++
s;
1208 while (*
s !=
'\0' && *
s !=
'=') ++
s;
1215 while (*
s !=
'\0' && *
s !=
'"') ++
s;
1218 while (*
s !=
'\0' && *
s !=
' ' && *
s !=
',') ++
s;
1224 while (*
s !=
'\0' && *
s !=
',') ++
s;
1225 if (*
s !=
'\0') ++
s;
1234 add_assoc_string(&digest,
name,
val);
1246 if (phpurl->
user) phpurl->
user = zend_string_copy(phpurl->
user);
1247 if (phpurl->
pass) phpurl->
pass = zend_string_copy(phpurl->
pass);
1248 if (phpurl->
host) phpurl->
host = zend_string_copy(phpurl->
host);
1249 if (phpurl->
path) phpurl->
path = zend_string_copy(phpurl->
path);
1261 if (auth)
efree(auth);
1263 smart_str_free(&soap_headers_z);
1266 content_type = get_http_header_value(
ZSTR_VAL(http_headers),
"Content-Type:");
1272 cmplen =
pos - content_type;
1274 cmplen =
strlen(content_type);
1276 if (
strncmp(content_type,
"text/xml", cmplen) == 0 ||
1277 strncmp(content_type,
"application/soap+xml", cmplen) == 0) {
1278 content_type_xml = 1;
1292 efree(content_type);
1296 content_encoding = get_http_header_value(
ZSTR_VAL(http_headers),
"Content-Encoding:");
1297 if (content_encoding) {
1304 if ((
strcmp(content_encoding,
"gzip") == 0 ||
1305 strcmp(content_encoding,
"x-gzip") == 0) &&
1306 zend_hash_str_exists(
EG(function_table),
"gzdecode",
sizeof(
"gzdecode")-1)) {
1309 }
else if (
strcmp(content_encoding,
"deflate") == 0 &&
1310 zend_hash_str_exists(
EG(function_table),
"gzuncompress",
sizeof(
"gzuncompress")-1)) {
1314 efree(content_encoding);
1332 efree(content_encoding);
1341 efree(content_encoding);
1348 if (http_status >= 400) {
1354 if (!content_type_xml) {
1357 while (*
s !=
'\0' && *
s <
' ') {
1382static char *get_http_header_value_nodup(
char *headers,
char *
type,
size_t *
len)
1385 int typelen, headerslen;
1388 headerslen =
strlen(headers);
1399 tmp =
pos + typelen;
1402 while (*tmp ==
' ' || *tmp ==
'\t') {
1408 eol = headers + headerslen;
1409 }
else if (eol > tmp) {
1410 if (*(eol-1) ==
'\r') {
1415 while (eol > tmp && (*(eol-1) ==
' ' || *(eol-1) ==
'\t')) {
1435static char *get_http_header_value(
char *headers,
char *
type)
1440 value = get_http_header_value_nodup(headers,
type, &
len);
1453 int header_close =
close, header_chunked = 0, header_length = 0, http_buf_size = 0;
1456 header = get_http_header_value(headers,
"Connection:");
1462 header = get_http_header_value(headers,
"Transfer-Encoding:");
1467 header = get_http_header_value(headers,
"Content-Length:");
1469 header_length = atoi(
header);
1471 if (!header_length && !header_chunked) {
1477 if (header_chunked) {
1478 char ch, done, headerbuf[8192];
1486 if (
sscanf(headerbuf,
"%x", &buf_size) > 0 ) {
1488 size_t len_size = 0;
1490 if (http_buf_size + buf_size + 1 < 0) {
1498 http_buf = zend_string_realloc(http_buf, http_buf_size + buf_size, 0);
1500 http_buf = zend_string_alloc(buf_size, 0);
1503 while (len_size < buf_size) {
1504 ssize_t len_read =
php_stream_read(stream, http_buf->
val + http_buf_size, buf_size - len_size);
1505 if (len_read <= 0) {
1510 len_size += len_read;
1511 http_buf_size += len_read;
1534 if (buf_size == 0) {
1545 if ((headerbuf[0] ==
'\r' && headerbuf[1] ==
'\n') ||
1546 (headerbuf[0] ==
'\n')) {
1552 if (http_buf ==
NULL) {
1556 }
else if (header_length) {
1557 if (header_length < 0 || header_length >=
INT_MAX) {
1560 http_buf = zend_string_alloc(header_length, 0);
1561 while (http_buf_size < header_length) {
1562 ssize_t len_read =
php_stream_read(stream, http_buf->
val + http_buf_size, header_length - http_buf_size);
1563 if (len_read <= 0) {
1566 http_buf_size += len_read;
1568 }
else if (header_close) {
1572 http_buf = zend_string_realloc(http_buf, http_buf_size + 4096, 0);
1574 http_buf = zend_string_alloc(4096, 0);
1578 http_buf_size += len_read;
1585 http_buf->
val[http_buf_size] =
'\0';
1586 http_buf->
len = http_buf_size;
1593 char headerbuf[8192];
1596 if ((headerbuf[0] ==
'\r' && headerbuf[1] ==
'\n') ||
1597 (headerbuf[0] ==
'\n')) {
1599 smart_str_0(&tmp_response);
1600 return tmp_response.
s;
1604 smart_str_appends(&tmp_response, headerbuf);
1607 smart_str_free(&tmp_response);
sscanf(string $string, string $format, mixed &... $vars)
strrchr(string $haystack, string $needle, bool $before_needle=false)
header(string $header, bool $replace=true, int $response_code=0)
strstr(string $haystack, string $needle, bool $before_needle=false)
strchr(string $haystack, string $needle, bool $before_needle=false)
zend_ffi_ctype_name_buf buf
hash(string $algo, string $data, bool $binary=false, array $options=[])
PHPAPI void make_digest(char *md5str, const unsigned char *digest)
PHPAPI void PHP_MD5Final(unsigned char *result, PHP_MD5_CTX *ctx)
PHPAPI void PHP_MD5Update(PHP_MD5_CTX *ctx, const void *data, size_t size)
unsigned const char * pos
int basic_authentication(zval *this_ptr, smart_str *soap_headers)
void http_context_headers(php_stream_context *context, bool has_authorization, bool has_proxy_authorization, bool has_cookies, smart_str *soap_headers)
int make_http_soap_request(zval *this_ptr, zend_string *buf, char *location, char *soapaction, int soap_version, zval *return_value)
int proxy_authentication(zval *this_ptr, smart_str *soap_headers)
#define smart_str_append_const(str, const)
PHP_JSON_API size_t int options
unsigned char key[REFLECTION_KEY_LEN]
#define SOAP_COMPRESSION_ACCEPT
#define SOAP_SSL_METHOD_SSLv2
#define Z_CLIENT_HTTPURL_P(zv)
#define Z_CLIENT_PROXY_PORT_P(zv)
#define Z_CLIENT_LOGIN_P(zv)
zend_class_entry * soap_url_class_entry
#define Z_CLIENT_USER_AGENT_P(zv)
#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv)
#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv)
#define Z_CLIENT_PROXY_LOGIN_P(zv)
#define Z_CLIENT_TRACE_P(zv)
#define Z_CLIENT_COMPRESSION_P(zv)
#define Z_CLIENT_KEEP_ALIVE_P(zv)
void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail)
#define Z_CLIENT_HTTPSOCKET_P(zv)
#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv)
#define SOAP_SSL_METHOD_SSLv23
#define Z_CLIENT_USE_DIGEST_P(zv)
#define Z_CLIENT_PROXY_PASSWORD_P(zv)
#define SOAP_SSL_METHOD_SSLv3
#define SOAP_SSL_METHOD_TLS
#define Z_CLIENT_SSL_METHOD_P(zv)
#define Z_CLIENT_PASSWORD_P(zv)
#define Z_CLIENT_PROXY_HOST_P(zv)
#define Z_CLIENT_USE_PROXY_P(zv)
#define Z_CLIENT_STREAM_CONTEXT_P(zv)
#define Z_CLIENT_DIGEST_P(zv)
#define Z_CLIENT_COOKIES_P(zv)
#define SOAP_COMPRESSION_DEFLATE
#define php_stream_context_from_zval(zcontext, nocontext)
PHPAPI zval * php_stream_context_get_option(php_stream_context *context, const char *wrappername, const char *optionname)
PHPAPI void php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue)
#define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode)
PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate)
@ STREAM_CRYPTO_METHOD_SSLv3_CLIENT
@ STREAM_CRYPTO_METHOD_TLS_CLIENT
@ STREAM_CRYPTO_METHOD_SSLv23_CLIENT
@ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
#define STREAM_XPORT_CONNECT
PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream)
#define STREAM_XPORT_CLIENT
struct _php_stream php_stream
struct _php_stream_context php_stream_context
#define php_stream_read(stream, buf, count)
#define php_stream_gets(stream, buf, maxlen)
#define php_stream_auto_cleanup(stream)
#define php_stream_getc(stream)
#define php_stream_eof(stream)
#define php_stream_close(stream)
#define PHP_STREAM_CONTEXT(stream)
#define php_stream_from_zval_no_verify(xstr, pzval)
#define STREAM_LOCATE_WRAPPERS_ONLY
PHPAPI php_stream_wrapper * php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options)
#define php_stream_write(stream, buf, count)
PHPAPI php_url * php_url_parse(char const *str)
PHPAPI void php_url_free(php_url *theurl)
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
ZEND_API void add_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length)
ZEND_API void add_index_str(zval *arg, zend_ulong index, zend_string *str)
ZEND_API void add_index_bool(zval *arg, zend_ulong index, bool b)
#define ZVAL_STRING(z, s)
#define call_user_function(function_table, object, function_name, retval_ptr, param_count, params)
#define ZVAL_STRINGL(z, s, l)
#define estrndup(s, length)
error_reporting(?int $error_level=null)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
#define strncasecmp(s1, s2, n)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val)
#define ZEND_HASH_FOREACH_VAL(ht, _val)
#define ZEND_LONG_FMT_SPEC
struct _zend_string zend_string
ZEND_API void ZEND_FASTCALL convert_to_null(zval *op)
#define UNEXPECTED(condition)
#define zend_string_equals_literal(str, literal)
#define ZSTR_EMPTY_ALLOC()
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
#define ZVAL_STR_COPY(z, s)
#define Z_STRLEN_P(zval_p)
#define Z_OBJCE_P(zval_p)
#define SEPARATE_ARRAY(zv)
#define ZVAL_COPY_VALUE(z, v)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)