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

Add response header X-Uncompressed-Content-Length for JSON API #1277

Merged
merged 1 commit into from
Mar 24, 2024

Conversation

Zwyx
Copy link
Contributor

@Zwyx Zwyx commented Mar 24, 2024

Hope you don't mind that I create a PR before discussing the subject. This is such a small change than showing it is easier than explaining it 🙂

Add response header X-Uncompressed-Content-Length for JSON API

Because the response from the API is PHP output, the usual Content-Length header is absent.

This custom header technique allows the client to know the total length of the data being received, in order to display a progress indicator.

Here's a code example with XMLHttpRequest:

xhr.addEventListener("progress", (e) => {
	if (e.lengthComputable) {
		onDownloadProgress({
			loaded: e.loaded,
			total: e.total,
		});
	} else {
		const uncompressedContentLength = xhr.getResponseHeader(
			"X-Uncompressed-Content-Length",
		);

		if (uncompressedContentLength) {
			onDownloadProgress({
				loaded: e.loaded,
				total: Number(uncompressedContentLength),
			});
		}
	}
});

Notes:

  • Fetch can be used as well (only reason I use XMLHttpRequest is because fetch doesn't allow to track the progress of uploaded data (when creating a paste); whereas XMLHttpRequest does).
  • e.loaded can be different between browsers; Firefox reports the length of the compressed data, Chrome reports the length of uncompressed data (see Clarify if ProgressEvent.loaded should indicate the size of compress, or uncompressed, data whatwg/xhr#388). A workaround for this is to manually set our progress indicator to 100% when the request finishes.
Because the response from the API is PHP output, the usual `Content-Length` header is absent.

This [custom header technique](https://stackoverflow.com/questions/15097712/how-can-i-use-deflated-gzipped-content-with-an-xhr-onprogress-function/32799706#32799706) allows the client to know the total length of the data being received, in order to display a progress indicator.

Here's a code example with `XMLHttpRequest`:


```
xhr.addEventListener("progress", (e) => {
	if (e.lengthComputable) {
		onDownloadProgress({
			loaded: e.loaded,
			total: e.total,
		});
	} else {
		const uncompressedContentLength = xhr.getResponseHeader(
			"X-Uncompressed-Content-Length",
		);

		if (uncompressedContentLength) {
			onDownloadProgress({
				loaded: e.loaded,
				total: Number(uncompressedContentLength),
			});
		}
	}
});
```

Notes:
- `Fetch` can be used as well (only reason I use `XMLHttpRequest` is because `fetch` doesn't allow to track the progress of uploaded data (when creating a paste); whereas `XMLHttpRequest` does).
- `e.loaded` can be different between browsers; Firefox reports the length of the compressed data, Chrome reports the length of uncompressed data (see whatwg/xhr#388). A workaround for this is to manually set our progress indicator to 100% when the request finishes.
Copy link
Contributor

@elrido elrido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: Sorry, misclicked. Let me try again.

@elrido elrido merged commit b75aee6 into PrivateBin:master Mar 24, 2024
3 checks passed
@rugk
Copy link
Member

rugk commented Mar 25, 2024

That is nice, but as you indicated the frontend equivalent to this still needs to be added then, if I see that correctly?

If so, that would solve #369 / #9

@Zwyx
Copy link
Contributor Author

Zwyx commented Mar 25, 2024

This is only for the JSON API, and for downloading a paste 😉

I think we could track the upload progress easily, with XMLHttpRequest (although, as mentioned in the issues, we might want to show more steps, like encryption and compression), but this PR won't help us with that.

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