http-extensions
http-extensions copied to clipboard
Resumable upload: feature detection mechanism
Here is a list of various options to perform feature detection for reusable upload. Is 1xx status code the best option among them?
- HTTP/2 and HTTP/3 SETTINGS frame
- DNS record
- OPTIONS request (extra round-trip)
- /.well-known URI (extra round-trip)
My 2 cents:
- I believe this should not rely on techniques specific to certain HTTP versions (thus no to SETTINGS)
- Requiring access to DNS records will definitively make this hard to deploy
- We don't need to optimize round-trips in case 1xx doesn't work; that's an incentive to make them work.
That said, it would be good to have a place that documents where servers/clients/frameworks fail to make 1xx work.
I went through TIOBE languages list (removed a few obviously inapplicable ones like SQL) and looked up the most common HTTP client libraries in each language. Here is the list of 1xx status code support in each library. I put question marks where I'm not absolutely certain:
- Python
- http.client: ignores received 1xx?
- C
- curl: supports 1xx
- Java
- C++
- C#
- System.Net.Http: ignores received 1xx?
- Visual Basic
- JavaScript
- Fetch: ignores received 1xx?
- PHP
- Objective-C
- NSURLSession: ignores received 1xx
- Go
- Net::HTTP: supports sending, (doc) supports received 1xx through httptrace
- Delphi
- Swift
- URLSession: ignores received 1xx
- Perl
- Ruby
- Net::HTTP: ignores received 1xx?
We can turn this into a wiki page if people want to complete the list.
Java: as far as I know, Apache HttpClient 5.x does support handling 1xx responses
Oh yes, I found the documentation here: https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/org/apache/hc/client5/http/async/AsyncExecCallback.html
For Java's HTTPURLConnection there's even a bug that 1xx is treated as final code, unfixed since being reported in 2016: https://bugs.openjdk.org/browse/JDK-8170305
Started test suite at https://github.com/greenbytes/java-http-1xx-tests and verified that at least one client (Apache HC 5) actively supports 1xx codes (when asked nicely).
The Go documentation currently says following about 1xx:
supports sending 1xx
Yes, this is supported.
ignores received 1xx?
Not entirely sure on this one. The docs mention that it has a Got1xxResponse callback, but I am not sure to what extend this can currently be used. As per https://pkg.go.dev/net/http:
Responses with status codes in the 1xx range are either handled automatically (100 expect-continue) or ignored. The one exception is HTTP status code 101 (Switching Protocols), which is considered a terminal status and returned by RoundTrip. To see the ignored 1xx responses, use the httptrace trace package's ClientTrace.Got1xxResponse.
Found the document with some example code at the top: https://pkg.go.dev/net/http/httptrace
The JDK bugs are now fixed (as of JDK 20); backports pending. Active reporting of 1xx still missing.
I have to admit that the state of supporting 1XX in servers and clients is a lot better than anticipated. Do we have any information how support is looking with proxies, such as nginx, HAProxy, and Apache? I think to remember that nginx does not pass on the handling of the Expect: 100-continue header to the downstream server. Or is that not relevant in our case because the server is only interested in sending a 1XX status code and does not have to receive an Expect header? Should we also introduce an Expect: 10?-resumable-upload header (or some similar value)?
So it would also be worth investigating the current state in proxies.
Discussion on Expect (or not) is in https://github.com/httpwg/http-extensions/issues/2243
I think there is consensus that an information response is the best approach for a server to indicate its support. There are currently limits to the real-world usability of 1XX responses, but that will improve in the future. As such, I think the question of which mechanism to use for feature detection can be closed. Let me know if we should keep this issue open.