Hi,

So I checked that the web site will receive a ping, some don't for security purposes, and it seems ok:

ping www.intersystems.com

PING e9933.g.akamaiedge.net (104.103.202.60): 56 data bytes

64 bytes from 104.103.202.60: icmp_seq=0 ttl=56 time=80.280 ms

64 bytes from 104.103.202.60: icmp_seq=1 ttl=56 time=76.565 ms

64 bytes from 104.103.202.60: icmp_seq=2 ttl=56 time=53.358 ms

ping 104.103.202.60

PING 104.103.202.60 (104.103.202.60): 56 data bytes

64 bytes from 104.103.202.60: icmp_seq=0 ttl=56 time=17.981 ms

64 bytes from 104.103.202.60: icmp_seq=1 ttl=56 time=17.399 ms

64 bytes from 104.103.202.60: icmp_seq=2 ttl=56 time=86.598 ms

64 bytes from 104.103.202.60: icmp_seq=3 ttl=56 time=53.091 ms

64 bytes from 104.103.202.60: icmp_seq=4 ttl=56 time=54.445 ms

Try opening up a terminal on the Ensemble box and PING www.intersystems.com. If that works then we know that the network is ok.

Good Luck

Iain

Ok, so a couple of things to check:

1. When you say that you can connect from a browser but not from Ensemble, is the browser that you're using on the same computer as Ensemble?

2. Instead of a 'do httprequest.Get(...)' use 'set status=httprequest.Get(...)' and then inspect the value of 'status'. You can do 'do $system.OBJ.DisplayError(status)' in order to get a readable output. If the result is that you cannot open a TCP/IP socket then Ensemble cannot see the other computer. Otherwise the status should give you more information.

Are you addressing the other computer by its IP address or its DNS name? If you're using the DNS name then try using the IP address. If that works then edit your 'hosts' file to put the name and IP address in there and go back to using the DNS name to get to the other computer.

Let me know how you get on.

Iain

I'd probably do it something like this:

<html>
<head>
<title> Cache Server Page </title>

<script language='javascript'>
function SubmitForm(pid,sid) {
var elem document.getElementsByName("Studyform");
elem[0].submit;
//code to process form

alert ("study saved");
self.document.location="newpage.csp";
}

</script>
</head>

<body>
<form name="Studyform">
<input type="button" name="submit" value="submit" onclick="javascript:SubmitForm(#(SubjObj.%Id())#,#(StudyObj.%Id())#);">

</form>
</body>
</html>

or this, which is very similar apart from the use of 'id' rather than 'name'

<html>
<head>
<title> Cache Server Page </title>

<script language='javascript'>
function SubmitForm(pid,sid) {
var elem document.getElementById("Studyform");
elem.submit;
//code to process form

alert ("study saved");
self.document.location="newpage.csp";
}

</script>
</head>

<body>
<form id="Studyform">
<input type="button" name="submit" value="submit" onclick="javascript:SubmitForm(#(SubjObj.%Id())#,#(StudyObj.%Id())#);">

</form>
</body>
</html>

I have a working operation that uses the EnsLib.HTTP.OutboundAdapter.

The operation settings that I use are:

1. HTTP Server set to appropriate address

2. Credentials set to an entry in the Ensemble/Configure/Credentials where the username and password are set.

3. Connection Settings/SSL Configuration set to a very basic SSL/TLS Configuration. (This is in System Administrator/Security/SSL-TLS Configurations). By very basic what I mean is that it has a name and that is it. No other details or credentials or anything.

My code then looks like this:

Method GetId(objRequest As test.Message.RequestId, objResponse As test.Message.ResponseId) As %Status
{
set objResponse = ##class(test.Message.ResponseId).%New()
set objResponse.SubjectId = objRequest.SubjectId

set ..Adapter.URL = ..IdQueryURL // Property of the operation, setup in the configuration page
set status = ..Adapter.Get(.HttpResponse,"subjectId,subjectNamespace",objRequest.SubjectId,..IdNamespace)
if status {
     set objResponse.StatusCode = HttpResponse.StatusCode
     if HttpResponse.StatusCode = 200 {
          do HttpResponse.Data.Rewind()
          set string = HttpResponse.Data.Read()
          set objDyn = ##class(%DynamicAbstractObject).%FromJSON(string)
          set objItr = objDyn.%GetIterator()
          while objItr.%GetNext(.key,.value) {
               if key = "Id" set objResponse.Id = value quit
          }
     }
}
quit status
}

This will work. The second parameter of '2' indicates test mode and will write out the response to the current device

set httprequest = ##class(%Net.HttpRequest).%New()
set httprequest.Server = "www.intersystems.com"
set status = httprequest.Get("/",2)

You should see something like this:

HTTP/1.1 301 Moved Permanently
CONNECTION: keep-alive
CONTENT-LENGTH: 178
CONTENT-TYPE: text/html
DATE: Thu, 02 Aug 2018 10:21:56 GMT
LOCATION: https://www.intersystems.com/
SERVER: nginx
X-TYPE: default
 
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>

Alternatively you can do this:

Setup an SSL/TLS Configuration. This is very simple and doesn't have any values apart from a name. Mine is called 'test'

Then use the following code:

set httprequest = ##class(%Net.HttpRequest).%New()
set httprequest.Server = "www.intersystems.com"
set httprequest.SSLConfiguration = "test"
set httprequest.Https = 1
set status = httprequest.Get("/")
if status {
     do httprequest.HttpResponse.Data.Rewind()
     do {
          write httprequest.HttpResponse.Data.Read()
     } while 'httprequest.HttpResponse.Data.AtEnd
}

Not sure if it will help but there are 2 examples below.

The first uses the  EnsLib.HTTP.OutboundAdapter to perform a GET on a REST service. This has had the credentials and the SSL configuration specified in the operation properties.

The second uses the %Net.HttpRequest to perform a POST to a REST service. This is more of a manual process.

Example #1:

set ..Adapter.URL = ..QueryURL
set status = ..Adapter.Get(.HttpResponse,"subjectId,subjectNamespace",objRequest.SubjectId,..Namespace)
if status {
     set objResponse.StatusCode = HttpResponse.StatusCode
     if HttpResponse.StatusCode = 200 {
          do HttpResponse.Data.Rewind()
          set string = HttpResponse.Data.Read()
          set objDyn = ##class(%DynamicAbstractObject).%FromJSON(string)
          set objItr = objDyn.%GetIterator()
          while objItr.%GetNext(.key,.value) {
               if key = "patId" set objResponse.PatId = value quit
          }
     }
}
quit status

Example #2

set objHttp = ##class(%Net.HttpRequest).%New()
set objHttp.Server = ..Server
set objHttp.Port = ..Port
set objHttp.Https = 1
set objHttp.SSLConfiguration = ..SSLConfiguration
set objCred = ##class(Ens.Config.Credentials).%OpenId(..Credentials)
set objHttp.Password = objCred.Password
set objHttp.Username = objCred.Username
set objHttp.WriteRawMode = 1
set objHttp.ContentType = "application/json"

do objHttp.SetHeader("Cache-Control","no-cache")

// Parameters. These are in the request message as an array of %String where the key in the array is the name of the parameter
set key = ""
for  {
     set data = pRequest.Headers.GetNext(.key)
     if key = "" quit
     if data '= "" do objHttp.SetParam(key,data)
}

// Form data. This is an array of stringsin the request message. Written directly to the entity body as name/value pairs in a JSON stream

set first = 1

do objHttp.EntityBody.Write("{")
for  {
     set data = pRequest.FormData.GetNext(.key)
     if key = "" quit
     if data '="" {

          if 'first do objHttp.EntityBody.Write(", ")

          do objHttp.EntityBody.Write(""""_key_"""")
          do objHttp.EntityBody.Write(": ")
          do objHttp.EntityBody.Write(""""_data_"""")
          set first = 0
     }
}

do objHttp.EntityBody.Write("}")
set status = objHttp.Post(..URL)
if status {
     set pResponse.StatusCode = objHttp.HttpResponse.StatusCode
     set pResponse.StatusLine = objHttp.HttpResponse.StatusLine
}

quit status