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

"Accept-Encoding" inserted into http requests headers #5043

Closed
iidebyo opened this issue Sep 12, 2023 · 3 comments
Closed

"Accept-Encoding" inserted into http requests headers #5043

iidebyo opened this issue Sep 12, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@iidebyo
Copy link
Contributor

iidebyo commented Sep 12, 2023

What version of Bun is running?

1.0.0+822a00c4d508b54f650933a73ca5f4a3af9a7983

What platform is your computer?

Linux 5.15.90.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

import h from 'node:http'
import z from 'node:zlib'
h.get('http://example.com/', async r => {
  var d = []
  var f = () => {
    console.log(z.gunzipSync(Buffer.concat(d)).toString())
    console.log(Buffer.concat(d).length)
  }
  for await (const c of r) {
    d.push(c)
  }
  f()
})

What is the expected behavior?

An error should appear such as: Error: incorrect header check.

What do you see instead?

html from http://example.com

Additional information

bun/src/http_client_async.zig

Lines 2125 to 2128 in 8615b8a

if (!override_accept_encoding) {
request_headers_buf[header_count] = accept_encoding_header;
header_count += 1;
}

@iidebyo iidebyo added the bug Something isn't working label Sep 12, 2023
@Axiean
Copy link

Axiean commented Sep 12, 2023

The behavior you are observing is related to how the zlib.gunzipSync method is used in your code and how it handles the response from the HTTP request.

In your code, you are making an HTTP request to http://example.com/ and attempting to decode the response using zlib.gunzipSync. However, this method is synchronous and expects the entire compressed data to be available before it can be decompressed.

When you use for await (const c of r) to iterate over the response data stream, you are processing the response incrementally, but zlib.gunzipSync doesn't support this incremental processing. It expects the complete compressed data in one go.

As a result, when you call zlib.gunzipSync(Buffer.concat(d)), it attempts to decompress the concatenated data, which may not be a complete gzip stream, leading to the behavior you described.

To handle compressed responses from an HTTP request in a more appropriate manner, you should use asynchronous decompression and handle the response incrementally. You can use the zlib.gunzip function from the 'zlib' module instead of zlib.gunzipSync. Here's an example of how you can modify your code:

import http from 'node:http';
import zlib from 'node:zlib';

const req = http.get('http://example.com/', (res) => {
  const gunzip = zlib.createGunzip();
  res.pipe(gunzip);

  let data = '';

  gunzip.on('data', (chunk) => {
    data += chunk;
  });

  gunzip.on('end', () => {
    console.log(data);
    console.log(data.length);
  });
});

req.end();

In this example, we create a gunzip stream using zlib.createGunzip() and pipe the response data through it. The data is then accumulated incrementally in the data variable. This approach allows for proper handling of gzip-compressed responses.

@iidebyo
Copy link
Contributor Author

iidebyo commented Sep 12, 2023

Please take another look at expected and observed behavior.

@iidebyo
Copy link
Contributor Author

iidebyo commented Sep 15, 2023

fixed by #5057

@iidebyo iidebyo closed this as completed Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants