firebase / firebase/firebase-tools
chunked/streaming response disparity between functions emulator and deployment
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.3k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 84
Description
### [REQUIRED] Environment info
**firebase-tools:** 9.4.0
**Platform:** linux
### [REQUIRED] Test case
#### 1. Chunked Transfer-Encoding
```js
const sleep = (t=2) => new Promise(r => setTimeout(r, t * 1000));
https.onRequest(async (req, res) => {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.setHeader('Transfer-Encoding', 'chunked');
res.write('one');
await sleep();
res.write('two');
res.end();
});
```
#### 2. Readable streams
```js
import {Readable} from 'stream';
https.onRequest(async (req, res) => {
const pageChunks = ['one', 'two'];
const pageStream = new Readable({
async read() {
if (!pageChunks.length) {
pageStream.push(null);
} else {
await sleep();
pageStream.push(pageChunks.shift());
}
}
});
pageStream.pipe(res);
});
```
### [REQUIRED] Steps to reproduce
1. Start firebase function emulator
2. Browse to function url or `curl --raw $FUNCTION_URL`
### [REQUIRED] Expected behavior
Chunked/Streaming response or progressive server side rendering is not supported when the function is deployed under GCP. In case of (1), the `Transfer-Encoding` header is stripped away. The expected behaviour would be for the emulator to replicate the same behaviour as GCP, to avoid confusion where it's possible to develop something based on this technique and then learn it's not supported once deploying to staging/production.
### [REQUIRED] Actual behaviour
Emulator responses work as expected in a NodeJS environment, but do not follow the behaviour on GCP.
#### Firebase emulator
```sh
curl --raw http://localhost:5001/projectId/region/streamTest
one
3
[waits for 2 seconds]
two
3
```
#### GCP
```
curl --raw https://region-projectId.cloudfunctions.net/streamTest
[waits for 2 seconds]
onetwo
```
Contributor guide
Research direction
Start at the functions emulator's HTTP response handling and reproduce both examples with curl --raw: the Transfer-Encoding case and the Readable stream case. Compare emulator output with the documented GCP output; done means the emulator consistently reflects the deployment behavior for both cases, with verification covering the observed delays and response body.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- gcp, nodejs, typescript
- Domain
- backend, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100