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'
}
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)
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).
@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).
@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.
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 ?
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.
@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?
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?
I have the same issue. Using
get-streamresults 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?
Most helpful comment
This bug is due to the fact that
FormDatais 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).