0 votes

I have a basic python server like this:

from http.server import HTTPServer, BaseHTTPRequestHandler
import json

class ServerHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        print("got post")
        content_len = int(self.headers.get('Content-Length'))
        print(content_len)
        post_body = json.loads(self.rfile.read(content_len))
        self.send_response(200)
        self.send_header('Content-type',"application/json")
        self.end_headers()

        self.wfile.write(b'{"message":"General Kenobi"}')


server= HTTPServer(('',6000),ServerHandler)
server.serve_forever()
print("server started...")

and I'm sending my post request from godot (gdscript) like this:

tool
extends HTTPRequest

export (bool) var send_req_btn = false setget send_req

func send_req(val):
    if(val):
        # Create an HTTP request node and connect its completion signal.
        var body = to_json({"message": "Hello there"})
        var error=self.request("http://localhost:6000", ['Content-Length:'+str(body.length())], true, HTTPClient.METHOD_POST, body)
        if error != OK:
            push_error("An error occurred in the HTTP request.")

func _on_HTTPRequest_request_completed(result, response_code, headers, body):
    print("result: ",result)
    print("response_code: ",response_code)
    print("headers:",headers)
    print("body:",body)

but it prints this as response in godot

result: 0
response_code: 200
headers:[Server: BaseHTTP/0.6 Python/3.10.4, Date: Thu, 22 Sep 2022 05:47:57 GMT, Content-type: application/json]
body:[]

why can't I get the body of the response sent back by python?

Godot version v3.5.stable.mono
in Engine by (65 points)

1 Answer

0 votes
Best answer

Figured it out!
I had to set Content-Length in the header, that sneaky little bastard!

python server:

from http.server import HTTPServer, BaseHTTPRequestHandler
import json

class ServerHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        print("got post")
        content_len = int(self.headers.get('Content-Length'))
        post_body = json.loads(self.rfile.read(content_len))

        res=b'{"message":"General Kenobi"}'
        self.send_response(200)
        self.send_header("Content-Length", str(len(res)))
        self.end_headers()

        self.wfile.write(res)

server= HTTPServer(('',6000),ServerHandler)
server.serve_forever() print("server started...")

Godot:

tool
extends HTTPRequest

export (bool) var send_req_btn = false setget send_req

func send_req(val):
    if(val):
        var body = to_json({"message": "Hello there"})
        var error=self.request("http://localhost:6000", ['Content-Length:'+str(body.length())], true, HTTPClient.METHOD_POST, body)
        if error != OK:
            push_error("An error occurred in the HTTP request.")

func _on_HTTPRequest_request_completed(result, response_code, headers, body):
    print("result: ",result)
    print("response_code: ",response_code)
    print("headers:",headers)
    print("body:",body)
    print("body:",JSON.parse(body.get_string_from_utf8()).result["message"])

Response printed in godot:

result: 0
response_code: 200
headers:[Server: BaseHTTP/0.6 Python/3.10.4, Date: Thu, 22 Sep 2022 20:10:24 GMT, Content-Length: 28]
body:[123, 34, 109, 101, 115, 115, 97, 103, 101, 34, 58, 34, 71, 101, 110, 101, 114, 97, 108, 32, 75, 101, 110, 111, 98, 105, 34, 125]
body:General Kenobi
by (65 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.