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
Stream multipart/related is broken: missing chunked encoding for default GET
method.
#1271
Comments
This is what CouchDB receives when the Headers: [{'Connection',"keep-alive"},
{'Content-Type',"multipart/related; boundary=ab95e194-58df-42f2-943e-a680489951eb"},
{'Host',"localhost:5984"},
{'Transfer-Encoding',"chunked"}] This is what the test server in { host: 'localhost:8080',
accept: 'application/json',
'content-type': 'multipart/related; boundary=70e7cc0f-f8dd-4d9b-98c3-0541f367f881',
connection: 'keep-alive',
'transfer-encoding': 'chunked' } Passing this options multipart: {
chunked: false,
data: [
body: fs.readFileSync('cat.png')
]
} Sends this to CouchDB Headers: [{'Connection',"keep-alive"},
{'Content-Length',"22272"},
{'Content-Type',"multipart/related; boundary=082ea6fe-6c72-4bf0-bb29-943828397c12"},
{'Host',"localhost:5984"}] and this inside the tests { host: 'localhost:8080',
'content-type': 'multipart/related; boundary=9af9e209-5e35-4f39-9098-34b856644333',
'content-length': '172',
connection: 'keep-alive' } |
Here is my test: var request = require('request');
var source = 'https://registry.npmjs.org/';
var target = 'http://requestb.in/1lkya2s1';
request({
url: target,
qs: { test: 3 },
multipart:[
{ body: 'test' },
{ body: request(source) }
]
}, function (error, response, body) {
console.log('response', error, body);
}).on('error', function (error) {
console.log('error:', error);
}); http://requestb.in/1lkya2s1?inspect |
Are you trying to make a |
@triccardi-systran take a look at this http://requestb.in/rlstv7rl?inspect The |
OK, it works with |
GET
method.
@triccardi-systran from RFC 7231 (HTTP/1.1): Semantics and Content:
and
Both of these conditions are violated if you're sending a request body, so GET requests must not have bodies. I don't think there is still an issue here, let us know if you disagree. |
@nylen I know some think GET requests cannot have body (and thus no multipart body, or chunked encoding), but I really don't see an contradiction between what you quoted from the RFC and the following scenario: Sending a large request doesn't necessarily means we will modify the state of the server. Regardless of the chunk encoding, prior to 2.47.0 we could send multipart/related GET requests (albeit only for String & Buffers parts), but now |
@triccardi-systran you can do the same in v2.48 (use a multipart: {
chunked: false,
data: [
{
'content-type': 'application/json',
body: JSON.stringify({
_attachments: {
'cat.png': {
follows: true,
content_type: 'image/png',
length: 22025
}
}
})
},
{
body: fs.readFileSync(image)
}
]
} http://requestb.in/1joavk71?inspect Besides that the current multipart implementation always set So what you are suggesting is to either use combined-stream or the old implementation based on body type? What happens if I want to use chunked encoding always? Isn't the current implementation better - where you explicitly specify what you want to use (even though it defaults to chunked)? |
@triccardi-systran as for using Here is what I'm getting back from requestb.in doing so <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
html, body, iframe { margin: 0; padding: 0; height: 100%; }
iframe { display: block; width: 100%; border: none; }
</style>
<title>Application Error</title>
</head>
<body>
<iframe src="//s3.amazonaws.com/heroku_pages/error.html">
<p>Application Error</p>
</iframe>
</body>
</html> |
The other way around is to check for chunked && options.method == 'GET' and throw an error saying that 'Get requests are not allowed using transfer-encoding chunked' This will effectively eliminate the source of annoyance in this thread. |
@simov I know I can toggle the old implementation, but what I said is that old code worked on old Then, I suggest to guarantee chunk encoding whenever we use Otherwise, If you don't want to support |
Yep that's the suggestion from my second comment. We should either throw an error or send a correct chunked request at all time. Let's see if anyone else have something to add, also I want my #1275 PR reviewed first, because I'm going to work on top of that. Once this one is in, I'll add the tests for |
@simov perfect, thanks for your help! I expect no objection to this, because if someone doesn't want to send |
@triccardi-systran fair enough, I agree that your example is unusual but valid according to the RFC. so the proposed solution to always set |
Great, I'll push later today. |
Issue #1185 implemented
multipart/related
stream support even for streams of unknown length. This means using HTTPTransfer-Encoding: chunked
because the other transfer encoding (the default one) requires setting theContent-Length
header beforehand.HTTP chunked encoding is not implemented in current
request
master:Using wireshark I see that currently neither the
content-length
nor thetransfer-encoding: chunked
is set.The combined-stream is part of the solution, but it needs to be piped to a chunk encoder before sending it to the socket. I don't know what can be done by node.js itself (with its http module).
This means that current multipart/related requests are broken HTTP requests since
request
2.47.0.(Tested with node v0.10.18 & v0.10.33 on 2.48.0 & current master)
I don't understand how and why for some people it did send chunked encoded requests (it seems to be the case here: #1243).
The text was updated successfully, but these errors were encountered: