URLConnection - fails, Thunderclient succeeds

Im sending the below to a server that should respond with a list of data. If I send the exact same (as near as I can tell) via Thunderclient I get back the list I expect but with URL connect via my webapp, I get a repsonse that indicates the request body isnt right. It should look like: {“dsid”:50982} My json.ToString appears to be perfect to me, as well as the rest. What could I be missing?

Self.RequestHeader("Content-Type") = "application/json"
Self.RequestHeader("api-token") = APIKey

Var json As New JSONItem
json.Value("dsid") = 50982

me.SetRequestContent(json.ToString, "application/json")
me.Send("GET", "https://api.myserver.com/v1/datasource/tree")

Shouldn’t that be a POST iso a GET ?

Thanks Steve, it is a GET… Im wondering if theres some difference in 2021r3.1 or Webapp verses desktop. Im searching everywhere but still not able to see the diff…

Why are you using self.xxx on the top lines but me.xxx on the bottom two lines? We are missing some context here.

Hi Douglas, You’re right, just legacy copying - Ill fix that. Its a subclass of URLConnection and that header setup is just copied from other code. I also transfered the important parts I see into the xojo example “URLConnectionGET” in the asych call and its exactly the same response.

WebConnection.RequestHeader("api-token") = EncodeURLComponent("APIKey")

Var json As New JSONItem
json.Value("dsid") = 50982

WebConnection.SetRequestContent(json.ToString, "application/json")
WebConnection.Send("GET", "https://api.myserver.com/v1/datasource/tree")

Im just continuing to try to find what could possibly be different. Im going to check postman but realling grasping at straws now…

Not your server ? Still maintain that no body is expected with a GET

2 Likes

correct Steve, not my server but one of a partnerss that hasnt changed in this regard. Plus it works perfectly in vscode and postman. Its also not reassuring that the same code in the example produces the same result. Heres the doc on that endpoint, minus the details about how if you dont ask for a dsid it returns a parent source to traverse - which is what happens with my code and is unexpected to say the least. With the others it works exactly as documented and expected

GET /datasource/tree
Request
Response 200
Headers

Content-Type: application/json
api-token: API-00000-00000-00000-00000
Body

{
  "dsid": 1
}
Schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "dsid": {
      "type": "number"
    }
  }
}

I know it looks like the dsid value should be a string but that throws an error and Ive always sent integers before and ints work in the other apps.

In your original code, the url had a v1 between the .com and /datasource/tree but in your latest post you only “GET /datasource/tree”.

Are you sure the URL is correct?

Yep, the one just above is from the api endpoint’s document to show what im supposed to send in there so thats just the description of the endpoint that its a GET and does expect a body formatted accordingly. I for sure did a full look though thanks!

This request has no body, as would be expected for a GET request.

Edit: It’s also really strangely formed. The content type is in the body? A content type is not normally included with a GET request. That’s part of the response. Normally you’d use Accept to tell the server what kind of response you want.

I would add this part in bold:

Var json As New JSONItem
json.Value(“dsid”) = 50982

Var jsonString As String = json.ToString
Break

WebConnection.SetRequestContent(jsonString, “application/json”)

Then in the debugger examine the contents of jsonString to make sure it is was you expect.

Content Type is not in the body Thom

If I had to guess, URLConnection is not sending the body because it doesn’t belong. When I try your request in Paw, it also warns me “GET requests should not have a body” and doesn’t include it in HTTP output:

GET /v1/datasource/tree HTTP/1.1
api-token: API-00000-00000-00000-00000
Content-Type: application/json; charset=utf-8
Host: api.myserver.com
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.3.0) GCDHTTPRequest



Obviously I can’t try a request to see the response, but my point stands. Changing it to a POST request, which also feels wrong, yields more expected results:

POST /v1/datasource/tree HTTP/1.1
api-token: API-00000-00000-00000-00000
Content-Type: application/json; charset=utf-8
Host: api.myserver.com
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.3.0) GCDHTTPRequest
Content-Length: 16

{"dsid":"50982"}

You might need to use CURLMBS to do something as standard-breaking as this, but even then, I have my doubts. You could try it on the command line first to see what happens:

curl "https://api.myserver.com/v1/datasource/tree" \
     -H 'api-token: API-00000-00000-00000-00000' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "dsid": "50982"
}'

I can see the json.ToString value in the debugger and it looks perfect but I ssuspect this is where soemthing is going wrong…

you cannot make a GET request with body data in URLConnection since it follows system guidelines which arn’t allowing for this (as html spec suggest it should not have a body).

Thanks Thom but Ive been using this same API for over a year and with the same GET structures. You must have read the endpoint description but I did try your cURL with and without quotes (postman and thunder it works without quotes and also how Ive been doing it for a year) but it gets a different failure in contacting the server. I dont know cURL well enough to figure out whats going on there. Its odd though how other endpoints with the same structure continue to work as expected. URLConnect definately sends the body if you put one in there - right or wrong. I suspect something is happening to the body string in xojo. Does anyione know if anything could have changed? The only difference I know of is that on this iteration of code I went to 2021r3.1 - but the same older calls work fine but not the new ones I wrote in the new version.

Thanks Derk, you and a few others ahve pointed that out but it works in many other circumstances and lots of other endpoints in various APIs so Im pretty sure thats not it. URLConnect does send the body - it just returns the response for a body inccorectly formed or more specifically as if there was no body attached (if you dont request a particular dsid it return a root level dsid that should be traversed). I pasted the endpoint schema from the API docs above.
I also tried the URLConnectionGET example with the above code in 2020r2.1 and it does the same thing. So strange…Im not sure where to look now.

1 Like

At least two ways to fine out:

  1. Use Wireshark or similar tool to sniff what is on the network wire
  2. Send the URLConnection to a server you control and examine contents
1 Like

Unfortunately since we can’t actually make the request, there’s only so much we can do to help. Douglas is right, your next step is to figure out what URLConnection is sending.

1 Like

Don’t expect something to remain in the future. Fix the cause and move on. Finding a solution to keep as is will cause more issues.

Your best somution is to fix the server or have that being fixed so it expects a POST and read the body or GET and expect NO body (in the request) .

GET simply means give me some data, so don’t send it some.

1 Like