Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket hang up error occurs when redirected after submitting FormData #1271

Closed
2 tasks done
prfss opened this issue May 16, 2020 · 9 comments
Closed
2 tasks done

Socket hang up error occurs when redirected after submitting FormData #1271

prfss opened this issue May 16, 2020 · 9 comments

Comments

@prfss
Copy link

prfss commented May 16, 2020

  • Got version: 11.3.1
  • Node.js version: 14.2.0 (12.16.3)
  • OS & version: Windows10 (Ubuntu 18.04 on WSL)

Code to reproduce

import got from "got";
import FormData from "form-data";

(async function f() {
    try {
        const body = new FormData();
        body.append("aaa", "bbb");
        const res = await got.post(`http://httpstat.us/302`, { body });
    } catch (err) {
        console.log(err);
    }
})();
internal/streams/legacy.js:61
      throw er; // Unhandled stream error in pipe.
      ^

Error: socket hang up
    at connResetException (internal/errors.js:608:14)
    at TLSSocket.socketOnEnd (_http_client.js:453:23)
    at TLSSocket.emit (events.js:322:22)
    at endReadableNT (_stream_readable.js:1187:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'ECONNRESET'
}

Additional info

Similar result is produced with the local flask server (no error message, simply get stucked)

from flask import Flask, request, redirect, url_for
app = Flask(__name__)


@app.route('/', methods=["GET", "POST"])
def index():
    return "hello"


@app.route('/redirect', methods=["POST"])
def redirect_to_index():
    return redirect(url_for("index"))


if __name__ == '__main__':
    app.run(debug=True)

Checklist

  • I have read the documentation.
  • I have tried my code with the latest version of Node.js and Got.
@Giotino
Copy link
Collaborator

Giotino commented May 16, 2020

This bug is due to the fact that FormData is a stream-like object.
It's read until the end for the first request. Then, when it comes the redirect (second request), it's already at the end, so no body is transmitted (while the server is waiting for it).

@Giotino
Copy link
Collaborator

Giotino commented May 16, 2020

@szmarczak
One solution could be calling await this._finalizeBody(); right before sending the body and making the user change (re-initialize) the body in the beforeRedirect (or beforeRequest) hook, but, to me, it seems a little tricky.

Another solution could be reading all the stream a single time and using it as a Buffer when making requests, but this is going to break the stream feature (big file are going to fill the RAM).

@szmarczak
Copy link
Collaborator

@Giotino is right. It is not a bug, it's the intended behavior. If you want to use method rewriting, please use get-stream and pass the output to the body option.

@prfss
Copy link
Author

prfss commented May 17, 2020

Thank you for your quick response. Giving body: await getStream(body) solves the problem.
By the way, how to remove the body (and re-calculate the headers) in the second request when methodRewriting: false or 303 is returned ?

@szmarczak
Copy link
Collaborator

how to remove the body (and re-calculate the headers) in the second request when methodRewriting: false

What do you mean? The body is removed if you disable method rewriting.

@proton-ab
Copy link

proton-ab commented Jun 8, 2020

@Giotino @szmarczak Using methodRewriting: false does not seem to work for me, it still causes crash. Only setting followRedirect: false helped.

Perhaps the code still tries to read FormData but simply not sending it despite that?

@ghost
Copy link

ghost commented Dec 18, 2020

I have the same issue. Using get-stream results in a HTTP 413 Request Entity Too Large error. However, curl is able to POST the same file without issues. Any ideas on how to fix this?

@Giotino
Copy link
Collaborator

Giotino commented Dec 21, 2020

I have the same issue. Using get-stream results in a HTTP 413 Request Entity Too Large error. However, curl is able to POST the same file without issues. Any ideas on how to fix this?

When using get-stream on a form data are you also setting the boundary header?

@makeable
Copy link

makeable commented Nov 27, 2023

Why is got trying to POST to the redirected URL? Is this really expected behaviour?

Historically user agents (e.g. all browsers) redirected POST to GET and so the spec was updated accordingly, yet got is redirecting POST to POST:
https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4-3.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants