Tue, 10 Apr 2018 18:16:47 -0700 httppeer: support protocol upgrade
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 18:16:47 -0700] rev 37558
httppeer: support protocol upgrade With the new handshake defined and in place on the server, we can now implement it on the client. The HTTP handshake mechanism has been taught to add headers advertising its support for the new capabilities response. Response handling has been adjusted to allow CBOR responses through. And makepeer() has been taught to instantiate a mutually supported peer. The HTTPv2 peer class doesn't implement the full peer interface. So HTTPv2 is not yet usable as a peer. Like the server side, we support registering handlers for different API services. This allows extensions to easily implement API services and peers. A practical use case for this is to provide a previous implementation of the experimental version 2 wire protocol to a future version of Mercurial. We know there will be BC breaks after 4.6 ships. But someone could take the peer and server code from 4.6, drop it in an extension, and allow its use indefinitely. Differential Revision: https://phab.mercurial-scm.org/D3243
Tue, 10 Apr 2018 14:29:15 -0700 wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 14:29:15 -0700] rev 37557
wireproto: define and implement HTTP handshake to upgrade protocol When clients connect to repositories over HTTP, they issue a request to the well-known URL "?cmd=capabilities" to fetch the repository capabilities. This is the handshake portion of the HTTP protocol. This commit defines a mechanism to use that HTTP request to return information about modern server features. If a client sends an X-HgUpgrade-* header containing a list of client-supported API names, the server responds with a response containing information about available services. This includes the normal capabilities string. So if the server doesn't support any newer services, the client can easily fall back. By advertising supported services from clients, server operators can see and log what client support exists in the wild. This will also help with debugging. The response contains the base path to API services. We know there are potential issues with the <repo>/api/ URL space conflicting with hgwebdir and subrepos. By making the API URL dynamic from the perspective of the client, the URL for APIs is not subject to backwards compatibility concerns - at least as long as a ?cmd=capabilities request is made. We've also defined the ``cbor`` client capability for the X-HgProto-* header. This MUST be sent in order to get the modern response from "?cmd=capabilities". During implementation, I initially always sent an application/mercurial-cbor response. However, the handshake mechanism will be more future compatible if the client is in charge of which formats to request. We already perform content negotiation from X-HgProto-*, so keying off this for the capabilities response feels appropriate. In addition, I initially used application/cbor. However, it is conceivable that a non-Mercurial server could serve application/cbor. To rule out this possibility, I've invented a new media type that is Mercurial specific and can't be confused for generic CBOR. Differential Revision: https://phab.mercurial-scm.org/D3242
Tue, 10 Apr 2018 18:13:28 -0700 httppeer: only advertise partial-pull if capabilities are known
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 18:13:28 -0700] rev 37556
httppeer: only advertise partial-pull if capabilities are known We don't need to be advertising client protocol parameters as part of the capabilities request during the handshake because nothing in version 1 of the wire protocol will use this data. i.e. the advertisement is wasteful. Differential Revision: https://phab.mercurial-scm.org/D3241
Tue, 10 Apr 2018 16:53:44 -0700 httppeer: always add x-hg* headers to Vary header
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 16:53:44 -0700] rev 37555
httppeer: always add x-hg* headers to Vary header Before, we manually updated the Vary header value for each header contributing to it. All X-Hg* headers are reserved for the Mercurial protocol and could have caching implications. So it makes sense to always add these headers to Vary. A test revealed that X-HgArgs-Post wasn't being added to Vary. This is only sent on POST requests. POST requests generally aren't cacheable. However, it is possible if the server sends the appropriate headers. Mercurial shouldn't be sending those headers. But let's not take any chances. Differential Revision: https://phab.mercurial-scm.org/D3240
Tue, 10 Apr 2018 13:41:21 -0700 httppeer: don't accept very old media types (BC)
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 13:41:21 -0700] rev 37554
httppeer: don't accept very old media types (BC) Versions of Mercurial older than 1.0 emitted the text/plain and application/hg-changegroup media types in response to wire protocol commands. Way back in 8760d0c83b9b in 2005, the code validating these media types was added, presumably for backwards compatibility. 0b245edec124 a short time before that commit changed things from text/plain and application/hg-changegroup to application/mercurial-0.1 and application/hg-0.1. 8760d0c83b9b seemed to indicate ("for now") that the BC compatibility was temporary. But that code has lived until this day. It has been more than 10 years and nobody should be running pre 1.0 servers. Pretty much the only risk to this is if there's a server somewhere advertising the old media types or server software is interfering and not letting Mercurial send the proper Content-Type header. I think the chances are rare. The wire protocol docs were created (by me) from reading existing code. So the deletions don't constitute a spec change as much as reflecting the reality of how things have been for years. .. bc:: The HTTP client no longer accepts text/plain and application/hg-changegroup Content-Type values as a valid Mercurial command response. These should only be encountered on pre 1.0 Mercurial servers. Differential Revision: https://phab.mercurial-scm.org/D3239
Tue, 10 Apr 2018 13:07:13 -0700 httppeer: allow opener to be passed to makepeer()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 13:07:13 -0700] rev 37553
httppeer: allow opener to be passed to makepeer() This allows us to use makepeer() in `hg debugwireproto`. Differential Revision: https://phab.mercurial-scm.org/D3238
Tue, 10 Apr 2018 13:11:40 -0700 httppeer: perform capabilities request in makepeer()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 13:11:40 -0700] rev 37552
httppeer: perform capabilities request in makepeer() Previously, we constructed an httppeer then always ran _fetchcaps() to issue the capabilities command. We want to issue the capabilities command before constructing a peer instance so we can construct an appropriate peer instance depending on the capabilities result. With the code for making and sending requests moved out of httppeer, it is now possible to send command requests without an httppeer. This commit creates a new function for making the capabilities request and calls it as part of makepeer(). This code should be functionality equivalent to what existed before. Differential Revision: https://phab.mercurial-scm.org/D3237
Tue, 10 Apr 2018 12:52:29 -0700 httppeer: extract common response handling into own function
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 12:52:29 -0700] rev 37551
httppeer: extract common response handling into own function This allows the common redirect detection, content type validation, and decompression wrapping to be usable outside of httppeer instances. Differential Revision: https://phab.mercurial-scm.org/D3236
Tue, 10 Apr 2018 12:12:07 -0700 httppeer: move error handling and response wrapping into sendrequest
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 12:12:07 -0700] rev 37550
httppeer: move error handling and response wrapping into sendrequest This is common for all HTTP requests. It should be part of sendrequest(). Differential Revision: https://phab.mercurial-scm.org/D3235
Tue, 10 Apr 2018 10:51:12 -0700 httppeer: extract code for creating a request into own function
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 10:51:12 -0700] rev 37549
httppeer: extract code for creating a request into own function Some of this feels awkward, such as having to pass in a function to evaluate a capability. And this code is generally pretty difficult to read. I didn't want to perform too much refactoring as part of the code move since it would make review more difficult. Differential Revision: https://phab.mercurial-scm.org/D3234
Tue, 10 Apr 2018 10:27:49 -0700 httppeer: extract code for performing an HTTP request
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 10:27:49 -0700] rev 37548
httppeer: extract code for performing an HTTP request This is generic and doesn't need to live as a method of httppeer. Differential Revision: https://phab.mercurial-scm.org/D3233
Tue, 10 Apr 2018 10:22:26 -0700 httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 10 Apr 2018 10:22:26 -0700] rev 37547
httppeer: move requestbuilder defaults into makepeer() argument Upcoming commits will move the initial ?cmd=capabilities handshake request out of httppeer so the handshake can be performed before a peer instance is constructed. In order to do this, we'll need to refactor code for making HTTP requests. The type used to construct HTTP requests is configurable. If we'll be making HTTP requests outside of httppeer, we should be able to use a custom request builder. So move the definition of that type into makepeer(). Extensions can monkeypatch the function and override the argument value. Differential Revision: https://phab.mercurial-scm.org/D3232
(0) -30000 -10000 -3000 -1000 -300 -100 -12 +12 +100 +300 +1000 +3000 +10000 tip