Previous Thread
Next Thread
Print Thread
HTTP GET Custom Headers #24258 02 Apr 19 08:43 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
It has come to the attention of one of our intrepid developers that there was no way to add custom headers to a "GET" (XHTTPF_REQGET) request in HTTP.SBR. In order to rectify that, I've added the following patch to the ASHNET library...

Code
1. ASHNET library update 1.12.164: refinement to HTTP.SBR to allow custom
headers to be added to a GET request (XHTTPF_REQGET). Previously this was
only possible with the POST request type (XHTTPF_REQPOST / XHTTPF_REQUPLOAD).
To specify custom headers, set the XHTTPF_HDRBODY flag and put the new
headers into the request$ parameter, using chr(13) to separate multiple
headers, e.g.:

   flags = XHTTPF_REQGET or XHTTPF_HDRBODY
   request$ = "Referer: http://www.microsabio.com"
   request$ += chr(13) + "User-Agent: A-Shell/ashnet-1.2.164"
   ...
   xcall HTTP, 1, status, flags, url$, request$, response$, properties$

Note that you must specify at least 7 parameters (i.e. at least thru the
properties$ parameter), even if the properties$ parameter is blank.
(Otherwise a more limited version of the routine will be used, which
doesn't support this enhancement.)

You can also put the custom headers into a file, as you would with
XHTTPF_REQPOST + XHTTPF_FILEREQ + XHTTPF_HDRBODY. (With the GET request,
anything following the first blank line would be ignored.)

Note that to examine/debug your headers, set the XHTTPF_DEBUG flag and
then look at the DEBUG.LOG file on return from the XCALL.
  
It's not yet clear though whether this capability is going to actually resolve the underlying issue (of some web service rejecting the request, allegedly due to some issue with the headers), so I'm posting this as a beta update for testing until the issue is resolved.

Links:

ashnet-1.12.164-w32.zip
libashnet.so.1.12.164.el5.tz
libashnet.so.1.12.164.el7.tz

Notes: these should be able to work with any 6.4+ version of A-Shell, and probably considerably farther back than that. (The Linux version requires at least 6.3.1544 to even support HTTP.SBR at all though.) For Windows, you can drop the DLL in the bin directory with the ashw32.exe. For Linux, do the same, but then create a link from /usr/lib/libashnet.so.1 to it. In both cases you need to unzip/untar it first.

Re: HTTP GET Custom Headers #24259 02 Apr 19 09:12 PM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
No such luck on my end I'm afraid. I'm trying using the el5 version, and getting the same errors as before, the large response payload that appears to relate to the underlying library, and not the actual respons from the called URL, http status code is -26.

With _DEBUG enabled looking at the send section shows that none of the custom headers were processed. And the actual response from the server can be seen correctly, rather than the one being presented as the response by HTTP.

Test Code
Code
++INCLUDE ashinc:http.def


! http communication
map1 http'params
    map2 http'flags,b,4
    map2 http'url,s,0,""
    map2 http'upload,s,2000,""
    map2 http'response,s,4000,""
    map2 http'status,f
    map2 http'properties,s,100,""
    
    http'flags = XHTTPF_SSL
    http'flags = http'flags or XHTTPF_REQGET
    http'flags = http'flags or XHTTPF_HDRBODY
    http'flags = http'flags or XHTTPF_DEBUG
    
    http'url = "https://test-api.service.hmrc.gov.uk/organisations/vat/524813945/obligations?status=O"
    
    http'upload = ""
    http'upload += "Accept: application/vnd.hmrc.1.0+json" +  CHR(13)
    http'upload += "Authorization: Bearer fe621927641ad70f7116b41de42252" +  CHR(13)
    http'upload += "Content-Type: application/json"
    
    xcall http, 1, http'status, http'flags, http'url, http'upload, http'response, http'properties
    
    ? http'status
    ? http'response
DEBUG.LOG
Code
---- Sending ----
GET /organisations/vat/524813945/obligations?status=O HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip
Host: test-api.service.hmrc.gov.uk


---- Received ----
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=UTF-8
Content-Length: 92
Accept-Encoding: gzip
Accept-Language: en-us,en;q=0.5
Cache-Control: no-cache, max-age=0
Pragma: no-cache
WWW-Authenticate: Bearer realm="HMRC API Platform"
Strict-Transport-Security: max-age=31536000;
Date: Wed, 03 Apr 2019 08:44:28 GMT
Connection: keep-alive

{ "code" : "MISSING_CREDENTIALS", "message" : "Authentication information is not provided" }
HTTP Response
Code
ChilkatLog:
  QuickGetStr(281ms):
    DllDate: Nov 13 2016
    ChilkatVersion: 9.5.0.64
    UnlockPrefix: MCRSABHttp
    Architecture: Little Endian; 32-bit
    Language: Linux C/C++
    VerboseLogging: 1
    url: https://test-api.service.hmrc.gov.uk/organisations/vat/524813945/obligations?status=O
    httpRequestStr(281ms):
      sessionLogFilename: debug.log
      a_quickReq(281ms):
        quickHttpRequest(281ms):
          httpVerb: GET
          url: https://test-api.service.hmrc.gov.uk/organisations/vat/524813945/obligations?status=O
          openHttpConnection(240ms):
            Opening connection directly to HTTP server.
            httpHostname: test-api.service.hmrc.gov.uk
            httpPort: 443
            ssl: 1
            bUsingHttpProxy: 0
            httpProxyAuthMethod:
            socket2Connect(240ms):
              connect2(240ms):
                hostname: test-api.service.hmrc.gov.uk
                port: 443
                ssl: 1
                connectImplicitSsl(240ms):
                  Clearing TLS client certificates.
                  connectSocket(70ms):
                    domainOrIpAddress: test-api.service.hmrc.gov.uk
                    port: 443
                    connectTimeoutMs: 30000
                    connect_ipv6_or_ipv4(70ms):
                      Single-threaded domain to IP address resolution
                      connecting to IPV4 address...
                      ipAddress: 104.127.42.135
                      createSocket:
                        Setting SO_SNDBUF size
                        sendBufSize: 262144
                        Setting SO_RCVBUF size
                        recvBufSize: 4194304
                      --createSocket
                      connect(28ms):
                        Waiting for the connect to complete...
                        myIP: 172.16.0.12
                        myPort: 50198
                        socket connect successful.
                      --connect
                    --connect_ipv6_or_ipv4
                  --connectSocket
                  clientHandshake(170ms):
                    The client cert chain is NULL.
                    cacheClientCerts:
                      Cached TLS client certificates.
                      Client cert chain is NULL.
                    --cacheClientCerts
                    clientHandshake2(169ms):
                      readHandshakeMessages(24ms):
                        processHandshakeRecord:
                          processHandshakeMessage:
                            processServerHello:
                              negotiatedTlsVersion: TLS 1.2
                              negotiatedCipherSuite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
                              minAcceptableRsaKeySize: 1024
                            --processServerHello
                          --processHandshakeMessage
                        --processHandshakeRecord
                      --readHandshakeMessages
                      buildClientKeyExchange(30ms):
                        buildClientKeyExchangeECDHE(30ms):
                          verifyServerKeyExchange(3ms):
                            verifyHash(3ms):
                              keyType: Public
                              hashInSize: 32
                              padding: PKCS v1.5
                              HashOid: 2.16.840.1.101.3.4.2.1
                            --verifyHash
                          --verifyServerKeyExchange
                          Verified server key exchange.
                          generateNewKey_ecc(13ms):
                            loadCurveByName:
                              name: secp256r1
                            --loadCurveByName
                          --generateNewKey_ecc
                          loadSshPubKey:
                            loadCurveByName:
                              name: secp256r1
                            --loadCurveByName
                          --loadSshP
Pretty sure the library is setup correctly.
Code
lrwxrwxrwx 1 omni omni       25 Apr  3 09:06 libashnet.so.1 -> libashnet.so.1.12.164.el5
-rwxrwxrwx 1 omni omni  6180088 Feb 13  2017 libashnet.so.1.10.158.el5
-rwxr-xr-x 1 omni omni  7475230 Apr  2 20:27 libashnet.so.1.12.164.el5

Re: HTTP GET Custom Headers #24260 03 Apr 19 03:20 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
Something wrong there. Clearly it's not calling the new library function, but it's not clear why. Is this A-Shell 6.4? Is that directly listing showing the libashnet's from the A-Shell bin directory or from the /usr/lib/ directory? (It should be the latter, since the ashell executable will look there first.)

Re: HTTP GET Custom Headers #24261 03 Apr 19 03:44 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
Here's what my el5 setup looks like...

Code
$ ls -l /usr/lib/libashnet*
lrwxrwxrwx 1 root root 39 Apr  4  2018 /usr/lib/libashnet.so.1 -> /vm/miame/bin/libashnet.so.1.12.164.el5
And here's what the debug.log contains after running your program...

Code
---- Sending ----
GET /organisations/vat/524813945/obligations?status=O HTTP/1.1
Accept: application/vnd.hmrc.1.0+json
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
Accept-Language: en-us,en;q=0.5
Authorization: Bearer fe621927641ad70f7116b41de42252
Accept-Encoding: gzip
Host: test-api.service.hmrc.gov.uk


---- Received ----
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=UTF-8
Content-Length: 93
Accept-Encoding: gzip
Accept-Language: en-us,en;q=0.5
Cache-Control: no-cache, max-age=0
Pragma: no-cache
WWW-Authenticate: Bearer realm="HMRC API Platform"
Strict-Transport-Security: max-age=31536000;
Date: Wed, 03 Apr 2019 15:37:23 GMT
Connection: keep-alive

{ "code" : "INVALID_CREDENTIALS", "message" : "Invalid Authentication information provided" }
So the good news is that the new headers are being sent, and they are having an effect. The bad news is that now instead of "MISSING CREDENTIALS", we're getting "INVALID CREDENTIALS". (Hopefully that's a simple matter of getting the right ones, or of sending the request from the right domain or within the provided time frame.)

Re: HTTP GET Custom Headers #24262 03 Apr 19 10:05 PM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
Looks like I'd linked the wrong library, that's now correct, and I can see in the debug.log that the round trip appears to be working.

However, the reponse in AShell via XCALL HTTP still looks like it's polluted rather than returning the actual response code and response body.

Re: HTTP GET Custom Headers #24263 04 Apr 19 06:58 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
The response code is returned in the status parameter (-26). That seems correct.

You have a point that the detailed log currently being returned in the response parameter in the case of an error is obscuring the actual response, which can be see in the DEBUG.LOG file.

I think that does need to be fixed, but shouldn't be getting in the way of determining whether the new custom headers capability is going to make it possible to achieve a successful get. (In which case I think the detailed response will be the correct one, not the log dump.)

Re: HTTP GET Custom Headers #24264 08 Apr 19 08:49 PM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
Sorry for the delayed reply, I've been pulled back and forth and completelty lost track of this!

It certainly seems that everything is correct now, apart from the response. The REST API's we're dealing with will be sending back information in the body of a rejected request, so having easy access to it would be preferable, as it's feasible we could end up with two requests both firing at the same time, which would make reading DEBUG.LOG not ideal.

Re: HTTP GET Custom Headers #24265 09 Apr 19 02:44 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
Understood (on all fronts). I've got a few balls in the air at the moment too, but have it near the top of my list to fix the error response issue.

Re: HTTP GET Custom Headers #24266 15 Apr 19 12:25 PM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
I think this (beta) update of the ashnet library resolves the issue with the response parameter when the GET operation fails. See the notes for further details.

libashnet.so.1.12.165.el5.tz
ash65notes.txt

With the new version, here are the responses I get with a slightly modified version of your program...

!
Code
...
    ? "Status: ";http'status
    ? "Response: ";http'response
    
    if http'status <= 0 then
        xcall http, 1, http'status, XHTTPF_GETSTSTXT, "", "", http'response
        ? "GETSTSTXT: "
        ? http'response
    endif
Using the original XHTTPF_REQGET opcode...
Code
Status:  0
Response: 401 Unauthorized
GETSTSTXT:
401 Unauthorized (ConnectFailCode=0)
Note that the "ConnectFailCode=0" is essentially telling us that it didn't fail to connect; the error was that the service didn't like our authorization. (If we failed to connect, the ConnectFailCode would have been non-zero.)

Using the new XHTTPF_REQGETX opcode...
Code
Status:  401
Response: { "code" : "INVALID_CREDENTIALS", "message" : "Invalid Authentication
information provided" }

Re: HTTP GET Custom Headers #24267 17 Apr 19 06:05 AM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
Thanks Jack, that appears to work perfectly!

Re: HTTP GET Custom Headers #24268 17 Apr 19 04:27 PM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
Glad to hear it. I'll move it out of beta status in a couple of days (as there a couple of unrelated problems I'm trying to track down.)

Re: HTTP GET Custom Headers #24269 16 Jun 19 08:19 PM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
Hi Jack, this has worked perfectly, but I've just found out we have one customer still on a windows server that needs the software too. Is it possible to get a windows version of the library with the update?

Re: HTTP GET Custom Headers #24270 17 Jun 19 02:52 AM
Joined: Jun 2001
Posts: 11,945
J
Jack McGregor Online Content OP
Member
OP Online Content
Member
J
Joined: Jun 2001
Posts: 11,945
Here's a link to the two pieces you'll need for testing...

ash-6.5.1661.3-w32c-upd.zip
ashnet-1.12.165-w32.zip

I'll try to get a proper release package posted shortly.

Re: HTTP GET Custom Headers #24271 18 Jun 19 03:57 AM
Joined: Jun 2001
Posts: 153
O
OmniLedger - Tom Reynolds Offline
Member
Offline
Member
O
Joined: Jun 2001
Posts: 153
Thanks Jack, much appreciated.


Moderated by  Jack McGregor, Ty Griffin 

Powered by UBB.threads™ PHP Forum Software 7.7.3