# ext/soap and http header

- Thread: https://externals.io/message/40707
- Original archive: https://news-web.php.net/php.internals/40707
- Started by Brian J. France on 2008-09-26T13:15:12+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #40707 — Brian J. France — 2008-09-26T13:15:12+00:00

URL: https://externals.io/message/40707#40707

Hi,

   Currently there isn't a way to add http headers into a soap  
request.  Below is a patch to get headers from the passed in context  
(code taken from ext/standard/http_fopen_wrapper.c).  Doing something  
like this:

   $opts = array('http' => array('header' => 'X-foo: bar'));
   $ctx = stream_context_create($opts);

and then passing $ctx into the SoapClient constructor.  This is a  
simple patch as it assumes the user isn't going to duplicate items  
like content-type, user-agent or other headers already set by the soap  
client code.

This patch is based on 5.2.5, it could easily be ported to HEAD/5_3/5_2.

Thoughts?

Thanks,

Brian

---------


--- ext/soap/php_http.c.orig	2008-09-26 05:39:50.000000000 -0700
+++ ext/soap/php_http.c	2008-09-26 05:54:15.000000000 -0700
@@ -391,7 +391,8 @@
  	PG(allow_url_fopen) = old_allow_url_fopen;

  	if (stream) {
-		zval **cookies, **login, **password;
+	    php_stream_context *context = NULL;
+		zval **cookies, **login, **password, **tmpzval = NULL;
  	  int ret = zend_list_insert(phpurl, le_url);

  		add_property_resource(this_ptr, "httpurl", ret);
@@ -638,6 +639,23 @@
  			proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
  		}

+		/* get context to check for http headers */
+		if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
+					      "_stream_context", sizeof("_stream_context"),  
(void**)&tmp)) {
+		    context = php_stream_context_from_zval(*tmp, 0);
+		}
+
+		/* Send http headers from context */
+		if (context &&
+		    php_stream_context_get_option(context, "http", "header",  
&tmpzval) == SUCCESS &&
+		    Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
+		    char *tmp = php_trim(Z_STRVAL_PP(tmpzval),  
Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC);
+		    int len = strlen(tmp);
+		    if (len > 0) {
+			smart_str_appendl(&soap_headers, tmp, len);
+		    }
+		}
+
  		/* Send cookies along with request */
  		if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies",  
sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
  			zval **data;

---

## #40708 — Brian J. France — 2008-09-26T14:22:03+00:00

URL: https://externals.io/message/40707#40708 · In reply to: #40707

After some more testing I needed to tweak the patch and the example,  
here is version 2.

  $opts = array('http' => array('header' => 'X-foo: bar'));
  $ctx = stream_context_create($opts);

Brian


--- ext/soap/php_http.c.orig	2008-09-26 05:39:50.000000000 -0700
+++ ext/soap/php_http.c	2008-09-26 06:42:34.000000000 -0700
  -391,7 +391,8 @@
  	PG(allow_url_fopen) = old_allow_url_fopen;

  	if (stream) {
-		zval **cookies, **login, **password;
+	    php_stream_context *context = NULL;
+		zval **cookies, **login, **password, **tmpzval = NULL;
  	  int ret = zend_list_insert(phpurl, le_url);

  		add_property_resource(this_ptr, "httpurl", ret);
  -638,6 +639,19 @@
  			proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
  		}

+		/* get context to check for http headers */
+		if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
+					      "_stream_context", sizeof("_stream_context"),  
(void**)&tmp)) {
+		    context = php_stream_context_from_zval(*tmp, 0);
+		}
+
+		/* Send http headers from context */
+		if (context &&
+		    php_stream_context_get_option(context, "http", "header",  
&tmpzval) == SUCCESS &&
+		    Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
+		    smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmpzval),  
Z_STRLEN_PP(tmpzval));
+		}
+
  		/* Send cookies along with request */
  		if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies",  
sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
  			zval **data;

---

## #40758 — Dmitry Stogov — 2008-09-29T08:11:40+00:00

URL: https://externals.io/message/40707#40758 · In reply to: #40708

Hi Brian,

I think you patch does the things you like properly, but why do we need
such ability? I don't see a use-case.

In case of accepting this patch, we also need to care about duplicate
headers.

Thanks. Dmitry.

Brian J. France wrote:
> After some more testing I needed to tweak the patch and the example,
> here is version 2.
> 
>  $opts = array('http' => array('header' => 'X-foo: bar'));
>  $ctx = stream_context_create($opts);
> 
> Brian
> 
> 
> --- ext/soap/php_http.c.orig    2008-09-26 05:39:50.000000000 -0700
> +++ ext/soap/php_http.c    2008-09-26 06:42:34.000000000 -0700
>  -391,7 +391,8 @@
>      PG(allow_url_fopen) = old_allow_url_fopen;
> 
>      if (stream) {
> -        zval **cookies, **login, **password;
> +        php_stream_context *context = NULL;
> +        zval **cookies, **login, **password, **tmpzval = NULL;
>        int ret = zend_list_insert(phpurl, le_url);
> 
>          add_property_resource(this_ptr, "httpurl", ret);
>  -638,6 +639,19 @@
>              proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
>          }
> 
> +        /* get context to check for http headers */
> +        if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
> +                          "_stream_context", sizeof("_stream_context"),
> (void**)&tmp)) {
> +            context = php_stream_context_from_zval(*tmp, 0);
> +        }
> +
> +        /* Send http headers from context */
> +        if (context &&
> +            php_stream_context_get_option(context, "http", "header",
> &tmpzval) == SUCCESS &&
> +            Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
> +            smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmpzval),
> Z_STRLEN_PP(tmpzval));
> +        }
> +
>          /* Send cookies along with request */
>          if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies",
> sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
>              zval **data;

---

## #40777 — Rasmus Lerdorf — 2008-09-29T14:44:00+00:00

URL: https://externals.io/message/40707#40777 · In reply to: #40758

Dmitry Stogov wrote:
> Hi Brian,
>
> I think you patch does the things you like properly, but why do we need
> such ability? I don't see a use-case.
>
> In case of accepting this patch, we also need to care about duplicate
> headers.

Some web services require custom headers for authentication or to bounce 
along information about the originating request in order to do proper 
logging and accounting about which top-level users are causing the 
backend web services requests.

-Rasmus

---

## #40780 — Dmitry Stogov — 2008-09-29T15:51:48+00:00

URL: https://externals.io/message/40707#40780 · In reply to: #40777

Hi Rasmus,

Rasmus Lerdorf wrote:
> Dmitry Stogov wrote:
> > […]
> 
> Some web services require custom headers for authentication or to bounce
> along information about the originating request in order to do proper
> logging and accounting about which top-level users are causing the
> backend web services requests.

Could you give an example.

Thanks. Dmitry.

---

## #40782 — david.zuelke@bitextender.com — 2008-09-29T16:15:04+00:00

URL: https://externals.io/message/40707#40782 · In reply to: #40758

just curious, why is ext/soap internally duplicating this http stuff  
instead of using the http stream stuff directly? or did I  
misunderstand something?



Am 29.09.2008 um 10:11 schrieb Dmitry Stogov:

> Hi Brian,
>
> I think you patch does the things you like properly, but why do we  
> need
> such ability? I don't see a use-case.
>
> In case of accepting this patch, we also need to care about duplicate
> headers.
>
> Thanks. Dmitry.
>
> Brian J. France wrote:
> > […]

---

## #40802 — Rasmus Lerdorf — 2008-09-30T06:14:55+00:00

URL: https://externals.io/message/40707#40802 · In reply to: #40780

Dmitry Stogov wrote:
> Hi Rasmus,
>
> Rasmus Lerdorf wrote:
> > […]
>
> Could you give an example.

Well, for one a bunch of the internal Yahoo web services require a 
certificate header.  I doubt we are the only Web company who needs to 
authenticate the higher-level users of lower-level web services.

We are running with Brian's patch now, but I don't really see the reason 
not to make it possible for people to set custom headers on web services 
requests.

Another example is the Weather Underground API.  They ask you to set the 
User-Agent to your email address so they can contact you if your app 
starts causing them problems.

-Rasmus

---

## #40806 — Dmitry Stogov — 2008-09-30T07:42:38+00:00

URL: https://externals.io/message/40707#40806 · In reply to: #40802

Rasmus Lerdorf wrote:
> Dmitry Stogov wrote:
> > […]
> 
> Well, for one a bunch of the internal Yahoo web services require a
> certificate header.  I doubt we are the only Web company who needs to
> authenticate the higher-level users of lower-level web services.
> 
> We are running with Brian's patch now, but I don't really see the reason
> not to make it possible for people to set custom headers on web services
> requests.

I see. It's not a problem. I'll look and probably add the patch on this
week.

Thanks. Dmitry.

> Another example is the Weather Underground API.  They ask you to set the
> User-Agent to your email address so they can contact you if your app
> starts causing them problems.
> 
> -Rasmus

---

## #40818 — Dmitry Stogov — 2008-10-01T13:15:57+00:00

URL: https://externals.io/message/40707#40818 · In reply to: #40708

Hi Brain,

A little bit different patch committed into PHP_5_3 and HEAD.
I don't think it's allowed to commit it into PHP_5_2.
Please verify, if it works for you.

Thanks. Dmitry.

Brian J. France wrote:
> After some more testing I needed to tweak the patch and the example,
> here is version 2.
> 
>  $opts = array('http' => array('header' => 'X-foo: bar'));
>  $ctx = stream_context_create($opts);
> 
> Brian
> 
> 
> --- ext/soap/php_http.c.orig    2008-09-26 05:39:50.000000000 -0700
> +++ ext/soap/php_http.c    2008-09-26 06:42:34.000000000 -0700
>  -391,7 +391,8 @@
>      PG(allow_url_fopen) = old_allow_url_fopen;
> 
>      if (stream) {
> -        zval **cookies, **login, **password;
> +        php_stream_context *context = NULL;
> +        zval **cookies, **login, **password, **tmpzval = NULL;
>        int ret = zend_list_insert(phpurl, le_url);
> 
>          add_property_resource(this_ptr, "httpurl", ret);
>  -638,6 +639,19 @@
>              proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
>          }
> 
> +        /* get context to check for http headers */
> +        if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
> +                          "_stream_context", sizeof("_stream_context"),
> (void**)&tmp)) {
> +            context = php_stream_context_from_zval(*tmp, 0);
> +        }
> +
> +        /* Send http headers from context */
> +        if (context &&
> +            php_stream_context_get_option(context, "http", "header",
> &tmpzval) == SUCCESS &&
> +            Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
> +            smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmpzval),
> Z_STRLEN_PP(tmpzval));
> +        }
> +
>          /* Send cookies along with request */
>          if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies",
> sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
>              zval **data;
