int buf_size,err,ret;
sdlPtr sdl;
php_url *phpurl = NULL;
- SOAP_STREAM stream;
+ php_stream *stream;
zval **trace;
FETCH_THIS_SOCKET(stream);
if(!stream)
{
char *url;
+ int use_ssl;
if(!sdl)
{
}
phpurl = php_url_parse(url);
+ if (phpurl == NULL) {
+ php_error(E_ERROR, "Unable to parse URL \"%s\"", url);
+ }
+ use_ssl = strcmp(phpurl->scheme, "https") == 0;
+#if !HAVE_OPENSSL_EXT
+ if (use_ssl) {
+ php_error(E_ERROR, "SSL support not available in this build");
+ }
+#endif
+
if (phpurl->port == 0) {
- if (strcmp(phpurl->scheme, "http") == 0)
- phpurl->port = 80;
- else if (strcmp(phpurl->scheme, "https") == 0)
- phpurl->port = 443;
+ phpurl->port = use_ssl ? 443 : 80;
}
-#ifdef PHP_HAVE_STREAMS
stream = php_stream_sock_open_host(phpurl->host, (unsigned short)phpurl->port, SOCK_STREAM, NULL, NULL);
-#else
- stream = get_socket(phpurl->host, phpurl->port, 10);
-#endif
+
if(stream)
{
- ret = zend_list_insert((void *)stream, le_http_socket);
- add_property_resource(this_ptr, "httpsocket", ret);
- zend_list_addref(ret);
+
+#if HAVE_OPENSSL_EXT
+ /* fire up SSL, if requested */
+ if (use_ssl) {
+ if (FAILURE == php_stream_sock_ssl_activate(stream, 1)) {
+ php_error(E_ERROR, "SSL Connection attempt failed");
+ }
+ }
+#endif
+
+ add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream));
ret = zend_list_insert(phpurl, le_url);
add_property_resource(this_ptr, "httpurl", ret);
zend_list_addref(ret);
} else {
- php_error(E_ERROR,"Could not connect to host");
+ php_error(E_ERROR, "Could not connect to host");
}
}
- if(stream)
- {
+ if (stream) {
zval **cookies;
char *header = "POST %s HTTP/1.1\r\nConnection: close\r\nAccept: text/html; text/xml; text/plain\r\nUser-Agent: PHP SOAP 0.1\r\nHost: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nSOAPAction: \"%s\"\r\n";
int size = strlen(header) + strlen(phpurl->host) + strlen(phpurl->path) + 10;
sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction);
}
-#ifdef PHP_HAVE_STREAMS
err = php_stream_write(stream, soap_headers, strlen(soap_headers));
-#else
- err = send(stream, soap_headers, strlen(soap_headers), 0);
-#endif
+
if(err != (int)strlen(soap_headers))
php_error(E_ERROR,"Failed Sending HTTP Headers");
smart_str_appendl(&cookie_str, "\r\n", 2);
smart_str_0(&cookie_str);
-#ifdef PHP_HAVE_STREAMS
err = php_stream_write(stream, cookie_str.c, cookie_str.len);
-#else
- err = send(stream, cookie_str.c, cookie_str.len,0);
-#endif
+
if(err != (int)cookie_str.len)
php_error(E_ERROR,"Failed Sending HTTP Headers");
smart_str_free(&cookie_str);
}
-#ifdef PHP_HAVE_STREAMS
err = php_stream_write(stream, "\r\n", 2);
-#else
- err = send(stream, "\r\n", 2, 0);
-#endif
+
if(err != 2)
php_error(E_ERROR,"Failed Sending HTTP Headers");
-#ifdef PHP_HAVE_STREAMS
err = php_stream_write(stream, buf, buf_size);
-#else
- err = send(stream, buf, buf_size, 0);
-#endif
+
if(err != (int)strlen(buf))
php_error(E_ERROR,"Failed Sending HTTP Content");
int http_header_size, http_body_size, http_close;
sdlPtr sdl;
zval **socket_ref;
- SOAP_STREAM stream;
+ php_stream *stream;
zval **trace;
FETCH_THIS_SDL(sdl);
}
*/
- if(http_close)
- {
-#ifdef PHP_HAVE_STREAMS
+ if (http_close) {
php_stream_close(stream);
-#else
- SOCK_CLOSE(stream);
-#endif
- zend_list_delete(Z_RESVAL_PP(socket_ref));
- zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", strlen("httpsocket") + 1);
+ zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
}
/* Check and see if the server even sent a xml document */
char *get_http_header_value(char *headers, char *type)
{
- char *tmp = NULL,*var = NULL;
- int size;
+ char *pos, *tmp = NULL;
+ int typelen, headerslen;
+
+ typelen = strlen(type);
+ headerslen = strlen(headers);
+
+ /* header `titles' can be lower case, or any case combination, according
+ * to the various RFC's. */
+ pos = headers;
+ do {
+ /* start of buffer or start of line */
+ if (strncasecmp(pos, type, typelen) == 0) {
+ char *eol;
+
+ /* match */
+ tmp = pos + typelen;
+ eol = strstr(tmp, "\r\n");
+ if (eol == NULL) {
+ eol = headers + headerslen;
+ }
+ return estrndup(tmp, eol - tmp);
+ }
+
+ /* find next line */
+ pos = strstr(pos, "\r\n");
+ if (pos)
+ pos += 2;
- tmp = strstr(headers, type);
- if(tmp != NULL)
- {
- tmp += strlen(type);
- size = strstr(tmp, "\r\n") - tmp;
- var = emalloc(size + 1);
- strncpy(var, tmp, size);
- var[size] = '\0';
- }
- return var;
+ } while (pos);
+
+ return NULL;
}
-int get_http_body(SOAP_STREAM stream, char *headers, char **response, int *out_size TSRMLS_DC)
+int get_http_body(php_stream *stream, char *headers, char **response, int *out_size TSRMLS_DC)
{
- char *trans_enc, *content_length, *http_buf;
+ char *trans_enc, *content_length, *http_buf = NULL;
int http_buf_size = 0;
-/* TSRMLS_FETCH();*/
trans_enc = get_http_header_value(headers, "Transfer-Encoding: ");
content_length = get_http_header_value(headers, "Content-Length: ");
- /* this is temp...
- netscape enterprise server sends in lowercase???
- */
- if(content_length == NULL)
- content_length = get_http_header_value(headers, "Content-length: ");
-
- if(trans_enc && !strcmp(trans_enc, "chunked"))
- {
+ if (trans_enc && !strcmp(trans_enc, "chunked")) {
int cur = 0, size = 0, buf_size = 0, len_size;
char done, chunk_size[10];
done = FALSE;
- http_buf = emalloc(1);
- *http_buf = '\0';
- while(!done)
- {
- for (cur = 0; cur < 3 || !(chunk_size[cur - 2] == '\r' && chunk_size[cur - 1] == '\n'); cur++)
-#ifdef PHP_HAVE_STREAMS
- chunk_size[cur] = php_stream_getc(stream);
-#else
- chunk_size[cur] = php_sock_fgetc(stream);
-#endif
- chunk_size[cur] = '\0';
- if(sscanf(chunk_size,"%x",&buf_size) != -1)
- {
- http_buf = erealloc(http_buf,http_buf_size + buf_size);
+ http_buf = NULL;
+
+ while (!done) {
+ php_stream_gets(stream, chunk_size, sizeof(chunk_size));
+
+ if (sscanf(chunk_size, "%x", &buf_size) != -1) {
+ http_buf = erealloc(http_buf, http_buf_size + buf_size + 1);
len_size = 0;
- while(http_buf_size < buf_size)
- {
-#ifdef PHP_HAVE_STREAMS
- len_size += php_stream_read(stream, &http_buf[http_buf_size], buf_size - len_size);
-#else
- len_size += php_sock_fread(&http_buf[http_buf_size], buf_size - len_size, stream);
-#endif
+
+ while (http_buf_size < buf_size) {
+ len_size += php_stream_read(stream, http_buf + http_buf_size, buf_size - len_size);
http_buf_size += len_size;
}
-#ifdef PHP_HAVE_STREAMS
- php_stream_getc(stream);php_stream_getc(stream);
-#else
+
/* Eat up '\r' '\n' */
- php_sock_fgetc(stream);php_sock_fgetc(stream);
-#endif
+ php_stream_getc(stream);php_stream_getc(stream);
}
- if(buf_size == 0)
+ if (buf_size == 0) {
done = TRUE;
+ }
}
efree(trans_enc);
- }
- else if(content_length)
- {
+
+ if (http_buf == NULL) {
+ http_buf = estrndup("", 1);
+ http_buf_size = 1;
+ } else {
+ http_buf[http_buf_size] = '\0';
+ }
+
+ } else if (content_length) {
int size;
size = atoi(content_length);
http_buf = emalloc(size + 1);
- while(http_buf_size < size)
-#ifdef PHP_HAVE_STREAMS
- http_buf_size += php_stream_read(stream, &http_buf[http_buf_size], size - http_buf_size);
-#else
- http_buf_size += php_sock_fread(&http_buf[http_buf_size], size - http_buf_size, stream);
-#endif
+ while(http_buf_size < size) {
+ http_buf_size += php_stream_read(stream, http_buf + http_buf_size, size - http_buf_size);
+ }
http_buf[size] = '\0';
efree(content_length);
+ } else {
+ php_error(E_ERROR, "Don't know how to read http body, No Content-Length or chunked data");
}
- else
- php_error(E_ERROR,"Don't know how to read http body, No Content-Length or chunked data");
(*response) = http_buf;
(*out_size) = http_buf_size;
return TRUE;
}
-int get_http_headers(SOAP_STREAM stream, char **response, int *out_size TSRMLS_DC)
+int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_DC)
{
- int done;
+ int done = FALSE;
char chr;
smart_str tmp_response = {0};
-
- done = FALSE;
+ char headerbuf[8192];
while(!done)
{
-#ifdef PHP_HAVE_STREAMS
- chr = php_stream_getc(stream);
-#else
- chr = php_sock_fgetc(stream);
-#endif
- if(chr != EOF)
- {
- smart_str_appendc(&tmp_response, chr);
- if(tmp_response.c[tmp_response.len - 2] == '\r' && tmp_response.c[tmp_response.len - 1] == '\n' &&
- tmp_response.c[tmp_response.len - 4] == '\r' && tmp_response.c[tmp_response.len - 3] == '\n')
- {
- smart_str_0(&tmp_response);
- done = TRUE;
- }
- } else {
- return FALSE;
+ if (!php_stream_gets(stream, headerbuf, sizeof(headerbuf))) {
+ break;
+ }
+
+ if (strcmp(headerbuf, "\r\n") == 0) {
+ /* empty line marks end of headers */
+ done = TRUE;
+ break;
}
+
+ /* add header to collection */
+ smart_str_appends(&tmp_response, headerbuf);
}
+ smart_str_0(&tmp_response);
(*response) = tmp_response.c;
(*out_size) = tmp_response.len;
- return TRUE;
+ return done;
}
-#ifndef PHP_HAVE_STREAMS
-SOCKET get_socket(char* host,int portno,int time)
-{
- SOCKET socketd = -1;
- struct sockaddr_in server;
- struct timeval timeout;
-
- memset(&server, 0, sizeof(server));
- socketd = socket(AF_INET,SOCK_STREAM,0);
- if (socketd == SOCK_ERR) {
- if(socketd > 0)
- SOCK_CLOSE(socketd);
- return FALSE;
- }
- server.sin_family = AF_INET;
-
- if(php_lookup_hostname(host,&server.sin_addr)) {
- if(socketd > 0)
- SOCK_CLOSE(socketd);
- return FALSE;
- }
- server.sin_port = htons((unsigned short)portno);
- timeout.tv_sec = time;
- timeout.tv_usec = 0;
- if (php_connect_nonb(socketd, (struct sockaddr *)&server, sizeof(struct sockaddr_in), &timeout) == SOCK_CONN_ERR) {
- if(socketd > 0)
- SOCK_CLOSE(socketd);
- return FALSE;
- }
- return socketd;
-}
-#endif
#include "php_soap.h"
int le_sdl = 0;
-int le_http_socket = 0;
int le_url = 0;
int le_service = 0;
/* TODO: add ini entry for always use soap errors */
ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, php_soap_del_globals);
+ /* Enable php stream/wrapper support for libxml */
+ xmlRegisterDefaultInputCallbacks();
+ xmlRegisterInputCallbacks(php_stream_xmlIO_match_wrapper, php_stream_xmlIO_open_wrapper,
+ php_stream_xmlIO_read, php_stream_xmlIO_close);
+
/* Register SoapObject class */
/* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated.
soap_call_function_handler should be of type struct _zend_function, not (*handle_function_call).
zend_register_internal_class(&soap_param_class_entry TSRMLS_CC);
le_sdl = register_list_destructors(NULL, NULL);
- le_http_socket = register_list_destructors(delete_http_socket, NULL);
le_url = register_list_destructors(delete_url, NULL);
le_service = register_list_destructors(delete_service, NULL);
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &function_name) == FAILURE)
php_error(E_ERROR, "Invalid parameters passed to addfunction");
+ /* TODO: could use zend_is_callable here */
+
if(function_name->type == IS_ARRAY)
{
if(service->type == SOAP_FUNCTIONS)
ret = zend_list_insert(sdl, le_sdl);
add_property_resource(thisObj, "sdl", ret);
+ /* FIXME: this is extremely bad practice */
add_property_resource(thisObj, "port", (long)get_binding_from_type(sdl, BINDING_SOAP));
zend_list_addref(ret);
}
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ss",
&function, &function_len, &args, &soap_action, &soap_action_len, &uri, &uri_len) == FAILURE)
- php_error(E_ERROR, "Invalid arguments to SoapObject->__call");
+ php_error(E_ERROR, "Invalid arguments to SoapObject->__generate");
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
}
if (ret_params) {
+ FREE_ZVAL(ret_params[0]);
efree(ret_params);
}
}
}
if (ret_params) {
+ FREE_ZVAL(ret_params[0]);
efree(ret_params);
}
}
if(zend_hash_find(Z_OBJPROP_P(thisObj), "__last_request", sizeof("__last_request"), (void **)&tmp) == SUCCESS)
{
- *return_value = *(*tmp);
- zval_copy_ctor(return_value);
- return;
+ RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
}
RETURN_NULL();
}
if(zend_hash_find(Z_OBJPROP_P(thisObj), "__last_response", sizeof("__last_response"), (void **)&tmp) == SUCCESS)
{
- *return_value = *(*tmp);
- zval_copy_ctor(return_value);
- return;
+ RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
}
RETURN_NULL();
}
zval *thisObj;
char *function = Z_STRVAL(function_name->element);
zend_function *builtin_function;
-
-// TSRMLS_FETCH();
GET_THIS_OBJECT(thisObj);
}
if (ret_params) {
+ FREE_ZVAL(ret_params[0]);
efree(ret_params);
}
}
free(tmp);
}
-void delete_http_socket(void *handle)
-{
- SOAP_STREAM stream = (SOAP_STREAM)handle;
-#ifdef PHP_HAVE_STREAMS
- TSRMLS_FETCH();
- php_stream_close(stream);
-#else
- SOCK_CLOSE(stream);
-#endif
-}
-
void delete_url(void *handle)
{
php_url_free((php_url*)handle);