I am exploring the possible options of accesssing a REST API via OpenEdge ChUI client. My progress version is 11.7.4 and after going through progress tutorials I opted to use OpenEdge Http client (OpenEdge.Net.pl).
USING OpenEdge.Net.HTTP.IHttpRequest. USING OpenEdge.Net.HTTP.IHttpResponse. USING OpenEdge.Net.HTTP.ClientBuilder. USING OpenEdge.Net.HTTP.RequestBuilder. DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO. DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO. oRequest = RequestBuilder:Get('www.progress.com/'):Request. oResponse = ClientBuilder:Build():Client:Execute(oRequest). MESSAGE oResponse:StatusCode SKIP oResponse:StatusReason SKIP VIEW-AS ALERT-BOX.
But I am getting below error if I execute from Procedure Editor.
Secure Socket Layer (SSL) failure. error code -3829: SSL routines (9318) Connection failure for host www.progress.com port 443 transport TCP. (9407)
response-data-received.txt created was blank.
Then instead (of https://www.progress.com/) I used another API (http://api.worldbank.org/countries?format=json) which will return a json data. (Through broswer I have confirmed it.) But through OE Client it gave oResponse:StatusCode as 403 and oResponse:StatusMessage as "Forbidden".
This time response-data-received.txt was created with below content.
HTTP/1.1 403 Forbidden Server: squid/3.5.20 Mime-Version: 1.0 Date: Tue, 03 Sep 2019 11:38:22 GMT Content-Type: text/html;charset=utf-8 Content-Length: 3655 X-Squid-Error: ERR_ACCESS_DENIED 0 Vary: Accept-Language Content-Language: en X-Cache: MISS from cppra00a0288.erferf.com X-Cache-Lookup: NONE from cppra00a0288.erferf.com:0 Via: 1.1 cppra00a0288.erferf.com (squid/3.5.20) Connection: keep-alive <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "www.w3.org/.../strict.dtd"> <html><head> <meta type="copyright" content="Copyright (C) 1996-2016 The Squid Software Foundation and contributors"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: The requested URL could not be retrieved</title> <style type="text/css"><!-- /* * Copyright (C) 1996-2016 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ /* Stylesheet for Squid Error pages Adapted from design by Free CSS Templates www.freecsstemplates.org Released for free under a Creative Commons Attribution 2.5 License */ /* Page basics */ * { font-family: verdana, sans-serif; } html body { margin: 0; padding: 0; background: #efefef; font-size: 12px; color: #1e1e1e; } /* Page displayed title area */ #titles { margin-left: 15px; padding: 10px; padding-left: 100px; background: url('/squid-internal-static/icons/SN.png') no-repeat left; } /* initial title */ #titles h1 { color: #000000; } #titles h2 { color: #000000; } /* special event: FTP success page titles */ #titles ftpsuccess { background-color:#00ff00; width:100%; } /* Page displayed body content area */ #content { padding: 10px; background: #ffffff; } /* General text */ p { } /* error brief description */ #error p { } /* some data which may have caused the problem */ #data { } /* the error message received from the system or other software */ #sysmsg { } pre { font-family:sans-serif; } /* special event: FTP / Gopher directory listing */ #dirmsg { font-family: courier; color: black; font-size: 10pt; } #dirlisting { margin-left: 2%; margin-right: 2%; } #dirlisting tr.entry td.icon,td.filename,td.size,td.date { border-bottom: groove; } #dirlisting td.size { width: 50px; text-align: right; padding-right: 5px; } /* horizontal lines */ hr { margin: 0; } /* page displayed footer area */ #footer { font-size: 9px; padding-left: 10px; } body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; } --></style> </head><body id=ERR_ACCESS_DENIED> <div id="titles"> <h1>ERROR</h1> <h2>The requested URL could not be retrieved</h2> </div> <hr> <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="api.worldbank.org/countries <blockquote id="error"> <p><b>Access Denied.</b></p> </blockquote> <p>Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect.</p> <p>Your cache administrator is <a href="mailto:root?subject=CacheErrorInfo%20-%20ERR_ACCESS_DENIED&body=CacheHost%3A%20cppra00a0288.erferf.com%0D%0AErrPage%3A%20ERR_ACCESS_DENIED%0D%0AErr%3A%20%5Bnone%5D%0D%0ATimeStamp%3A%20Tue,%2003%20Sep%202019%2011%3A38%3A22%20GMT%0D%0A%0D%0AClientIP%3A%2010.86.128.240%0D%0A%0D%0AHTTP%20Request%3A%0D%0AGET%20%2Fcountries%3Fformat%3Djson%20HTTP%2F1.1%0AUser-Agent%3A%20OpenEdge-HttpClient%2F0.4.0%20(WIN32%2F64)%20OpenEdge%2F11.7.0.0.1388%20Lib-ABLSockets%2F0.4.0%0D%0AAccept%3A%20*%2F*%0D%0AHost%3A%20api.worldbank.org%0D%0A%0D%0A%0D%0A">root</a>.</p> <br> </div> <hr> <div id="footer"> <p>Generated Tue, 03 Sep 2019 11:38:22 GMT by cppra00a0288.erferf.com (squid/3.5.20)</p> <!-- ERR_ACCESS_DENIED --> </div> </body></html>
Can someone help me to identify the issue here? Is it because calling a http data from SSL client?
Running on OE 12.0 I get:
Error(s):
Lead attributes in a chained-attribute expression (a:b:c) must be type HANDLE or a user-defined type and valid (not UNKNOWN). (10068)
Unable to parse malformed URI: www.progress.com/
Changing line to:
oRequest = RequestBuilder:Get('https://www.progress.com/'):Request.
Gives: 200 OK
When you start with SSL you need to exchange and load the proper certificates in the client environment.
Other question: on the server are you using an PASOE instance or a Classic AppServer?
As Peter notes, you have to load all of the TLS/SSL certificates into the OE cert store, using the certutil command. Make sure that you have all of them (the whole chain) , including the root CA. It's not enough to have them on the OS - they must be in the OE-version-specific certstore.
I use my browser to get the certs (most browsers have the ability to download/export them).
The "unable to parse malformed URI" error is because there's no schema on the URI (ie no 'http' or 'https').
Thanks Torben. This seems a formatting issue in site. When I copied it was just like what you mentionied here. Mostly the formatting stepped over this. My program looks exactly like your quoted piece of code.
After importing certificates I get the following code to give desired result.
Think they are behind load balancer, so you need the ServerNameIndicator
BLOCK-LEVEL ON ERROR UNDO, THROW. USING OpenEdge.Core.*. USING OpenEdge.Net.HTTP.ClientBuilder. USING OpenEdge.Net.HTTP.IHttpRequest. USING OpenEdge.Net.HTTP.IHttpResponse. USING OpenEdge.Net.HTTP.RequestBuilder. USING OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder. DEFINE VARIABLE jOut AS Progress.Json.ObjectModel.JsonArray NO-UNDO. FUNCTION InvokeworldBank RETURNS Progress.Json.ObjectModel.JsonArray (): DEFINE VARIABLE oHttpRequest AS IHttpRequest NO-UNDO. DEFINE VARIABLE oHttpResponse AS IHttpResponse NO-UNDO. DEFINE VARIABLE oUri AS OpenEdge.Net.URI NO-UNDO. DEFINE VARIABLE oLib AS OpenEdge.Net.HTTP.IHttpClientLibrary NO-UNDO. // Set server to call oUri = (NEW OpenEdge.Net.URI('https', 'api.worldbank.org')). oUri:Path = '/countries'. oUri:addQuery("format", "json":U). // Set ssl properties oLib = OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder:Build() // :SslVerifyHost(FALSE) :ServerNameIndicator('api.worldbank.org') :library. oHttpRequest = OpenEdge.Net.HTTP.RequestBuilder:Get(oUri):Request. // Call and get response oHttpResponse = ClientBuilder:Build() :UsingLibrary(oLib) :Client:Execute(oHttpRequest). MESSAGE oHttpResponse:StatusCode SKIP oHttpResponse:StatusReason VIEW-AS ALERT-BOX INFORMATION. IF TYPE-OF(oHttpResponse:Entity, Progress.Json.ObjectModel.JsonArray) THEN RETURN CAST(oHttpResponse:Entity, Progress.Json.ObjectModel.JsonArray). UNDO, THROW NEW Progress.Lang.AppError("Wrong response type", 0). END FUNCTION. // Call worldBank with input parameters jOut = InvokeworldBank(). // Message 200 first chars of result MESSAGE STRING(SUBSTRING(jOut:GetJsonText(), 1, 200)) VIEW-AS ALERT-BOX INFORMATION.
[{"page":1,"pages":7,"per_page":"50","total":304},[{"id":"ABW","iso2Code":"AW","name":"Aruba","region":{"id":"LCN","value":"Latin America & Caribbean "},"adminregion":{"id":"","value":""},"incomeLevel
Hi Peter,
Is this certificate specific to a particular API url? I am confused beacuse in my browser(chrome) I can see only one entry under certificates. When I try to export that one, the options "Export with Private Key" & "Include all certificates in certification path" are disabled and unselected. So I am not sure if this is a show-stopper for me !!. Still I was able to export certificate file.
I tried to add the above certificate into my OE developer studio but client still gave the same "Forbidden" error.
Ideally when we consume a REST API, should we need to request & get for a certificate from them?
I am currently executing it from developer studio and also tried it with PASOE instance. I don't have AppServer in my application.
Hi Torben,
Could you help me to understand the steps to import those licences? <sorry if that was a very basic queston>
Also, when I used your code block in my OE studio it is not able to find "ServerNameIndicator" and causing syntax error. Probably that would be a newly introduced method in 12.0. (Mine is 11.7)
Hi Anil Kumar,
Thanks for the step by step detailed explanation. I tried to create an .crt file from chrome but strangely it had an extension of .cer instead. When I tried to install that file using proenv, it gave an error that "The file C:\xx\xx\\worldBank.cer does not contain a Digital Certificate". I guess, I need to retry it in Mozilla. I will update you soon how it goes.
On certutil you can add the -format DER to import binary formatted certificates.
You need 11.7.3 or later for SNI support.