Tuesday, June 28, 2016

Design for the default

If the library doesn't work out of the box, there must be a problem with the library.

node-soap generates xmlns prefix (tns), but it doesn't apply it to SOAP's method:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:tns="http://v5.soap.platform.helloworld.com/">
    <soap:Body>
         <authenticate>
             <apiKey>meh</apiKey>
             <username>ryan</username>
             <password>dahl</password>
        </authenticate>
    </soap:Body>
</soap:Envelope>

This is the right XML, as tested in Google Chrome's Boomerang extension, there is tns prefix in SOAP's method (authenticate):
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:tns="http://v5.soap.platform.helloworld.com/">
    <soap:Body>
         <tns:authenticate>
             <apiKey>meh</apiKey>
             <username>ryan</username>
             <password>dahl</password>
        </tns:authenticate>
    </soap:Body>
</soap:Envelope>



To fix the node-soap's broken default, add this option on createClient method:

var options = {
    ignoredNamespaces: {
        namespaces: [],
        override: true
    }
}


soap.createClient ( url, options, function ( err, client ) {


Using that, node-soap will apply the tns prefix to the SOAP's method name.


.NET's generated SOAP works out of the box, notice that there is no prefix in SOAP call:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
        <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none" />
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <authenticate xmlns="http://v5.soap.platform.helloworld.com/">
            <apiKey xmlns="">meh</apiKey>
            <username xmlns="">ryan</username>
            <password xmlns="">dahl</password>
        </authenticate>
    </s:Body>
</s:Envelope>


Happy Coding!

Sunday, June 26, 2016

Make further proxy requests authenticated

app.get('/hoo/ray', (req,res,next) => {


    let url = "https://www.helloworld.com/ui/fragments/header.html";

    let cookie = request.cookie(req.headers["cookie"]);

    let headers = {cookie};

    request({url, headers}, (error, response, body) => {

        url = "https://www.helloworld.com/ui/fragments/toolbox.html";

        request({url, headers}, (toolboxError, toolboxResponse, toolboxBody) => {

            let html = body + toolboxBody;

            res.writeHead(200, {
                'Content-Type'  : 'text/html',
                'Content-Length': html.length,
                'Expires'       : new Date().toUTCString()
            });


            res.end(html);

        });

    });

});


Next step, convert those callback hell to promises.