mIRC Homepage
Posted By: AeonPsych Seeking Assistance w/ Sockets - 12/01/17 10:33 AM
Hello,
Been awhile since I've been around here, but just came across a new API I was waiting for to come out, and have been trying to figure out implementation into IRC script.


Basically just simple GET/POST requests. I have everything working correctly, the requests are successful, but I can't seem to get any needed information.

This is the code to GET information, API pertains to points for being in the server gained per minute.
Code:
  var %sw sockwrite -n points
  %sw GET /1/fans/aeonpsych/points HTTP/1.1
  %sw x-api-key: <api-key-removed>
  %sw Content-Type: application/x-www-form-urlencoded
  %sw Accept: application/json
  %sw Host: <host-removed>:443
  %sw Connection: close
  %sw $crlf




When I use a web based request for the api call, the response is:
Code:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,x-api-key
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Thu, 12 Jan 2017 09:00:45 GMT
Server: nginx/1.4.6 (Ubuntu)
X-Content-Type-Options: nosniff
Content-Length: 108
Connection: Close

{"loyalty":{"fan":"aeon","total_points":64,"current_points":64,"updated_at":"2017-01-12T09:00:00.000Z"}}




but when I make the request within irc client, the response is only the headers of the response (not any of the body), and I can't get the points data from such:
Code:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,x-api-key
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Thu, 12 Jan 2017 09:57:35 GMT
Server: nginx/1.4.6 (Ubuntu)
X-Content-Type-Options: nosniff
Content-Length: 115
Connection: Close





The POST request I use to add/subtract points works from both within the irc client and web client. The amount:3 is the total to add or subtract):
Code:
var %sw sockwrite -n addpoints
  %sw POST /1/fans/aeon/points/bonus HTTP/1.1
  %sw x-api-key: <api-key-removed>
  %sw Content-Length: 14
  %sw Content-Type: application/x-www-form-urlencoded
  %sw Accept: application/json
  %sw Host: <host-removed>:443
  %sw Connection: close
  %sw $crlf

  %sw {"amount": 3}


The assistance I am looking for is how can I get the points data from the socket/request? It comes out great when I make the call from a web client, but not from within irc.


Posted By: Wims Re: Seeking Assistance w/ Sockets - 12/01/17 12:08 PM
Hello, you forgot to include the most important part of what is needed to help you: the on sockread event.
An easy guess is that you are only reading a line with /sockread %var (which does not read anything if there's no line ending sequence) and the JSON data is on one big line with no line ending sequence.
More about how to deal with this and how to properly read from on sockread in general here.
If you are dealing with JSON, you may want to look for a JSON parser
Posted By: AeonPsych Re: Seeking Assistance w/ Sockets - 12/01/17 06:37 PM
this is the code I am using for reading from the socket:
Code:
if ($sockerr) { sockclose $sockname }
  var %streamodata
  sockread %streamodata

  tokenize 32 %streamodata

  echo -a %streamodata



Using this, only prints out the response headers, exactly as posted, originally. I'll take a look at that, thanks.




Edit:
I did a quick test by adding the -f switch to force read... It did end up reading in the full body this time, so that does seem to be my issue.

I do have a json parser, but when I use it, it also does not return any value from the data. It's been awhile since I used the json parser, so maybe I am just drawing blanks and forgetting how to use it, but I've tried running this code through the parser:

Code:
JSONOpen -uw points https://<url-removed>
  JSONURLMethod points GET
  JSONUrlHeader points Accept application/json
  JSONUrlHeader points Host <host-removed>:443
  JSONUrlHeader points Connection close
  JSONUrlHeader points x-api-key <api-key-removed>
  JSONUrlHeader points Content-Type application/x-www-form-urlencoded 

echo -a Result1: $json(points, current_points)


The output is just "Result1: "
Posted By: FroggieDaFrog Re: Seeking Assistance w/ Sockets - 12/01/17 09:07 PM
Dependant on which version of my json parser you are using -- you can check with: //echo -a $JSONVersion -- the JSON request should look like one of the following, assume the returned body is similar to the following(line breaks added for readability):
Code:
{
  "loyalty":{
    "fan":"aeon",
    "total_points":64,
    "current_points":64,
    "updated_at":"2017-01-12T09:00:00.000Z"
  }
}



v0.2.4x
Code:
alias example {
  JSONOpen -duw points <url>
  JSONUrlMethod points GET
  JSONUrlHeader points x-api-key <api-key-removed>
  ;; These headers are auto-set by the json parser
  ;;   Host: <host-removed>:443
  ;;   Connection: close
  ;; This header isn't needed as you aren't sending any data
  ;;   Content-Type application/x-www-form-urlencoded
  JSONUrlGet points

  echo -a Fan: $JSON(points, loyalty, fan)
  echo -a Total: $JSON(points, loyalty, total_points)
  echo -a Current: $JSON(points, loyalty, current_points)
  echo -a Updated: $JSON(points, loyalty, updated_at)
}


v1.0.x - (Recommended)
Code:
alias example {
  JSONOpen -duw points <url>
  JSONHttpMethod points GET
  JSONHttpHeader points x-api-key <api-key-removed>
  ;; These headers are auto-set by the json parser
  ;;   Host: <host-removed>:443
  ;;   Connection: close
  ;; This header isn't needed as you aren't sending any data
  ;;   Content-Type application/x-www-form-urlencoded
  JSONHttpFetch points

  echo -a Fan: $JSON(points, loyalty, fan).value
  echo -a Total: $JSON(points, loyalty, total_points).value
  echo -a Current: $JSON(points, loyalty, current_points).value
  echo -a Updated: $JSON(points, loyalty, updated_at).value
}


Posted By: AeonPsych Re: Seeking Assistance w/ Sockets - 12/01/17 09:31 PM
EDIT: Alright, so with FroggieDaFrog's assistance, I was able to finally narrow, and find the problem. It was an open JSON handler that was not closing, and it had a name of the new handler I was trying to use... /jsonlist /jsonclose and now it works like it should.



just check version. Appears I am using the older version: "JSONForMirc v.0.2.4"

I also updated my code to better match what you gave:
Code:
  JSONOpen -duw points <url>
  JSONURLMethod points GET
  JSONUrlHeader points x-api-key <key-removed>
  JSONUrlGet points

  echo -a fan: $json(points, loyalty, fan)
  echo -a Total: $JSON(points, loyalty, total_points)
  echo -a Current: $JSON(points, loyalty, current_points)
  echo -a Updated: $JSON(points, loyalty, updated_at)



output is still nothing for each of the values. I thought I was going in the right direction, seeing as how I was missing the "JSONUrlGet points" but it did not seem to change anything.


Note: I was able to get the data I needed through normal sockets using the suggested tips without using json parser, but it was a pain having to tokenize sections of the response, and then even substring. Would be nice to have the json parser working!
Posted By: Wims Re: Seeking Assistance w/ Sockets - 13/01/17 01:37 PM
Using /sockread -f inside on sockread isn't what you need. Please read the whole tutorial about how to properly read from a socket, you must not use -f inside on sockread, you should rather use it from on sockclose.
Posted By: OrFeAsGr Re: Seeking Assistance w/ Sockets - 13/01/17 01:50 PM
In my humble opinion an easy solution to get the body would be to include the Connection: Close header in the sockopen event
Code:
sockwrite -nt $sockname Connection: Close

And use, as said by Wims, the sockread -f in the sockclose event..
Posted By: FroggieDaFrog Re: Seeking Assistance w/ Sockets - 13/01/17 02:18 PM
This has been fixed; He forgot to close the json handler in his original test which caused subsequent testing to fail. We troubleshot it and have his script working.
Posted By: AeonPsych Re: Seeking Assistance w/ Sockets - 14/01/17 01:25 AM
while yes, I shouldn't be using the -f switch in the manner I did, I did say I put it in as a quick fix/test to force read the entire buffer. After the headers, in the response, there is a line break. The reader assumes that is the end of the response, and stops reading. That was the initial problem, why I wasn't getting the body of the response, and using the -f switch as a quick test worked in that manner.


As for the JSON part, Froggie was correct, as I also mentioned in my previous post edit. The JSON wasn't returning any information due to an unclosed handler with the same name.

Both JSON and using sockets works correctly now.
© mIRC Discussion Forums