Consuming a REST Web Service

Discussions related to HTTPAPI (An HTTP Client Package for RPG programming.) http://www.scottklement.com/httpapi/
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Consuming a REST Web Service

Post by sLucke1015 »

This will be my first experience accessing an API...

It is stipulated that the request be accompanied by a header that looks like this:
‘Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX’ where the repeating “X” is a hashed representative of the API User and Password.

I am now attempting to create an RPG program to send the request via HTTPAPI or SQL.


I have been able to create the necessary authentication string above and using Insomnia send a GET request and receive a valid response using NO AUTH and the above header

The website is https://...

The request is for all documents.

For “Auth” I have checked “No Authentication”.

Instead, I have a Header with Key = “Authorization”, and “Value = Basic “ concatenated with the long string we put together before using the apiKey and apiPin.

The test response should a JSON table with four records with five fields each. Of course when this goes live the responses will vary.

Thank you for any help!
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Consuming a REST Web Service

Post by Scott Klement »

HTTPAPI can create it for you. Just do this before making the request:

Code: Select all

http_setAuth(HTTP_AUTH_BASIC: 'userid here': 'password here');
HTTPAPI will calculate the value and send it as an authorization basic header -- according to the rules for basic. (FWIW, the string it uses isn't actually hashed -- it is just base64-encoded -- that's how basic auth works.)

If it's important to create your own, you can do that too -- but it really shouldnt be necessary for something this simple.
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Re: Consuming a REST Web Service

Post by sLucke1015 »

HI Scott,

I'm sorry in the initial post I said "User" and Password" when I should have said "APIKEY" and "APIPIN".
I don't know if that makes a difference or not but I have made some progress in that I seem to be getting in to the API server but am not getting what I expect to get.

Thank you very much for your time,
Scott


I also neglected to say that we were given this documentation regarding how to get in:

Security Documentation

All api calls require and apikey and an api hash.

Each affiliate will be assigned a unique apikey and api pin for each county.

The api hash will be build by hashing a random seed value. The concept is outlined below.
Please note this code is just conceptual and not actual implementation.

var seed = generateRandomValue();
var prehash = apikey + seed + apipin;
var apihash = 's2/'+ seed + '/' + encodeHex(sha256(prehash));
var authKey = base64Encode(apikey + ':' + apihash);

Authentication will be included as a basic auth http header with each call.

It will be sent as a base64 encoded representation of the following: apiKey:apiHash

Sample Request
--header 'Authorization: Basic X1JkelZxNEN3NlRRSnk2WDNGZzQ1bjUyU0k3OE03ZGU6czIvWGY3VUk4NDAzNGtodnBLYi84YjZhNGRkOTNlN2M2ZTg1Y2ZlMjE0MGRiNzJlNDQzYjI0YjgyN2QwMDY2OWQ0NTI2YTZkZjcwNzU0OWE5M2Fl'



Below is the code that I have been using and below that are the results that I am expecting to receive.

http_debug(*ON);
url = 'https://staging.iowalandrecords.org/esu ... /api/read-
yForDownload';

authorizationToken = 'Basic ' + hashedAPIkey();

http_xproc( HTTP_POINT_ADDL_HEADER
: %paddr(addSpecialHeaders)
: %addr(authorizationToken) );

monitor;
httpResponse = HTTP_req( 'GET' : url : *omit : resultString );

Data-Into docsReady
%data( resultString : 'case=any countPrefix=num_ allowExtra=yes' )
%parser( 'YAJL/YAJLINTO' );

result = *ON;

on-error;
result = *OFF;
endMON;

dump;

https_cleanup();

*inlr = *ON;
return;


Desired results

[
{
"groupID": 86559,
"groupName": "HUMBOLDT GROUP 2",
"recorderApprovedDate": "2019-05-21 19:40:50.471",
"sequence": 1,
"priaDocObjectID": 100470
},
{
"groupID": 86559,
"groupName": "HUMBOLDT GROUP 2",
"recorderApprovedDate": "2019-05-21 19:40:50.471",
"sequence": 2,
"priaDocObjectID": 100469
},
{
"groupID": 86559,
"groupName": "HUMBOLDT GROUP 2",
"recorderApprovedDate": "2019-05-21 19:40:50.471",
"sequence": 3,
"priaDocObjectID": 100468
},
{
"groupID": 86559,
"groupName": "HUMBOLDT GROUP 2",
"recorderApprovedDate": "2019-05-21 19:40:50.471",
"sequence": 4,
"priaDocObjectID": 100471
}
]



httpapi_debug.txt


HTTPAPI Ver 1.45 released 2021-09-20
NTLM Ver 1.4.0 released 2014-12-22
OS/400 Ver V7R3M0

New iconv() objects set, PostRem=819. PostLoc=0. ProtRem=819. ProtLoc=0
http_persist_open(): entered
http_long_ParseURL(): entered
DNS resolver retrans: 2
DNS resolver retry : 2
DNS resolver options: x'00000136'
DNS default domain: GMDSOLUTIONS.LOCAL
DNS server found: 10.100.101.5
DNS server found: 10.100.101.6
DNS server found: 8.8.8.8
https_init(): entered
QSSLPCL = *TLSV1.2 *TLSV1.1 *TLSV1 *SSLV3
SSL version 2 support disabled
SSL version 3 support disabled
Old interface to TLS version 1.0 support enabled
TLS version 1.0 support enabled
TLS version 1.1 support enabled
TLS version 1.2 support enabled
TLS version 1.3 support enabled
initializing GSK environment
GSK Environment now available
-------------------------------------------------------------------------------------
Dump of local-side certificate information:
-------------------------------------------------------------------------------------
Nagle's algorithm (TCP_NODELAY) disabled.
SNI hostname set to: staging.iowalandrecords.org
-------------------------------------------------------------------------------------
Dump of server-side certificate information:
-------------------------------------------------------------------------------------
Cert Validation Code = 6000
-----BEGIN CERTIFICATE-----
MIIHmjCCBoKgAwIBAgIQBtDTi/Ch5qEQnOtVNoQZcDANBgkqhkiG9w0BAQsFADB1
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTIzMDEzMTAwMDAwMFoXDTI0MDMwMjIz
NTk1OVowggEBMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRUwEwYLKwYBBAGCNzwCAQIT
BElvd2ExITAfBgsrBgEEAYI3PAIBARMQQXBwYW5vb3NlIENvdW50eTEaMBgGA1UE
DwwRR292ZXJubWVudCBFbnRpdHkxGjAYBgNVBAUTEUdvdmVybm1lbnQgRW50aXR5
MQswCQYDVQQGEwJVUzENMAsGA1UECBMESW93YTERMA8GA1UEBxMISm9obnN0b24x
IzAhBgNVBAoTGkVsZWN0cm9uaWMgU2VydmljZXMgU3lzdGVtMSQwIgYDVQQDExtz
dGFnaW5nLmlvd2FsYW5kcmVjb3Jkcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDDSQ+BH+e6tquCyP3TeqH1dytOgAHlYGA3+yZxjOv4V7u9onQL
ASMXi9CzqVys5OQg8Ccg3reu+7b9LB8T3GG7CXuLbt4s4YElsgXWgrGSpawJfaJX
DMx4+/fdNFGhY4puOaqq3uPXwMO0aeTO1SBocuObtcgKiyg4qHIHX1UA0+whgdxK
6h3ch8mxOgX1qNJj8DuogVA+zr434OceVpM4bsR6UitkpdP8zJ4bFZfkfXZEnDvv
BwbumFGtgFmkyHaG8u0j/rn0VS5sXnVS+pEGs1tYjMUpF3W229YGHMkkhQm8UU3Z
OgXK/R9Pz7V00V0mQYsY1sF8+j/G/yz+bG1JAgMBAAGjggOWMIIDkjAfBgNVHSME
GDAWgBQ901Cl1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQU/ALiOLa16jGKjBYE
N9klK4W0dNgwRwYDVR0RBEAwPoIbc3RhZ2luZy5pb3dhbGFuZHJlY29yZHMub3Jn
gh93d3cuc3RhZ2luZy5pb3dhbGFuZHJlY29yZHMub3JnMA4GA1UdDwEB/wQEAwIF
oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKg
MIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWczLmNy
bDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVy
LWczLmNybDBKBgNVHSAEQzBBMAsGCWCGSAGG/WwCATAyBgVngQwBATApMCcGCCsG
AQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYgGCCsGAQUFBwEB
BHwwejAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsG
AQUFBzAChkZodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEy
RXh0ZW5kZWRWYWxpZGF0aW9uU2VydmVyQ0EuY3J0MAkGA1UdEwQCMAAwggF9Bgor
BgEEAdZ5AgQCBIIBbQSCAWkBZwB2AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8vOzew1FI
WUZxH7WbAAABhgkLDcsAAAQDAEcwRQIgUvLha0TUYyaiIifp7qXPUPnM90M3SV+9
hkkwAAwN6mkCIQDlX0vABEbVe5spsCQNWd09MnuieEWO5YHylo8L2BtM/AB2AHPZ
nokbTJZ4oCB9R53mssYc0FFecRkqjGuAEHrBd3K1AAABhgkLDdYAAAQDAEcwRQIg
Aa7f5xNxEbqy7BxIrs7I6hjR+/mZjCKXaKATVv2rPLECIQDK5MWrbSXaM3l83O8W
J3TENGMVwfbvkXfVPLWv1LoJDAB1AEiw42vapkc0D+VqAvqdMOscUgHLVt0sgdm7
v6s52IRzAAABhgkLDacAAAQDAEYwRAIgVAcHVlKoK1ssSxGZuLqIA5bNsyXz1/t/
yko8ghl/Y0oCIH87ZSL3pKK2paK/NogpflU1+jcTzYQAlHcWsFM3yFTxMA0GCSqG
SIb3DQEBCwUAA4IBAQAKPB3RlAnorGEIeS8xLVVwo1g4D60wkRB4xjuFrzK2xS3/
qMxRo5Cchngylg0MXU/p/t6y+SvOFbasY1ox42a16RRAOXUxLRt7fiGi3nk6Z3/l
dCaXyRlckCknKl2lqgMhdQfbKkxhmijPd5KU+Zyl4shA39pqiPpdJIzrB/IaWZw4
xe0STX47HlxaOYA8HLFosgeXXzsyLrzWtr9wpowuj0gdPXoutqT9YL7bEUEqdtvy
91STF1yLCT9YieXxxomiekeJjKGX2Yabf4GmZ/s/UlMeGKfNgRN63I+Ig0yAKX8/
/JctYWO4PODoyhOYGxqCwo43mNtLX/PQAyR/Yv6Y
-----END CERTIFICATE-----
Serial Number: 06:D0:D3:8B:F0:A1:E6:A1:10:9C:EB:55:36:84:19:70
Common Name: staging.iowalandrecords.org
Country: US
State/Province: Iowa
Locality: Johnston
Org Unit: Electronic Services System
Issuer CN: DigiCert SHA2 Extended Validation Server CA
Issuer Country: US
Issuer Org: DigiCert Inc
Issuer Org Unit: www.digicert.com
Version: 3
not before: 20230130180000
Unknown Field: 18:00:00 30-01-2023
not after: 20240302175959
Unknown Field: 17:59:59 02-03-2024
pub key alg: 1.2.840.113549.1.1.1
signature algorithm: 1.2.840.113549.1.1.11
Unknown Field: 0382010F003082010A0282010100C3490F811FE7BAB6AB82C8FDD37AA1F5772B4E8001E5606037FB26718CEBF857BBBDA2740B0123178BD0B3A95CACE4E420F02720DEB7AEFBB6FD2C1F13DC61BB097B8B6EDE2CE18125B205D682B192A5AC097DA2570CCC78FBF7DD3451A1638A6E39AAAADEE3D7C0C3B469E4CED5206872E39BB5C80A8B2838A872075F5500D3EC2181DC4AEA1DDC87C9B13A05F5A8D263F03BA881503ECEBE37E0E71E5693386EC47A522B64A5D3FCCC9E1B1597E47D76449C3BEF0706EE9851AD8059A4C87686F2ED23FEB9F4552E6C5E7552FA9106B35B588CC5291775B6DBD6061CC9248509BC514DD93A05CAFD1F4FCFB574D15D26418B18D6C17CFA3FC6FF2CFE6C6D490203010001
Unknown Field: 2048
Unknown Field: BB6E45C8F07ABFEE36A2B571014DF81F
Unknown Field: 1.2.840.113549.2.5
Unknown Field: 8812F39CEA90589B8DB357AC33AA3FFA583CA30B
Unknown Field: 43E538FA65CDA4CBC9123C7CBD57BB0FB7A56D74ADF5A4B0C432408EE1E5B45A
Unknown Field: 5
Unknown Field: staging.iowalandrecords.org
Unknown Field: 0
Unknown Field: 1.3.6.1.5.5.7.3.2
Unknown Field: 1.3.6.1.5.5.7.3.1
Unknown Field: 2.23.140.1.1
Unknown Field: 2.16.840.1.114412.2.1
Unknown Field: http://ocsp.digicert.com

Protocol Used: TLS Version 1.2
http_persist_req(GET) entered.
http_long_ParseURL(): entered
http_long_ParseURL(): entered
do_oper(GET): entered
There are 0 cookies in the cache
GET /esubmission/services/county/api/readyForDownload HTTP/1.1
Host: staging.iowalandrecords.org
User-Agent: http-api/1.45
authorization: Basic X2pZZUJWbjJOZTRwUzFKc2w5eDNROTQ0ZVlUYmViM2M6czIvTnpwVEVHaVBwV1lsLzBiZWRlZT
%

recvresp(): entered
HTTP/1.1 408 Request Timeout
Date: Fri, 10 Mar 2023 20:05:03 GMT
Server: Apache
Strict-Transport-Security: max-age=15768000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Content-Length: 221
Connection: close
Content-Type: text/html; charset=iso-8859-1


SetError() #13: HTTP/1.1 408 Request Timeout
recvresp(): end with 408
recvdoc parms: identity 221
header_load_cookies() entered
recvdoc(): entered
SetError() #0:
recvdoc(): Receiving 221 bytes.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>408 Request Timeout</title>
</head><body>
<h1>Request Timeout</h1>
<p>Server timeout waiting for the HTTP request from the client.</p>
</body></html>

SetError() #13: HTTP/1.1 408 Request Timeout
http_close(): entered


CONTINUED


I made an attempt to use your suggestion just now and here is what the code and log file look like"

CODE

http_debug(*ON);
url = 'https://staging.iowalandrecords.org/esu ... /api/read-
yForDownload';

http_setAuth(HTTP_AUTH_BASIC: apiKey: apiPin);

monitor;
httpResponse = HTTP_req( 'GET' : url : *omit : resultString );

Data-Into docsReady
%data( resultString : 'case=any countPrefix=num_ allowExtra=yes' )
%parser( 'YAJL/YAJLINTO' );

result = *ON;

on-error;
result = *OFF;
endMON;

https_cleanup();

*inlr = *ON;
return;


httpapi_debug.txt

HTTPAPI Ver 1.45 released 2021-09-20
NTLM Ver 1.4.0 released 2014-12-22
OS/400 Ver V7R3M0

New iconv() objects set, PostRem=819. PostLoc=0. ProtRem=819. ProtLoc=0
http_setauth(): entered
http_persist_open(): entered
http_long_ParseURL(): entered
DNS resolver retrans: 2
DNS resolver retry : 2
DNS resolver options: x'00000136'
DNS default domain: GMDSOLUTIONS.LOCAL
DNS server found: 10.100.101.5
DNS server found: 10.100.101.6
DNS server found: 8.8.8.8
https_init(): entered
QSSLPCL = *TLSV1.2 *TLSV1.1 *TLSV1 *SSLV3
SSL version 2 support disabled
SSL version 3 support disabled
Old interface to TLS version 1.0 support enabled
TLS version 1.0 support enabled
TLS version 1.1 support enabled
TLS version 1.2 support enabled
TLS version 1.3 support enabled
initializing GSK environment
GSK Environment now available
-------------------------------------------------------------------------------------
Dump of local-side certificate information:
-------------------------------------------------------------------------------------
Nagle's algorithm (TCP_NODELAY) disabled.
SNI hostname set to: staging.iowalandrecords.org
-------------------------------------------------------------------------------------
Dump of server-side certificate information:
-------------------------------------------------------------------------------------
Cert Validation Code = 6000
-----BEGIN CERTIFICATE-----
MIIHmjCCBoKgAwIBAgIQBtDTi/Ch5qEQnOtVNoQZcDANBgkqhkiG9w0BAQsFADB1
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTIzMDEzMTAwMDAwMFoXDTI0MDMwMjIz
NTk1OVowggEBMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRUwEwYLKwYBBAGCNzwCAQIT
BElvd2ExITAfBgsrBgEEAYI3PAIBARMQQXBwYW5vb3NlIENvdW50eTEaMBgGA1UE
DwwRR292ZXJubWVudCBFbnRpdHkxGjAYBgNVBAUTEUdvdmVybm1lbnQgRW50aXR5
MQswCQYDVQQGEwJVUzENMAsGA1UECBMESW93YTERMA8GA1UEBxMISm9obnN0b24x
IzAhBgNVBAoTGkVsZWN0cm9uaWMgU2VydmljZXMgU3lzdGVtMSQwIgYDVQQDExtz
dGFnaW5nLmlvd2FsYW5kcmVjb3Jkcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDDSQ+BH+e6tquCyP3TeqH1dytOgAHlYGA3+yZxjOv4V7u9onQL
ASMXi9CzqVys5OQg8Ccg3reu+7b9LB8T3GG7CXuLbt4s4YElsgXWgrGSpawJfaJX
DMx4+/fdNFGhY4puOaqq3uPXwMO0aeTO1SBocuObtcgKiyg4qHIHX1UA0+whgdxK
6h3ch8mxOgX1qNJj8DuogVA+zr434OceVpM4bsR6UitkpdP8zJ4bFZfkfXZEnDvv
BwbumFGtgFmkyHaG8u0j/rn0VS5sXnVS+pEGs1tYjMUpF3W229YGHMkkhQm8UU3Z
OgXK/R9Pz7V00V0mQYsY1sF8+j/G/yz+bG1JAgMBAAGjggOWMIIDkjAfBgNVHSME
GDAWgBQ901Cl1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQU/ALiOLa16jGKjBYE
N9klK4W0dNgwRwYDVR0RBEAwPoIbc3RhZ2luZy5pb3dhbGFuZHJlY29yZHMub3Jn
gh93d3cuc3RhZ2luZy5pb3dhbGFuZHJlY29yZHMub3JnMA4GA1UdDwEB/wQEAwIF
oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKg
MIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWczLmNy
bDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVy
LWczLmNybDBKBgNVHSAEQzBBMAsGCWCGSAGG/WwCATAyBgVngQwBATApMCcGCCsG
AQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYgGCCsGAQUFBwEB
BHwwejAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsG
AQUFBzAChkZodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEy
RXh0ZW5kZWRWYWxpZGF0aW9uU2VydmVyQ0EuY3J0MAkGA1UdEwQCMAAwggF9Bgor
BgEEAdZ5AgQCBIIBbQSCAWkBZwB2AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8vOzew1FI
WUZxH7WbAAABhgkLDcsAAAQDAEcwRQIgUvLha0TUYyaiIifp7qXPUPnM90M3SV+9
hkkwAAwN6mkCIQDlX0vABEbVe5spsCQNWd09MnuieEWO5YHylo8L2BtM/AB2AHPZ
nokbTJZ4oCB9R53mssYc0FFecRkqjGuAEHrBd3K1AAABhgkLDdYAAAQDAEcwRQIg
Aa7f5xNxEbqy7BxIrs7I6hjR+/mZjCKXaKATVv2rPLECIQDK5MWrbSXaM3l83O8W
J3TENGMVwfbvkXfVPLWv1LoJDAB1AEiw42vapkc0D+VqAvqdMOscUgHLVt0sgdm7
v6s52IRzAAABhgkLDacAAAQDAEYwRAIgVAcHVlKoK1ssSxGZuLqIA5bNsyXz1/t/
yko8ghl/Y0oCIH87ZSL3pKK2paK/NogpflU1+jcTzYQAlHcWsFM3yFTxMA0GCSqG
SIb3DQEBCwUAA4IBAQAKPB3RlAnorGEIeS8xLVVwo1g4D60wkRB4xjuFrzK2xS3/
qMxRo5Cchngylg0MXU/p/t6y+SvOFbasY1ox42a16RRAOXUxLRt7fiGi3nk6Z3/l
dCaXyRlckCknKl2lqgMhdQfbKkxhmijPd5KU+Zyl4shA39pqiPpdJIzrB/IaWZw4
xe0STX47HlxaOYA8HLFosgeXXzsyLrzWtr9wpowuj0gdPXoutqT9YL7bEUEqdtvy
91STF1yLCT9YieXxxomiekeJjKGX2Yabf4GmZ/s/UlMeGKfNgRN63I+Ig0yAKX8/
/JctYWO4PODoyhOYGxqCwo43mNtLX/PQAyR/Yv6Y
-----END CERTIFICATE-----
Serial Number: 06:D0:D3:8B:F0:A1:E6:A1:10:9C:EB:55:36:84:19:70
Common Name: staging.iowalandrecords.org
Country: US
State/Province: Iowa
Locality: Johnston
Org Unit: Electronic Services System
Issuer CN: DigiCert SHA2 Extended Validation Server CA
Issuer Country: US
Issuer Org: DigiCert Inc
Issuer Org Unit: www.digicert.com
Version: 3
not before: 20230130180000
Unknown Field: 18:00:00 30-01-2023
not after: 20240302175959
Unknown Field: 17:59:59 02-03-2024
pub key alg: 1.2.840.113549.1.1.1
signature algorithm: 1.2.840.113549.1.1.11
Unknown Field: 0382010F003082010A0282010100C3490F811FE7BAB6AB82C8FDD37AA1F5772B4E8001E5606037FB26718CEBF857BBBDA2740B0123178BD0B3A95CACE4E420F02720DEB7AEFBB6FD2C1F13DC61BB097B8B6EDE2CE18125B205D682B192A5AC097DA2570CCC78FBF7DD3451A1638A6E39AAAADEE3D7C0C3B469E4CED5206872E39BB5C80A8B2838A872075F5500D3EC2181DC4AEA1DDC87C9B13A05F5A8D263F03BA881503ECEBE37E0E71E5693386EC47A522B64A5D3FCCC9E1B1597E47D76449C3BEF0706EE9851AD8059A4C87686F2ED23FEB9F4552E6C5E7552FA9106B35B588CC5291775B6DBD6061CC9248509BC514DD93A05CAFD1F4FCFB574D15D26418B18D6C17CFA3FC6FF2CFE6C6D490203010001
Unknown Field: 2048
Unknown Field: BB6E45C8F07ABFEE36A2B571014DF81F
Unknown Field: 1.2.840.113549.2.5
Unknown Field: 8812F39CEA90589B8DB357AC33AA3FFA583CA30B
Unknown Field: 43E538FA65CDA4CBC9123C7CBD57BB0FB7A56D74ADF5A4B0C432408EE1E5B45A
Unknown Field: 5
Unknown Field: staging.iowalandrecords.org
Unknown Field: 0
Unknown Field: 1.3.6.1.5.5.7.3.2
Unknown Field: 1.3.6.1.5.5.7.3.1
Unknown Field: 2.23.140.1.1
Unknown Field: 2.16.840.1.114412.2.1
Unknown Field: http://ocsp.digicert.com

Protocol Used: TLS Version 1.2
http_persist_req(GET) entered.
http_long_ParseURL(): entered
http_long_ParseURL(): entered
do_oper(GET): entered
There are 0 cookies in the cache
GET /esubmission/services/county/api/readyForDownload HTTP/1.1
Host: staging.iowalandrecords.org
User-Agent: http-api/1.45
Authorization: Basic X2pZZUJWbjJOZTRwUzFKc2w5eDNROTQ0ZVlUYmViM2M6NDI0MDcxMTQ0ODg1MTI0MzkxNw==


recvresp(): entered
HTTP/1.1 401 401
Date: Fri, 10 Mar 2023 19:37:52 GMT
Server: Apache
Strict-Transport-Security: max-age=15768000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Length: 26


SetError() #13: HTTP/1.1 401 401
recvresp(): end with 401
recvdoc parms: identity 26
interpret_auth(): entered
SetError() #36: This page requires a user-id & password
header_load_cookies() entered
AuthPlugin_mustReceiceAuthErrorPage(): entered
recvdoc(): entered
SetError() #0:
recvdoc(): Receiving 26 bytes.
{"error": "Access Denied"}
SetError() #36: This page requires a user-id & password
http_close(): entered
Last edited by sLucke1015 on Mon Mar 13, 2023 11:21 am, edited 1 time in total.
jonboy49
Posts: 200
Joined: Wed Jul 28, 2021 8:18 pm

Re: Consuming a REST Web Service

Post by jonboy49 »

I haven't the time right now to go through your code, but I did notice that you don't seem to be setting the network CCSID for JSON data. In all of my JSON routines I have:

Code: Select all

 http_setOption ( 'network-ccsid' : '1208' );
 
At the start of my code. Just after setting up debug.

I'm pretty sure it won't help your current situation, but when you do get connected, you'll need it to make sense of the data.
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Re: Consuming a REST Web Service

Post by sLucke1015 »

Thank you Jonboy49. It has been added to the program. Very much appreciate your input.
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Consuming a REST Web Service

Post by Scott Klement »

Hello,

In your documentation you show this as the last step:

Code: Select all

var authKey = base64Encode(apikey + ':' + apihash);
That is exactly what http_setauth does -- it combines the two parts (I call them userid/password rather than apikey and apihash, but they are the same). However, the code that comes before that line is custom to this API, and you will have to code it yourself.

So your code should look something like this:

Code: Select all

HTTP_setAuth(HTTP_AUTH_BASIC: apiKey:  hashedAPIkey());
and the hashedApiKey() routine should be responsible for generating the 'apihash' variable by performing these steps:

Code: Select all

var seed = generateRandomValue();
var prehash = apikey + seed + apipin;
var apihash = 's2/'+ seed + '/' + encodeHex(sha256(prehash));
Also take care to ensure that you convert your data to UTF-8 prior to generating the hash. Otherwise, your hash will not match the one on the server (since it's unlikely that it's generating its hash from EBCDIC data.)

So the steps in RPG would be:

1) Generate a random seed.
2) Combine the apikey + seed + apipin.
3) Convert the output of step 2 to UTF-8.
4) Use the https://www.ibm.com/docs/api/v1/content ... 3calha.htm QC3CALHA system API (or equivalent) to generate a hash of the UTF-8 string.
5) Convert the hash to hex. (You can use the CVTHC MI-built-in for this if you want)
6) Concatenate s2/ + seed + the result of step 5 to create the apihash variable. (This should be in EBCDIC)
7) That apihash variable is what is placed in the 'password' parameter to http_setAuth.
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Re: Consuming a REST Web Service

Post by sLucke1015 »

Thank you very much Scott.
It's working. The json string is being returned as expected.
Thanks again!
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Re: Consuming a REST Web Service

Post by sLucke1015 »

If a single RPGLE program is doing many "HTTP_req" and "HTTP_string" operations, will one "HTTP_setAuth" suffice?

...or will multiple be necessary?
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Consuming a REST Web Service

Post by Scott Klement »

The single one should be sufficient -- it will store in the credentials in memory and re-use them until you clear them (by calling HTTP_setAuth again with HTTP_AUTH_NONE) or until the activation group is reclaimed.
sLucke1015
Posts: 18
Joined: Tue Mar 07, 2023 3:09 pm

Re: Consuming a REST Web Service

Post by sLucke1015 »

I am now running into a problem with large documents with the following statement:
rc = HTTP_req( 'GET' : url : *omit : z_Buffer );

This is the DS that the incoming data will be placed into:

Code: Select all

dcl-ds  downloadDoc            qualified;         // -downloadDoc
  dcl-ds  requestGroup;                           // --requestGroup
    dcl-ds  submittingParty;                      // ---submittingParty
      name  varchar(35);                                        // "testpayment"
      num_contactDetailList         packed(2:0);
      dcl-ds  contactDetailList   dim(99);        // ----contactDetailList
        name  varchar(35);                                    // "Franklin, Ida"
        num_contactPoint            packed(2:0);
        dcl-ds  contactPoint      dim(99);        // -----contactPoint
          roleType                  varchar(12);                       // "Work"
          type                      varchar(12);                      // "Email"
          value                     varchar(45);             // "phil@clris.com"
        end-ds;                                   // -----contactPoint
      end-ds;                                     // ----contactDetailList
    end-ds;                                       // ---submittingParty
    dcl-ds  request;                              // ---request
      num_key                          packed(2:0);
      dcl-ds  key                 dim(99);        // ----key
        name                           varchar(20);                // "sequence"
        value                          varchar(25);                       // "1"
      end-ds;                                     // ----key
      dcl-ds  priaRequest;                        // ----priaRequest
        type                           varchar(12);                   // "Other"
        typeOtherDescription           varchar(25);             // "ESubmission"
        dcl-ds  package;                          // -----package
          dcl-ds  priaDocument;                   // ------priaDocument
            dcl-ds  recordingEndorsement;         // -------recordingEndorsement
              numberOfParcels          zoned(5:0);                          // 0
              dcl-ds  fees;                       // --------fees
                num_fee                packed(2:0);
                dcl-ds  fee       dim(99);        // ---------fee
                  description          varchar(25);             // "StandardFee"   <-----<<<
                  amount               zoned(7:2);                       // 5.00
                end-ds;                           // ---------fee
                totalAmount            zoned(9:2);                       // 7.00
              end-ds;                             // --------fees
              num_exemptions           packed(2:0);
              dcl-ds  exemptions  dim(99);        // --------exemptions
                type                   varchar(12);                   // "Other"
                typeOtherDescription   varchar(25);      // "DeclarationOfValue"
              end-ds;                             // --------exemptions
            end-ds;                               // -------recordingEndorsement
            countyOfRecordationName    varchar(25);                // "Humboldt"
            num_embeddedFile           packed(2:0);
            dcl-ds  embeddedFile  dim(4);         // -------embeddedFile
              encodingType             varchar(25);               // "B64Encode"
              mimeType                 varchar(10);                    // "TIFF"
              name                     varchar(60);  // "Recorde...Template.pdf"
              numberOfPages            zoned(4:0);                          // 1
              sequenceIdentifier       zoned(4:0);                          // 1
              document                 varchar(300000);         // ????????????????
            end-ds;                               // -------embeddedFile
            type                       varchar(20);                   // "Other"
            typeOtherDescription       varchar(70);      // "CornerCertificates"
          end-ds;                                 // ------priaDocument
        end-ds;                                   // -----package
      end-ds;                                     // ----priaRequest
    end-ds;                                       // ---request
  end-ds;                                         // --requestGroup
end-ds;                                           // -downloadDoc
[/size]

I have the z_Buffer field set to VARCHAR(16773100) the max, but the large document data sometimes exceeds this, therefore the JSON is incomplete.

Or maybe I'm doing something else wrong...

Is there any way to access this so that the large amount of data can be retrieved?

Thanks again,
Post Reply