ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

HTTPAPI : Preventing Content-Length From Being Inserted Into Header

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • HTTPAPI : Preventing Content-Length From Being Inserted Into Header

    How do I prevent the Content-Length property from being inserted in the header of an HTTPAPI rest request? For some reason, it is causing the rest api to fail. I can confirm this using a windows tools called Postman.

    (Scott, I removed my post from the "other" thread).



  • #2
    I went out on a limb and found any source in the httpapi source library that has "content-length" in it. I found source for HTTPAPIR4 which contains procedure do_oper. I found a block of code that set's Content-Length. I understand that this could potentially break other api's. I found how the module was compiled in the install program and compiled the module. Then I performed an UPDSRVPGM HTTPAPIR4 using module HTTPAPIR4. When I reran my program I noticed the content-length was still in the header. Then it dawned on me. We have several other 3rd party tools that use HTTPAPI. Sure enough, they were higher in my library list. I set my library list up so that my httpapi library is right after qtemp. I then reran my program and it did not include the Content-Length in the header, BUT, it's still hanging up for 60 seconds and logging the following messages:

    Code:
    recvresp(): entered
    SetError() #43: CommSSL_Read:  timeout!
    recvresp(): end with timeout
    http_close(): entered

    I double checked with Postman and was able to replicate the exact header that HTTPAPI is creating, and it worked. The only difference is Postman includes a Cache-Control: no-cache header, but I have a feeling this isn't the problem since another program access a separate host/api is working without the Cache-Control header. I have a feeling something is wrong with SSL.

    I made it all the way to the following code on line 6763 in HTTPAPIR4:

    Code:
    rc = select(fd+1:%addr(wwfds):*NULL:*NULL:%addr(wwTimeout) )
    The procedure is commssl_read(). I found HTTP_DEBUG_LEVEL in this procedure and saw that it would dump more information (not sure how to set this globally). Here is the additional dump in the debug log:

    Code:
    recvresp(): entered
    CommSSL_Read(): gsk_secure_soc_read socket fd=5, flags=00000084, blocking=0
    CommSSL_read(): gsk_secure_soc_read rc=502, len=0
    CommSSL_read(): before select socket fd=5, flags=00000084, blocking=0
    CommSSL_read(): before select: select fd=5, readset=00000020000000000000000000000000000000000000000000000000, writeset=*NULL, excpset=*NULL, timeval=0000003C00000000
    CommSSL_read(): after select socket fd=5, flags=00000084, blocking=0
    CommSSL_read(): after select: select fd=5, readset=00000000000000000000000000000000000000000000000000000000, writeset=*NULL, excpset=*NULL, timeval=0000003C00000000, rc=0
    SetError() #43: CommSSL_Read:  timeout!
    recvresp(): end with timeout
    http_close(): entered
    After commsslread() is done, fd = 5 and wwfds = all question marks.

    Not sure how much further I can take this research. Suggestions?

    Comment


    • #3
      What type of HTTP request are you doing? GET? PUT? POST?

      Certain HTTP operations, such as PUT and POST require the content-type. Without it, the HTTP protocol cannot function properly. Other requests such as GET should not have it.

      Basically, if you're sending "post data" (or file data... however you want to look at it... the technical term is 'request body') then the content-length is required.

      Comment


      • #4
        Scott,

        Definitely a post, and when I include a content-length header, it fails in Postman. When I remove it, it works. When I include content-length in my httpapi call, it fails instantly. When i exclude it, it hangs for 60 seconds and fails with the errors I listed above. I'd be happy to send you the exact request from Postman if there was a secure way to do so (it contains an API key that is private).

        Comment


        • #5
          You can e-mail them to me. Is that secure enough? it's sk<AT-SIGN>scottklement.com

          Comment


          • #6
            Originally posted by Scott Klement View Post
            You can e-mail them to me. Is that secure enough? it's sk<AT-SIGN>scottklement.com
            Sent. Thanks!

            Comment


            • #7
              I got them, thanks. I have been in meetings all day today, but will try to look at them tomorrow.

              FWIW: Content-Length is required unless when you use POST/PUT unless you use Transfer-Encoding (which HTTPAPI does not support.) Servers are required to accept it. This is all documented in RFC 2616 which is the Internet Standard for HTTP. You can read it yourself, here: https://www.ietf.org/rfc/rfc2616.txt

              The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers.
              That means that you cannot send a document ("message body") without it... it is what signals the receiver that the document is coming.

              Maybe you tried to manually ADD the content-length header yourself? That would've resulted in two of them -- which is not valid -- since POSTMAN would've added it automatically. These are details that are part of the internals of the HTTP protocol, you aren't supposed to have to worry about them. POSTMAN or HTTPAPI will add them... there is no way to disable them.

              I'll try to look at your documents tomorrow and see what I can figure out.

              Comment


              • #8
                I appreciate you looking into this.

                I confirmed with the authors of the web service and they do not require content-length in their services.

                That being said, in Postman, if I leave content-length out, the request is still successful. If I add it, I have to be careful that the length includes any "beautification" spacing/tabs. So, the web service does take content-length but I cannot seem to get it to work from HTTPAPI, with or without the content-length.

                Comment


                • #9
                  This whole request was failing due to an incorrect custom header. I was missing the ending CRLF. Thanks for your help Scott!


                  I need to be able to do this: rc = http_setOption( 'Authorization' : 'myEncodedApiKey123KuanYa#/0*3' ); The reason I need to be able to do this is because the rest request requires an api key that is not userid/password based. Any thoughts?


                  Comment

                  Working...
                  X