Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello everybody, I'va a cgi soap web server and I've a problem for returning special chars.

With this script, there is no problem :

#!/usr/bin/perl -w use CGI::Carp 'fatalsToBrowser'; my $soap_transport = SOAP::Transport::HTTP::CGI->dispatch_to('my_serve +r'); $soap_transport->serializer->encoding('UTF-8'); $soap_transport->handle(); =begin WSDL _RETURN $string _DOC fonction de test du web service =cut sub test { my $response = "xxx"; return $response; }

response is :

<soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-enco +ding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap +enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w +3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins +tance"> <soap:Body> <testResponse xmlns="https://my_server_url"> <s-gensym3 xsi:type="xsd:string">xxx</s-gensym3> </testResponse> </soap:Body> </soap:Envelope>

but when I try to return special chars :

=begin WSDL _RETURN $string _DOC fonction de test du web service =cut sub test { my $response = "ייי"; return $response; }

response is :

<soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-enco +ding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap +enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w +3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins +tance"> <soap:Body> <testResponse xmlns="https://my_server_url"> <s-gensym3 xsi:type="xsd:base64Binary">w6nDqcOp</s-gensym3> </testResponse> </soap:Body> </soap:Envelope>

We can see that the string type is now base64Binary

If I try to encode string in utf8, the problem persists :

#!/usr/bin/perl -w use CGI::Carp 'fatalsToBrowser'; use utf8; my $soap_transport = SOAP::Transport::HTTP::CGI->dispatch_to('saint_kr +o'); $soap_transport->serializer->encoding('UTF-8'); $soap_transport->handle(); =begin WSDL _RETURN $string _DOC fonction de test du web service =cut sub test { my $response = "ייי"; utf8::encode($response); return $response; }

response is still :

<soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-enco +ding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap +enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w +3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins +tance"> <soap:Body> <testResponse xmlns="https://my_server_url"> <s-gensym3 xsi:type="xsd:base64Binary">w6nDqcOp</s-gensym3> </testResponse> </soap:Body> </soap:Envelope>

Can someone tell me what is the solution for encode response to keep string type and prevent base64 conversion ?

Thanks

Replies are listed 'Best First'.
Re: Encoding problem on SOAP web server
by Anonymous Monk on Jan 12, 2016 at 14:44 UTC

    I've found something that works. Not perfect but it works :

    #!/usr/bin/perl -w use CGI::Carp 'fatalsToBrowser'; use utf8; *SOAP::Serializer::as_base64Binary = \&SOAP::XMLSchema2001::Serializer +::as_string; my $soap_transport = SOAP::Transport::HTTP::CGI->dispatch_to('my_serve +r'); $soap_transport->serializer->encoding('UTF-8'); $soap_transport->handle(); =begin WSDL _RETURN $string _DOC fonction de test du web service =cut sub test { my $response = "ייי"; return $response; }

    Response is :

    <soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-enco +ding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap +enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w +3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins +tance"> <soap:Body> <testResponse xmlns="https://my_server_url"> <s-gensym3 xsi:type="xsd:string">ייי</s-gensym3> </testResponse> </soap:Body> </soap:Envelope>

    But if someone has better to offer me I am interested !

    Thanks

Re: Encoding problem on SOAP web server
by hotchiwawa (Scribe) on Jan 12, 2016 at 11:07 UTC
    Hello :)

    This is not the solution at your problem but your test is wrong, you said:
    sub test { my $response = "ייי"; utf8::encode($response); return $response; }
    should be:
    $response = utf8::encode($response);

      I think you are wrong.

      utf8::encode($string) modifies in-place passed var and return nothing.

      http://perldoc.perl.org/utf8.html :

      utf8::encode($string) Converts in-place the character sequence to the corresponding octet sequence in UTF-X. That is, every (possibly wide) character gets replaced with a sequence of one or more characters that represent the individual UTF-X bytes of the character. The UTF8 flag is turned off. Returns nothing.

        Yep right, strange (if we compare with other convertion functions) but if we go deeper, the input parameter should be a reference and here $response is a value ("ייי"), or maybe I don't understand something! Can you explain that?!

        Edit (explanation)
        Thanks to choroba.
        Found in perlsub: http://perldoc.perl.org/perlsub.html

        if you called a function with two arguments, those would be stored in $_[0] and $_1 . The array @_ is a local array, but its elements are aliases for the actual scalar parameters. In particular, if an element $_[0] is updated, the corresponding argument is updated (or an error occurs if it is not updatable).
Re: Encoding problem on SOAP web server
by 1nickt (Canon) on Jan 12, 2016 at 14:39 UTC
    Edit: never mind, noticed the use utf8; in the lower example.

    In the code you've shown, you don't tell Perl that the source contains characters already in UTF-8. I don't know if that's the cause of your problem with the SOAP serializer's encoding, but it could be. You should always give Perl a clue and point out that your source code is (partially) UTF-8 "high" characters, when you use them in the source code, with:

    use utf8;
    From the docs for utf8:

    The use utf8 pragma tells the Perl parser to allow UTF-8 in the program text in the current lexical scope ...

    Because it is not possible to reliably tell UTF-8 from native 8 bit encodings, you need either a Byte Order Mark at the beginning of your source code, or use utf8; , to instruct perl.


    The way forward always starts with a minimal test.
      Yep thanks