0 votes

it is possible to upload file in godot using HTTPRequest node or I need use HTTPClient and do everything from scratch building raw http multipart request?

in Engine by (88 points)

For small files, you could send a POST request using HTTPRequest and pass the binary data converted to Base64 in the request data using Marshalls.raw_to_base64(array: PoolByteArray). (This will increase the payload size by at least 33%.)

Thanks @Callinou for for answer, but I have figured out how to make it with multipart form-data

1 Answer

+1 vote
Best answer

I have found solution myself, here you are, this code is sending directly icon.png from res:// code doesn't processing resposne, just send request as multipart form-data by HTTPClient.raw_request, as server backend I am using Rails with JSON format endpoint /images

func _ready():
    var file = File.new()
    file.open('res://icon.png', File.READ)
    var file_content = file.get_buffer(file.get_len())

    var body = PoolByteArray()
    body.append_array("\r\n--WebKitFormBoundaryePkpFF7tjBAqx29L\r\n".to_utf8())
    body.append_array("Content-Disposition: form-data; name=\"image\"; filename=\"icon.png\"\r\n".to_utf8())
    body.append_array("Content-Type: image/png\r\n\r\n".to_utf8())
    body.append_array(file_content)
    body.append_array("\r\n--WebKitFormBoundaryePkpFF7tjBAqx29L--\r\n".to_utf8())

    var headers = [
        "Content-Type: multipart/form-data;boundary=\"WebKitFormBoundaryePkpFF7tjBAqx29L\""
    ]
    var http = HTTPClient.new()
    http.connect_to_host("http://localhost", 3000, false)

    while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING:
        http.poll()
        OS.delay_msec(500)

    assert(http.get_status() == HTTPClient.STATUS_CONNECTED) # Could not connect

    var err = http.request_raw(HTTPClient.METHOD_POST, "/images" , headers, body)

    assert(err == OK) # Make sure all is OK.

    while http.get_status() == HTTPClient.STATUS_REQUESTING:
        # Keep polling for as long as the request is being processed.
        http.poll()
        if not OS.has_feature("web"):
            OS.delay_msec(500)
        else:
            yield(Engine.get_main_loop(), "idle_frame")
by (88 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 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 webmaster@godotengine.org with your username.