]> granicus.if.org Git - php/commitdiff
Support content_type stream context option in soap
authorVincent JARDIN <vjardin@free.fr>
Tue, 23 Apr 2019 21:10:38 +0000 (23:10 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 13 May 2019 08:51:03 +0000 (10:51 +0200)
Allows overriding the HTTP header using the HTTP context:

    $client = new SoapClient('http://url.wsdl&v=latest', [
      'stream_context' => stream_context_create([
        'http' => [
          'content_type' => 'foobarX',
        ],
      ]),
    ]);

ext/soap/php_http.c
ext/soap/tests/custom_content_type.phpt [new file with mode: 0644]

index 9df865b76a0ad2115b9a91d0972bde59c2218a03..5938a2e081b5981ecef33c4cdd54642a60d7f4ff 100644 (file)
@@ -617,7 +617,16 @@ try_again:
                smart_str_append_smart_str(&soap_headers, &soap_headers_z);
 
                if (soap_version == SOAP_1_2) {
-                       smart_str_append_const(&soap_headers,"Content-Type: application/soap+xml; charset=utf-8");
+                       if (context &&
+                               (tmp = php_stream_context_get_option(context, "http", "content_type")) != NULL &&
+                               Z_TYPE_P(tmp) == IS_STRING &&
+                               Z_STRLEN_P(tmp) > 0
+                       ) {
+                               smart_str_append_const(&soap_headers, "Content-Type: ");
+                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                       } else {
+                               smart_str_append_const(&soap_headers, "Content-Type: application/soap+xml; charset=utf-8");
+                       }
                        if (soapaction) {
                                smart_str_append_const(&soap_headers,"; action=\"");
                                smart_str_appends(&soap_headers, soapaction);
@@ -625,7 +634,17 @@ try_again:
                        }
                        smart_str_append_const(&soap_headers,"\r\n");
                } else {
-                       smart_str_append_const(&soap_headers,"Content-Type: text/xml; charset=utf-8\r\n");
+                       if (context &&
+                               (tmp = php_stream_context_get_option(context, "http", "content_type")) != NULL &&
+                               Z_TYPE_P(tmp) == IS_STRING &&
+                               Z_STRLEN_P(tmp) > 0
+                       ) {
+                               smart_str_append_const(&soap_headers, "Content-Type: ");
+                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                               smart_str_append_const(&soap_headers, "\r\n");
+                       } else {
+                               smart_str_append_const(&soap_headers, "Content-Type: text/xml; charset=utf-8\r\n");
+                       }
                        if (soapaction) {
                                smart_str_append_const(&soap_headers, "SOAPAction: \"");
                                smart_str_appends(&soap_headers, soapaction);
diff --git a/ext/soap/tests/custom_content_type.phpt b/ext/soap/tests/custom_content_type.phpt
new file mode 100644 (file)
index 0000000..b0dbc1d
--- /dev/null
@@ -0,0 +1,77 @@
+--TEST--
+SOAP customized Content-Type, eg. SwA use case
+--SKIPIF--
+<?php
+       require_once('skipif.inc');
+
+       if (!file_exists(__DIR__ . "/../../../sapi/cli/tests/php_cli_server.inc")) {
+               echo "skip sapi/cli/tests/php_cli_server.inc required but not found";
+       }
+?>
+--FILE--
+<?php
+
+include __DIR__ . "/../../../sapi/cli/tests/php_cli_server.inc";
+
+$args = substr(PHP_OS, 0, 3) == 'WIN' ? "-d extension_dir=" . ini_get("extension_dir") . " -d extension=php_soap.dll" : "";
+$code = <<<'PHP'
+/* Receive */
+$content = trim(file_get_contents("php://input")) . PHP_EOL;
+PHP;
+
+php_cli_server_start($code, false, $args);
+
+$client = new soapclient(NULL, [
+  'location' => 'http://' . PHP_CLI_SERVER_ADDRESS,
+  'uri' => 'misc-uri',
+  'soap_version' => SOAP_1_2,
+  'user_agent' => 'Vincent JARDIN, test headers',
+  'trace' => true, /* record the headers before sending */
+  'stream_context' => stream_context_create([
+    'http' => [
+      'header' => sprintf("MIME-Version: 1.0\r\n"),
+      'content_type' => sprintf("Multipart/Related")
+    ],
+  ]),
+]);
+
+$client->__soapCall("foo", [ 'arg1' => "XXXbar"]);
+
+$headers = $client->__getLastRequestHeaders();
+
+if (strpos($headers, 'Multipart/Related; action="misc-uri#foo"') === FALSE)
+  printf("Content-Type NOK %s" . PHP_EOL, $headers);
+else
+  printf("Content-Type OK" . PHP_EOL);
+
+/*
+ * In case of an empty content-type, let's fallback to the default content.
+ */
+$client2 = new soapclient(NULL, [
+  'location' => 'http://' . PHP_CLI_SERVER_ADDRESS,
+  'uri' => 'misc-uri',
+  'soap_version' => SOAP_1_2,
+  'user_agent' => 'Vincent JARDIN, test headers',
+  'trace' => true, /* record the headers before sending */
+  'stream_context' => stream_context_create([
+    'http' => [
+      'header' => sprintf("MIME-Version: 1.0\r\n"),
+      'content_type' => sprintf("")
+    ],
+  ]),
+]);
+
+$client2->__soapCall("foo", [ 'arg1' => "XXXbar"]);
+
+$headers = $client2->__getLastRequestHeaders();
+
+if (strpos($headers, 'Content-Type: application/soap+xml; charset=utf-8; action="misc-uri#foo"') === FALSE)
+  printf("Content-Type Default NOK %s" . PHP_EOL, $headers);
+else
+  printf("Content-Type Default OK" . PHP_EOL);
+?>
+==DONE==
+--EXPECT--
+Content-Type OK
+Content-Type Default OK
+==DONE==