Is there a way to disable byte-range requests on the client side? - http

I understand that one can set Accept-Ranges: none on the server to advise the client not to attempt a range request.
I am wondering if there is a way to tell a browser not to attempt a range request without having to make any changes on the server.
For instance, is there a setting in Chrome or Firefox that I can toggle to deter my browser from making range requests?

You answered the question in the first sentence.
The relevant RFC is 7233, Hypertext Transfer Protocol (HTTP/1.1): Range Requests:
2.3. Accept-Ranges
A client MAY generate
range requests without having received this header field for the
resource involved.
A server that does not support any kind of range request for the
target resource MAY send
Accept-Ranges: none
to advise the client not to attempt a range request.
If you mean you want to know how to disable range requests in a browser altogether, consult the specific browser's documentation. A quick web search yielded no options for me to do this for common browsers.

Related

How to send HTTP Headers during/after HTTP Body stream? Is there spec work on this?

Today, HTTP headers all need to be sent before a single bit of HTTP body is sent to the browser.
This is especially problematic with new technologies such as React 18 Streaming where certain headers, such as caching headers and 103 Early Hints, can be determined with certainty only at the end of the HTTP stream. Ideally these late headers would be sent to the browser just before ending the stream.
Are there efforts from spec working groups or browser vendors to enable headers to be sent during/after the HTTP body?
After doing research, it seems that there is no spec work about this, but I wonder if there is a browser vendor working on this? (Some browser folks are active here on StackOverflow.)
Context: I'm the author of vite-plugin-ssr and react-streaming.
There is a specification for Trailer fields for use with Chunked Encoding (Http 1.1, https://httpwg.org/specs/rfc7230.html#header.trailer).
The HTTP2 spec (which does not support Chunked Encoding) directly allows for a headers frame following the Data frames that contain the http body https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.
Library support may vary as most http libraries attempt to abstract away the differences in the underlying protocols. In Javascript you will be interested in enabling trailing headers in the cross-browser standard fetch API. The MDN docs suggest that support is coming with reference to a trailers field on the Response object: https://developer.mozilla.org/en-US/docs/Web/API/Response.

Can max-stale be set in the response header?

Can max-stale be set in the response header for it to be used by the request on the client side? The documentation here - Cache-Control: Syntax, specifically the "Cache response directives" section makes it appear as if max-stale is not part of the response header. Is this only used by client to make decision how much longer it will use the stale resource and server/application has no say in it? If so, what can be set on the response to simulate the functionality of max-stale?
No max-stale cannot be used in the response. It’s meant to be used by the client to override the cache defaults. “Gimme this resource even if it’s technically a bit past it’s expiry date”. It would be used if there is a caching server between the client and the origin server.
To be honest, in my experience, request cache-control headers are rarely used, except to force refresh all the way back to origin server (max-age=0) for example when doing a “hard reload” with dev tools open. I’ve never seen a real world instance of max-stale as far as I can recall.
There is not equivalent on a response header. If a server is happy for a resource to be used for longer then it should just increase the max-age amount.
There is the stale-while-revalidate response option which allows a stale resource to be used for a limited period, to allow a quick reload of the page, while the browser checks and downloads a new version in the background for the next time. However support of it is limited at this time as shown at the bottom of that page you linked.
Simulating the behaviour of max-stale on the response does not really make much sense. Server owns the resources and has an understanding of how those resources change over time. Server has to decide how critical a resource is and if it is ok for it be served stale. Also decide on some reasonable time limits for the resource to be re-validated such that the clients get fresh data most of the time. It is a balancing act on the server side. Too strict the setting, you are overloading your server with requests and client with network traffic. Too loose, your clients see an old representation.
A client can use max-stale to avoid any re-validation and get what is in the cache. you don't want to generate network requests unless it is really necessary. for example must-revalidate overrides max-stale so if the response has that header, even with max-stale you will hit the origin server no matter. Similarly with no-cache and no-store. So in that sense, server has a say in it. It can identify resources that CANNOT be used stale, even with max-stale and marks with the appropriate header.

HTTP1.1 to HTTP/2: what about headers?

In HTTP 1.1, the status line was
scheme/version code reason
HTTP/1.1 200 OK
I see :scheme and :status headers in the HPACK spec. I don't however see anything for version or reason? Is there not one?
In a request in HTTP 1.1, the request line was
method uri scheme/version
POST http://myhost.com HTTP/1.1
I see :method and I see :path, which I think is just a relative path, which is not the same as the full absolute path (and since Chrome and Firefox are pushing HTTPS for HTTP/2, this may make sense). I do not see version header though.
Is there a version header? Or is it seen that this will always be known before the protocol decision such that it is not really needed?
What about reason codes? Is it assumed these are pretty constant so that goes away (I am guessing here)?
In HTTP/1, the version token was needed to differentiate HTTP/1.0 from HTTP/1.1, since they had the same wire representation, but were supporting different features.
For example, a client declaring HTTP/1.1 implicitly tells the server that it supports persistent connections and content chunking.
With HTTP/2, the protocol version is negotiated.
In clear-text HTTP/2, the Upgrade header reports h2c, where the 2 means version 2 of the protocol. I imagine that for HTTP/3 the token will change to h3c.
Similarly happens for encrypted HTTP/2 where the token h2 is negotiated via ALPN.
Reason messages have been dropped as being redundant, as the status code was already conveying all the necessary information (not to mention that they could be attack vectors).
For these reasons, HTTP/2 does not have neither version nor reason pseudo-headers.

How to know the full request has been received with HTTP 1.0 and HTTP 1:1?

I'm implementing a ultra simple dummy HTTP server responding a message with Hello world to any requests. It is just for benchmarking the asynchronous event handling with wrk or equivalent web server benchmarking tool.
After some searching on the Web I can't find a clear EndOfMessage (EOM) marker. It seam that with HTTP 1.0 we know we have received the full request when the connection is closed. Is that right ?
For HTTP 1.1, how do we know if pipelining is used ? What is the EOM in this case ?
After some searching on the Web I can't find a clear EndOfMessage (EOM) marker.
You can't find one because such a thing doesn't exist. The only marker you may find is the CRLF pair indicating the end of the header fields. In general, the enclosed entity length (that is for requests and responses!) is either communicated beforehand via the Content-Length header or through the transport coding.
with HTTP 1.0 we know we have received the full request when the connection is closed. Is that right?
That is one of two ways mandated by RFC 1945. So generally speaking: no. From RFC 1945, section 7.2.2:
When an Entity-Body is included with a message, the length of that body may be determined in one of two ways. If a Content-Length header field is present, its value in bytes represents the length of the Entity-Body. Otherwise, the body length is determined by the closing of the connection by the server.
This may read like you were generally in the right with your assertion. BUT:
Closing the connection cannot be used to indicate the end of a request body, since it leaves no possibility for the server to send back a response.
With you being on the receiving side, your assumption is simply wrong on every conceivable level: If the request contains a body, announcing the size of said body through the Content-Length header is an absolute requirement.
HTTP/1.1 is a bit relaxed in this regard, as it allows for more options. As Julian pointed out, please consult RFC 7230, section 3.3.3. That section is straightforward to read and to answer your question, I'd have to c&p it as whole.
For HTTP 1.1, how do we know if pipelining is used ?
You do if you receive multiple requests through one connection. The strongest indicator for the client non engaging into pipelining is the presence of Connection: close in the first received request. See RFC 7230, section 6.3 and section 6.3.2. If you are worried about having to support this, you are always free to just read the first request and send back a response with Connection: close in it. The client will know it has to establish a new connection.
What is the EOM in this case ?
Again, there is no marker as there is no special treatment for requests during pipelining. All pipelining is really enabling is to have multiple requests being issued in one go. See section 3.3.3 from above on how to determine the message length.

If I check the "content-length" header, is it 100% accurate?

If not, how accurate is it?
I want to know the size of the image before I download it.
Can the HTTP Content-length header be malformed? Yes.
Should you trust it to be a fair representation of the size of the message body? Yes.
It should be, and usually is, accurate. However it is entirely possible for a web server to report a incorrect content length although this obviously doesn't happen often (I recall old versions of apache retuning nonsensical content lengths on files > 2GB).
It is also not mandatory to provide a Content-Length header
It had better be - otherwise why have it at all?
If it can't be reliably determined in advanced, it shouldn't be served by the server at all. (When dealing with dynamically generated text, for example, something like chunked transfer encoding may be used - which doesn't require the final length to be known when the HTTP header is written at the beginning of the stream.)
Content-Length can be sent by the server code (or) by the apache layer itself.
When the code is not sending apache will send it.
There are known client-crashes when the client connects and closes the socket when the
content-length is sent smaller.
Since the images are usually not generated by code in run-time, you can rely on it.
Browsers can be unforgiving if the content-length is incorrect.
I was having a problem here, where the server was sometimes returning a content-length that was too low. The browsers just wouldn't handle it.
So yes, you can assume that the server is setting the content-length correctly, based on the knowledge that browser clients work on the same assumption.
A sharing for what I've discovered recently.
My case was using NodeJS to post http request to another server, which I'm able to set the content-length value by my self into the header (the value is lower than the actual size).
When the other server received my http request, it only process the request param/body size up to the point that the content-length told the server.
E.g. my request actual length is 100, but content-length mentioned 80, the server who received the request will only process 1-80 and the last 20 wasn't being processed and caused some error like "Invalid parameter".
Nowadays sever side will automatically insert the content-length for you, unless there are needs and you know what you are doing, else you don't want to change it as it may cause you trouble.

Resources