invokeWS Injecting \r\n Character Into SOAPAction Header

Issue #3 closed
Noah Betzen created an issue

I adapted the following code from the example given here as the web service from the example is no longer operational.

{-# LANGUAGE OverloadedStrings #-}

module Lib
    ( someFunc
    ) where

import           Control.Applicative
import           Data.Text (Text)
import qualified Data.Text as T

import           Network.SOAP (invokeWS, Transport, ResponseParser(CursorParser))
import           Network.SOAP.Transport.HTTP (initTransportWithM)
import           Network.HTTP.Client (defaultManagerSettings)
import           Network.SOAP.Parsing.Cursor (Dict, dictBy, readT, readC)
import           Text.XML (Name)
import           Text.XML.Cursor hiding (element)
import           Text.XML.Writer (elementA, element)

someFunc :: IO ()
someFunc = do
    transport <- initTransportWithM defaultManagerSettings "http://www.webservicex.net/currencyconvertor.asmx" pure pure
    response <- getConversionRate transport (T.pack "USD") (T.pack "NOK")
    print response

getConversionRate :: Transport -> Text -> Text -> IO Dict
getConversionRate t c1 c2 = invokeWS t url () body parser
  where
    url = "http://www.webservicex.net/ConversionRate"
    body = element "web:ConversionRate" $ do
           element "web:FromCurrency" c1
           element "web:ToCurrency" c2

    parser = dictBy "ConversionRateResponse"

When running the service gives back an error:

soap-test-exe: SOAPFault {faultCode = "soap:Client", faultString = "System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://www.webservicex.net/ConversionRate.\r\n at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()\r\n at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)\r\n at System.Web.Services.Protocols.SoapServerProtocol.Initialize()\r\n at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)", faultDetail = ""}

Using Wireshark to verify what data is actually being sent, there are \r\n characters being injected. They're being injected in the entire request, so apparently HTTP doesn't care. But the SOAPAction header seems to care.

soapactionurl.PNG

Comments (12)

  1. dp wiz repo owner

    I see there are quotes in the example on the service site:

    SOAPAction: "http://www.webserviceX.NET/ConversionRate"
    

    Please try wrapping that into a level of quotes too e.g. using show on the url.

  2. Noah Betzen reporter

    I assume you mean this? url = show "http://www.webservicex.net/ConversionRate"

    I tried both that and: url = "\"http://www.webservicex.net/ConversionRate\""

    Both had the same result.

    Also I verified the SOAP service with SoapUI:

    haskellxmlsoapui.PNG

  3. Noah Betzen reporter

    SOAP UI:

    soapuiwireshark.PNG

    With the escaped quotes in the Haskell code:

    haskellwireshark.PNG

    I feel silly for not verifying that SOAP UI does the \r\n thing too. My apologies. So something still isn't working, but it could be my implementation of this example. Though I'm not sure what. This issue can probably be closed.

  4. dp wiz repo owner

    Well, the exact URLs are a bit different. The one from SoapUI has some extra upper case chars in there.

  5. Noah Betzen reporter

    ... TIL SOAP is very case sensitive. I noticed the capitalization but assumed (like a fool) that it didn't matter. That fixed it. Thank you.

  6. Log in to comment