Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoapServer returns Internal Server Error (no log) in Laravel 5.2 #13672

Closed
farhoudi opened this issue May 24, 2016 · 21 comments
Closed

SoapServer returns Internal Server Error (no log) in Laravel 5.2 #13672

farhoudi opened this issue May 24, 2016 · 21 comments

Comments

@farhoudi
Copy link

I'm trying to run soap server in laravel 5.2. I create wsdl file using piotrooi/wsdl-creator and create SoapServer object then handle it.
And my SoapClient can call it but returns an Internal Server Error Without logging in error-log file.
Here is my code:

<?php namespace Giant\Http\Controllers;

class SoapController extends Controller {

    public function __construct() {
        parent::__construct();
        ini_set('soap.wsdl_cache_enabled', 0);
        ini_set('soap.wsdl_cache_ttl', 0);
        ini_set('default_socket_timeout', 300);
        ini_set('max_execution_time', 0);
    }

    public function server() {
        $location = url('server'); // http://payment.dev/server
        $namespace = $location;
        $class = "\\Giant\\Http\\Controllers\\HelloWorld";

        $wsdl = new \WSDL\WSDLCreator($class, $location);
        $wsdl->setNamespace($namespace);

        if (isset($_GET['wsdl'])) {
            $wsdl->renderWSDL();
            exit;
        }

        $wsdl->renderWSDLService();

        $wsdlUrl = url('wsdl/server.wsdl');
        $server = new \SoapServer(
            url('server?wsdl'),
            array(
                'exceptions' => 1,
                'trace' => 1,
            )
        );

        $server->setClass($class);
        $server->handle();
        exit;
    }

    public function client() {
        $wsdl = url('server?wsdl');
        $client = new \SoapClient($wsdl);

        try {
            $res = $client->hello('world');
            dd($res);
        } catch (\Exception $ex) {
            dd($ex);
        }
    }
}


class HelloWorld {
    /**
     * @WebMethod
     * @desc Hello Web-Service
     * @param string $name
     * @return string $helloMessage
     */
    public function hello($name) {
        return "hello {$name}";
    }
}

And my WSDL file: WSDL
And my routes:

Route::any('/server', 'SoapController@server');
Route::any('/client', 'SoapController@client');

There is no problem with wsdl-creator, It is working in laravel 4.2. And I have also tried nusoap and php2wsdl libraries.
My SoapClient is working well. Because it can get service from other soap servers in other urls, But SoapServer is not working well in Laravel 5.2. (I have tried my code in pure PHP script with namespaces and it is working)

@farhoudi
Copy link
Author

The problem resolved.
I was wrong about log. I was checking error_log file for apache not the one for laravel.
And there i got TokenMismatchException and I just put my url of soap server inside except array of CsrfVerifyMiddleware.

@devexsolutions
Copy link

Hi @AliFarhoudi :
Can you publish, the problem´s solution. I need resolve the error too.
Thanks.

@farhoudi
Copy link
Author

Hi @devexsolutions
When you send a request (get/post/soap) to your controller (where your soap server is), laravel request handler tries to verify csrf token, and because your request is from another host laravel request handler does not allow your request to be processed.
To solve this issue you need to tell laravel not to verify csrf token for your soap server path. For example my soap server was running in /services route and I added this route to exceptions array so that laravel would not verify csrf token for this route.
Exceptions array is located in app/Http/MiddlewareVerifyCsrfToken.php file.
Whenever you encounter an internal server error there should a log for that default in storage/logs/laravel.log

@devexsolutions
Copy link

devexsolutions commented Jun 22, 2016

@AliFarhoudi dont fine work, Internal Error

My soap server run in /server route. This is my Middleware\VerifyCsrfToken code
`
**use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
/
protected $except = [
'/server'
];
}
*
`
Routes.php
**
Route::any('/server', 'SoapController@server');
**

Laravel.log

*#58 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#59 C:\xampp2\htdocs\myproject\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(32): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#60 [internal function]: Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#61 C:\xampp2\htdocs\myproject\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(103): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#62 C:\xampp2\htdocs\myproject\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(132): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#63 C:\xampp2\htdocs\myproject\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(99): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#64 C:\xampp2\htdocs\myproject\public\index.php(54): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#65 {main}
*

php_error.log

**[22-Jun-2016 10:06:58 UTC] PHP Fatal error: Class 'TokenMismatchException' not found in C:\xampp2\htdocs\myproject\app\Http\Middleware\VerifyCsrf.php on line 36

**

@farhoudi
Copy link
Author

Try to remove preceding slash (replace '/server' with 'server').

@farhoudi
Copy link
Author

One more thing. Your route method for soap server request needs to be defined as 'post' method.

@devexsolutions
Copy link

Sorry @AliFarhoudi i beginner Laravel user

this my SoapController code

class SoapController extends Controller {

public function __construct() {
//    parent::__construct();
    ini_set('soap.wsdl_cache_enabled', 0);
    ini_set('soap.wsdl_cache_ttl', 0);
    ini_set('default_socket_timeout', 300);
    ini_set('max_execution_time', 0);
}

public function server() {
    $location = url('server'); // http://payment.dev/server
    $namespace = $location;
    $class = "\\MyProject\\Http\\Controllers\\HelloWorldController";

    $wsdl = new \WSDL\WSDLCreator($class, $location);
    $wsdl->setNamespace($namespace);

    if (isset($_GET['wsdl'])) {
        $wsdl->renderWSDL();
        exit;
    }

    $wsdl->renderWSDLService();

    $wsdlUrl = url('wsdl/server.wsdl');
    $server = new \SoapServer(
        url('server?wsdl'),
        array(
            'exceptions' => 1,
            'trace' => 1,
        )
    );

    $server->setClass($class);
    $server->handle();
    exit;
}

public function client() {
    $wsdl = url('server?wsdl');
    $client = new \SoapClient($wsdl);

    try {
        $res = $client->hello('world');
        dd($res);
    } catch (\Exception $ex) {
        dd($ex);
    }
}

Routes.php

Route::any('/client', 'SoapController@client');
Route::any('/server', 'SoapController@server');
Route::post('/server', function()
{
//
});

@devexsolutions
Copy link

My Wsdl file

<?xml version="1.0" encoding="UTF-8"?> <definitions name="HelloWorld" targetNamespace="http://localhost/myproject/public/server/giant/http/controllers/helloworld" xmlns:tns="http://localhost/myproject/public/server/giant/http/controllers/helloworld" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://localhost/myproject/public//server/giant/http/controllers/helloworld/types"> <types> <xsd:schema targetNamespace="http://localhost/myproject/public//server/giant/http/controllers/helloworld/types" xmlns="http://localhost/myproject/public//server/giant/http/controllers/helloworld/types"/> </types> <message name="helloRequest"> <part name="name" type="xsd:string"/> </message> <message name="helloResponse"> <part name="helloMessage" type="xsd:string"/> </message> <portType name="HelloWorldPortType"> <operation name="hello"> <documentation>Hello Web-Service</documentation> <input message="tns:helloRequest"/> <output message="tns:helloResponse"/> </operation> </portType> <binding name="HelloWorldBinding" type="tns:HelloWorldPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="hello"> <soap:operation soapAction="http://localhost/myproject/public/server/myproject/http/controllers/helloworld/#hello"/> <input> <soap:body use="literal" namespace="http://localhost/myproject/public/server/myproject/http/controllers/helloworld"/> </input> <output> <soap:body use="literal" namespace="http://localhost/myproject/public/server/myproject/http/controllers/helloworld"/> </output> </operation> </binding> <service name="HelloWorldService"> <port name="HelloWorldPort" binding="tns:HelloWorldBinding"> <soap:address location="http://localhost/myproject/public/server"/> </port> </service> </definitions>

@devexsolutions
Copy link

@AliFarhoudi I solved the problem.
The bug, is a file call Class extended from VerifyCsrfToken.php. I called directly VerifyCsrfToken in Kernel.php
screencapture-localhost-gestor_rse-public-server-1466597428043

Not show the variable name!!!

Thanks.

@devexsolutions
Copy link

Hi:
My client method not correctly read the wsdl file

public function client() {
$wsdl = url('server?wsdl');

    $client = new \SoapClient($wsdl);
    dd($client);
    try {
        $res = $client->hello('world');
        dd($res);
    } catch (\Exception $ex) {
        dd($ex);
    }
}

I used dd($client) for trace and show this:

SoapClient {#166
+"_soap_version": 1
+"sdl": Unknown resource @199
}

Can you help me?

Thanks.

@farhoudi
Copy link
Author

Hi. try to disable wsdl cache before creating soap client object.

@devexsolutions
Copy link

Im try
ini_set('soap.wsdl_cache_enabled', '0');

Dont run

@devexsolutions
Copy link

This XML file does not appear to have any style information associated with it. The document tree is shown below. <definitions xmlns:tns="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller/types" name="HelloWorldController" targetNamespace="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller"> <types> <xsd:schema xmlns="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller/types" targetNamespace="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller/types"/> </types> <message name="helloRequest"> <part name="name" type="xsd:string"/> </message> <message name="helloResponse"> <part name="helloMessage" type="xsd:string"/> </message> <portType name="HelloWorldControllerPortType"> <operation name="hello"> <documentation>Hello Web-Service</documentation> <input message="tns:helloRequest"/> <output message="tns:helloResponse"/> </operation> </portType> <binding name="HelloWorldControllerBinding" type="tns:HelloWorldControllerPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="hello"> <soap:operation soapAction="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller/#hello"/> <input> <soap:body use="literal" namespace="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller"/> </input> <output> <soap:body use="literal" namespace="http://localhost/gestor_rse/public/server/gestorrse/http/controllers/helloworldcontroller"/> </output> </operation> </binding> <service name="HelloWorldControllerService"> <port name="HelloWorldControllerPort" binding="tns:HelloWorldControllerBinding"> <soap:address location="http://localhost/gestor_rse/public/server"/> </port> </service> </definitions>

@devexsolutions
Copy link

The XML is incorrectly formatted

SoapFault in SoapController.php line 48:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/gestor_rse/public/wsdl/servidor.wsdl' : XML declaration allowed only at the start of the document

@farhoudi
Copy link
Author

This is my soap server code:
Check the differences with yours:

    public function __construct() {
        parent::__construct();
        ini_set('soap.wsdl_cache_enabled', 0);
        ini_set('soap.wsdl_cache_ttl', 0);
        ini_set('default_socket_timeout', 300);
        ini_set('max_execution_time', 0);
    }
    public function index() {
        $uri = url('services');
        $wsdl = new WSDLCreator('WebService', $uri);
        $wsdl->setNamespace($uri);
        if (isset($_GET['wsdl'])) {
            $wsdl->renderWSDL();
            exit;
        }
        $wsdl->renderWSDLService();
        $server = new \SoapServer(url('services?wsdl'), array(
            'uri' => $wsdl->getNamespaceWithSanitizedClass(),
            'location' => $wsdl->getLocation(),
            'style' => SOAP_RPC,
            'use' => SOAP_LITERAL
        ));
        $server->setClass('WebService');
        $server->handle();
    }

@devexsolutions
Copy link

WebService is you controller class?

@farhoudi
Copy link
Author

No, it is a class that my soap functions are inside it.

@devexsolutions
Copy link

hi @AliFarhoudi
can you paste the your wsdl file content. Pastebin dont work.

Thanks.

@devexsolutions
Copy link

Hi @AliFarhoudi .

I can not continue with the project I 'm developing , I am not able to create the web service SOAP laravel SERVER. Can you provide a complete example that works? Thank you very much.

@rhombusit
Copy link

rhombusit commented Apr 29, 2019

Hi @AliFarhoudi .

How to integrate wsdl-file creator in laravel?.
I got the error like Class 'Giant\Http\Controllers\Controller' not found
Can you please suggest me how to integrate with laravel ?
Thank you.

@farhoudi
Copy link
Author

@rhombusit The class Giant\Http\ was the namespace I was using for laravel 4. You do not need to use that class.
Have you tried https://github.com/piotrooo/wsdl-creator?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants