George Hodder · Jul 17, 2017

Connecting to a web service


I am new to coding web services and trying to connect to an API that returns its format in xml or json.

I have a class as follows.. when I run I get back a 6059 in my status - Unable to open TCP/IP socket to server

Can someone help me identify what I am missing?  Thanks

Class Common.WebDownload Extends (%RegisteredObject, %XML.Adaptor)

ClassMethod Connect()
  Set aa=##class(%Net.HttpRequest).%New()
  Set aa.Server=""
  Set aa.Location="/service/actual location path and my API key here/"
  Set aa.ContentType="text/xml"
  set bb=aa.Get()

Method Get(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) As %Status
0 2,228
Discussion (12)5
Log in or sign up to continue

That would send request to the remote server using http. To use https, try adding:

Set aa.Https = $$$YES
Set aa.SSLConfiguration = "NameOfSSLConfiguration"

You'll also need client SSL Configuration, here's documentation.

ok.. I built a configuration, but how do I determine what the server requires.. is there anything in my 301 message that helps me determine that?

301 is "Moved permanently".  Try setting

Set aa.FollowRedirect = $$$YES

wow.. great that worked.. Thanks Ed... but now the next newbie question.  

If I understand from looking at the dump of the object, my results are in my aa.HttpResponse.Data as a stream.

How do I now work with the stream?

set stream = aa.HttpResponse.Data
while 'stream.AtEnd {
    write stream.Read($$$MaxStringLength)

Read argument is the number of charachers to read from the list. 32000 by default.

I think this all hasn't been working because I get back a 301 message saying to use the https:// location (and if you look above having trouble connecting there)


But related to the return.. my current GET() method is empty, does it need formatted to receive what I am expecting back?

HTTP Status 301 means Moved Permanently, which happens when you request a resource and the server redirects you to another (usually equivalent), since you said it's asking to use HTTPS, I suppose you haven't configured a SSL configuration on the Caché side.

Create a new SSL Configuration mark Enabled, select Type to Client, Peer certificate verification level to None, and Protocols to TLS.

Or simply fill the Name and Description, anything else is default... click Test to see if it works and Save it.

Now after instantiating the %Net.HttpRequest, you pass your instance.SSLConfiguration = "Your SSL Configuration Name" and instance.Https = 1.

This is the minimal you usually need to do to have a working SSL aware client.

Thanks Rubens... I have tried that and even in just testing the config I get the error 

ERROR #989: SSL connection failed, make sure server address and port (not url) is specified

I changed the Protocols from TLS to SSL and get the same... I have tried to port 80 and port 443.

I have an email into the site too to see if they can assist.

For server address I am just putting

that is the actual address... didn't want to put it out there and kill them with traffic, it is a small service... but this may help solve I would think if you have the actual address.

If you mean testing using the SSL configuration in the Portal, when you click Test, it asks you for your server name and port. This follows the same pattern as %Net.HttpRequest, which means: don't provide the protocol http:// or https://, only your address:

For a use case, we have service hosted on AWS using HTTPS and it connects succesfully, but only if I strip the protocol from the address. Here's a feedback from our service when using the Test button (it's portuguese though ...)

Conexão SSL bem sucedida <- Indicates success on connecting.
Protocolo: TLSv1/SSLv3
Peer:  <- No peer certification defined, so it's empty...
Requisição: GET / HTTP/1.0 <- Request done using HTTP 1.0 protocol 
Resposta: <- Response is an empty body.

Portuguese or not.. that worked for me too :)

Thank you a bunch, I had the https://www.  in the servername which was probbly a big part of my problem.

Now on to parsing the stream into usable data!