Android Question Problem with httpJob StatusCode

davemorris

Active Member
Licensed User
Longtime User
Hi, Guys
I have a problem with this code
Http code:
        Dim urlString As String = modEposWeb.URL_COMMS_API & "?msgSrcDst=0&centreID=" & myData.centre.centreID & "&customerId=" & customerId
        job.PutString(urlString, tempMsg)
        job.GetRequest.SetContentType("application/json;charset=UTF-8")   
        Wait For (job) JobDone(job As HttpJob)
        If job.Success And job.Response.StatusCode = 200 Then
'            ToastMessageShow("Comms message sent to Web Server.", True)
        Else If job.Success And job.Response.StatusCode = 204 Then
            ToastMessageShow("Message REJECTED - Centre Closed", True)
        Else ' An error of some sort occurred
            Dim errorMsg As String = "An error occurred with the HTTP job: " & job.ErrorMessage
            ToastMessageShow(errorMsg, True)
        End If
        statusCode = job.Response.StatusCode
        job.Release ' Must always be called after the job is complete, to free its resources

Basically, if the API call returns status code = 200 - job.Success = true and job.response.StatusCode = 200 and it works great.
However, if the API call returns status code = 204, then job.Success = false then job.response.StatusCode = -1, and I end up with error message (as it drops thro' to the Else statement).
"An error occurred with the HTTP job: okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR"

I need to detect a 204 response, can anyone help (Note: Same code snippet works in B4i) - also I have selected OkHttp and OkHttpUtils2 libraries.

Regards
Dave
 

davemorris

Active Member
Licensed User
Longtime User
Hi
Thanks for the response.
Firstly, can I emphasize that this same code works for B4i (which detects the 204 response) and I am big on B4X so I like to use common code.

"You can parse Job.GetString for the result" - sorry did try that in debug (with a break point) - but most of the elements are null and job.response.StatusCode = -1. If there is a element I missed, please advise.

"Why does the error occur " - For the record status code 204 is not an error - (quoting Wiki) This class of status codes (200-299) indicates the action requested by the client was received, understood and accepted and 204 simply means - No content: The server successfully processed the request and is not returning any content.

Kind regards
Dave
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
how about seeing the status code within the else block? i realize 204 is success, but somebody up there thinks it isn't, so let's go with that.

B4X:
   else               ' an error of some sort occurred
      if job.Response.StatusCode = 204 then                                                ' technically it shouldn't go here (being success), but it is what it is
           toastmessageshow("Success! But No Actual Response", true)
      else
            Dim errorMsg As String = "An error occurred with the HTTP job: " & job.ErrorMessage
            ToastMessageShow(errorMsg, True)
      end if
   end if

also, i would prefer a single test for job.success and then testing for various status codes within that block. maybe just me.

B4X:
   if job.success then
      select job.response.statuscode
         case 200
               ...
         case 204  ' when they fix the problem, you're good to go without any changes
              ...
         case 202  'Accepted
              ...
         case  203 'Non-Authoritative Information
              ...
         case  205 'Reset Content
              ...
         case  206 'Partial Content
              ...
      end select
   else   ' error (or 204 currently)
      ...
   end if
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
HI
Thanks for the response, but the simple problem is with both our codes is that job.response.statuscode = -1 for a returned http status code = 204 - so there is no point in checking job.response.statuscode value.

Also, and perhaps most importantly, job.response.statuscode contains the correct value in B4i (when status code 204 is returned from the API) but not for B4A.

So I do think this is a bug in the B4A implementation, does anyone agree?

Regards
Dave
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
my server (apache 2.2) returns 200 with empty content. this seems to be a known issue (not just with apache). check the usual haunts on stackoverspew
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the api says if the response is null, return -1 otherwise return the status code.
this seems to me to be what's happening in your case.
googling "OkHttp response null" returns a lot. the first few hits don't seem to apply,
but you may have already gone through them. it seems to me that the api is doing
what it's supposed to, and that the issue is further up the chain
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
somebody fixed something today. i was getting 301 with a redirect this afternoon. now i get a straight 204. did a test in b4a with okhttputils, works fine: job is success and status code is 204, empty content. try it. happy new year.
 

Attachments

  • 204.jpg
    204.jpg
    23.2 KB · Views: 191
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Hi
Thanks for looking into my problem - I agree the code above does return 204. However, I am using a Put verb with a body containing addition data.

i.e. using j.PutString(urlString, tempMsg) instead of j.download(urlString)

For example - a valid call is
B4X:
        Dim jnew As HttpJob
        jnew.Initialize("", Me)
        Dim newMsg As String
        '  Note 4 quotes in row are required to put a quote around the message text.
        Dim tempMsg As String = """" & "EposOpenTabRequest,192.168.0.15,30,p710:::dy90yg:01384211000" & """"
        ' the centreId=20 is an open centre.
        Dim urlString As String = "https://www.superord.co.uk/api/comms?msgSrcDst=0&centreID=21&customerId=30"
        jnew.PutString(urlString, tempMsg)
        jnew.GetRequest.SetContentType("application/json;charset=UTF-8")
        Wait For (jnew) JobDone(j As HttpJob)
        Log(jnew.Success)
        Log(jnew.Response.StatusCode)
        jnew.Release

Which is a valid command and returns 200.

However, if we change the url slightly (Line #7 has been highlighted so the Server knows the request is valid but has no content (returns 204)
B4X:
        Dim jnew As HttpJob
        jnew.Initialize("", Me)
        Dim newMsg As String
        '  Note 4 quotes in row are required to put a quote around the message text.
        Dim tempMsg As String = """" & "EposOpenTabRequest,192.168.0.15,30,p710:::dy90yg:01384211000" & """"
        ' the centreId=21 valid centre but closed and no content available.
        Dim urlString As String = "https://www.superord.co.uk/api/comms?msgSrcDst=0&centreID=21&customerId=30"
        jnew.PutString(urlString, tempMsg)
        jnew.GetRequest.SetContentType("application/json;charset=UTF-8")
        Wait For (jnew) JobDone(j As HttpJob)
        Log(jnew.Success)
        Log(jnew.Response.StatusCode)
        jnew.Release

Output:
false
-1
(returns -1 instead of 204)

Also interesting, is if the URL is changed to "https://www.superord.co.uk/api/comms?msgSrcDst=0&centreID=5&customerId=30" which is a non-existent centre. Then the Server will return status 409
When I try the above code with line #7 changed to the URL.
Output:
false
409

Any suggestions?

(P.s. The server will response to both http:// and https:// which may help if you are using like Fiddler to view the internet communications)

Regards
Dave
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
ResponseError. Reason: okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR, Response:
Error Status: -1

a known issue, sorry. you can spend the rest of your new year's day reading the wailing and gnashing of teeth on github. only consolation, such as it is: the b4x library is following its instructions.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
use http, not https:

http://www.superord.co.uk/api/comms?msgSrcDst=0&centreID=21&customerId=30"
cache-control : [no-cache]
content-type : [application/json; charset=utf-8]
date : [Wed, 01 Jan 2020 18:58:29 GMT]
expires : [-1]
pragma : [no-cache]
server : [Microsoft-IIS/10.0]
x-aspnet-version : [4.0.30319]
x-powered-by : [ASP.NET]
x-powered-by-plesk : [PleskWin]
Success Status: 204
GOT:

---------------------------------------------------------------------------------------------------------------
Dim urlString As String = "http://www.superord.co.uk/api/comms?msgSrcDst=0&centreID=5&customerId=30"
ResponseError. Reason: Conflict, Response: {"Message":"Bad CentreId"}
Error Status: 409



when i use https, i get the -1. when i use http, i get what seem to be the expected answers. after some research regarding the okhttp3 stream interrupt error, it looked like https vs http was involved. when i did the putstring with http, i got the answers you're looking for. i think the exact nature of the https issue will require more research. see if you think this does it. sorry i missed the PUT early on; not quite the run of the mill request.
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Hi
Thanks for looking into the problem, unfortunately the Server we use is to go Https only soon so the using Http is not an option.

I do think it is definitely a bug, but I will not report it if nobody agrees, what do other think?

Kind regards
Dave
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the bug is apparently in the implementation of http/2 and certificates. it certainly has been reported (i spent some time looking at github and elsewhere). worth an email to your sysadmin, presumably. just to recap (in case you haven't done the same), our library states simply that if the result is null, the library is to return -1 to caller. otherwise, the statuscode. the only way the result could be null, is if there is no result (due to the server's cutting the connection without sending one). that's the bug. it's server side. that a call via http works, while one made using https fails should be enough to convince the authorities. it is possible there has been a fix, but your system has not been patched (you didn't hear that from me, and i will deny i posted this.)
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Hi
Thanks for you help - As I did state previous (sorry to repeat myself) is that the same code works with B4i and also similar code works with #c.net and vb.net.

That said, I can have a word with our guys (who write the server side API) and ask them to return something in the body for 204 status code, if they don't already do it (i.e. "No data available").

Question, do you think this would help? or should I firstly take it up with the Provider (HostPresto) or the certification authority (Let's Encrypt) - but because it fails with only B4A (and then only https) - I am expecting them to give me a hard time.

Kind regards
Dave
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
which is why i have given myself plausible deniability. no one likes a whistleblower.

when a connection aborts (which seems to be the case with https), there is nothing they can return. the same request under http does return 204, as expected.

this error message is the key: ResponseError. Reason: okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR, Response:
if the authorities are presented with this (and they research it), they might make nice to you.

on the client side, if you check for -1 and the error message and you see the above, at least you'll know what has happened. it's basically what the guys who wrote the server side api would do, no? it's the equivalent of your returning 204 to yourself.

why things work for apple needs some research; it is a different os with protocols implemented differently. sorry to repeat on my part, but i believe the front end (httputils) is not at fault. okhttp3 is further up the stack (or down, depending on your viewpoint).

a suitably abject message to your provider and to let's encrypt - with that error message - might help. i wouldn't go beyond mentioning that the same request made via http works. let them ask what they want to know, don't tell them what you think they should know.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
before you run off to your providers, it occurs to me that http3 is java client-side network software. i'm thinking the issue is on the android side. ios has traditionally shunned java. so, your server could easily be unaware of what's happening on the other side of the aether. not sure where this leaves you now.
 
Upvote 0
Top