Skip to content

Instantly share code, notes, and snippets.

@Windastella
Last active December 12, 2019 06:54
Show Gist options
  • Save Windastella/21c0887fd65df1889648649c735a135b to your computer and use it in GitHub Desktop.
Save Windastella/21c0887fd65df1889648649c735a135b to your computer and use it in GitHub Desktop.
A HTTP Request class with Async using Thread suitable for REST API implementation
# Modified from http://codetuto.com/2015/05/using-httpclient-in-godot/
# Added POST and Optional Header Perimeter
extends Node
var reqlist = []
class request:
var t
var params
var finished = false
var parent
signal loading(s,l)
signal loaded(r)
func _init(p, param):
params = param
parent = p
t = Thread.new()
t.start(self,"_load",params)
func _load(params):
var err = 0
var http = HTTPClient.new()
err = http.connect(params.domain,params.port,params.ssl)
if err:
print('Connection Err:',err)
return
while(http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING):
http.poll()
OS.delay_msec(100)
var headers = StringArray(["User-Agent: Pirulo/1.0 (Godot)", "Accept:*/*"])
headers.append_array(StringArray(params.header))
headers = Array(headers)
if params.method == "get":
err = http.request(HTTPClient.METHOD_GET,params.url,headers)
elif params.method =="post":
err = http.request(HTTPClient.METHOD_POST,params.url,headers,params.data)
if err:
print('Request Error:',err)
return
while (http.get_status() == HTTPClient.STATUS_REQUESTING):
http.poll()
OS.delay_msec(500)
if http.get_status() == http.STATUS_CONNECTION_ERROR:
print('Request Error:', http.STATUS_CONNECTION_ERROR )
return
var rb = RawArray()
if(http.has_response()):
var headers = http.get_response_headers_as_dictionary()
while(http.get_status()==HTTPClient.STATUS_BODY):
http.poll()
var chunk = http.read_response_body_chunk()
if(chunk.size()==0):
OS.delay_usec(100)
else:
rb = rb+chunk
call_deferred("_send_loading_signal",rb.size(),http.get_response_body_length())
call_deferred("_send_loaded_signal")
http.close()
return rb.get_string_from_utf8()
func _send_loading_signal(size,length):
emit_signal("loading",size,length)
func _send_loaded_signal():
var result = t.wait_to_finish()
emit_signal("loaded",result)
parent.erase_req(self)
func get(domain,url,port,ssl, header=[]):
var req = request.new(self,{method="get",domain=domain,url=url,port=port,ssl=ssl,header=header})
reqlist.push_front(req)
return req
func post(domain,url,port,ssl,data, header=[]):
var req = request.new(self,{method="post",domain=domain,url=url,port=port,ssl=ssl,data=data,header=header})
reqlist.push_front(req)
return req
func check_req(req):
if reqlist.find(req) != -1:
return true
return false
func erase_req(req):
reqlist.erase(req)
extends Node2D
var http = load('res://http_request.gd')
onready var req = http.new()
func _on_loading(s, l):
print('size=',s,':length=',l)
func _on_loaded(r):
print(r)
func _on_Button_pressed():
var res = req.post('http://localhost','/index.php?id=1',8181,false,["Content-Type:application/json"])
res.connect("loading",self,"_on_loading")
res.connect("loaded",self,"_on_loaded")
extends Node2D
var http = load('res://http_request.gd')
onready var req = http.new()
func _on_loading(s, l):
print('size=',s,':length=',l)
func _on_loaded(r):
print(r)
func _on_Button_pressed():
var res = req.post('http://localhost','/',8181,false,'{"action":"getposts"}',["Content-Type:application/json"])
res.connect("loading",self,"_on_loading")
res.connect("loaded",self,"_on_loaded")
@Windastella
Copy link
Author

You're not sending the correct datatype. You sent a string 'bodyGetFav' instead of a JSON formatted string of dictionary bodyGetFav.
Use var res = req.post('http://myurl','/myapi',80,false,bodyGetFav.to_json(),["Content-Type:application/json"]) if your api required json data.

For Url encoded data your best bet is to write your own function that converts a dictionary into Url encoded string because Godot had no built-in Url encoding and decoding function at the moment.

@arthurtemple
Copy link

Hi,

I updated your awesome HTTP class for use in bleeding-edge godot master in this fork.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment