Skip to content

Avoid data transfer before Kerberos auth completes

Unlike Basic, Kerberos authentication involves several round-trips (i.e. a 401 Unauthorized response followed by a new request with more data in the Authorization header). When doing git push, proper support for the Expect: 100-Continue header in these round-trips can avoid git unnecessarily sending the whole pushed data with each of these round-trip, improving performance and the need for configuring http.postBuffer in gitconfig.

This patch enables sending a 401 response and close the connection without having consumed the request body, in accordance with http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3

Without the patch, when the git client first sends a Expect: 100-Continue header and waits a bit before actually sending data, the 401 response is kept in response buffers inside gitlab-workhorse and does not reach the git client before it times out waiting for the 100-Continue message and starts sending data. Thus git always starts sending data, even though authentication is not complete.

It makes a huge difference with large pushes when using a non-buffering proxy (HAProxy in our case):

  • A push larger than http.postBuffer results in git sending the data with chunked encoding. When the server needs to respond with 401 to request another round-trip of Kerberos authentication and does it after git started sending the chunked-encoded data, git would fail the push. The only solution to perform large pushes with Kerberos was to increase http.postBuffer to something larger that the push size.
  • But with a large http.postBuffer, the whole push data gets sent with every authentication round-trip. This makes large pushes really inefficient, but also causes some errors because the data is not actually consumed by the server, as discussed in !94 (closed).

With this patch large pushes can now safely use chunked encoding together with Kerberos authentication because git is properly notified, before it sends any data, that authentication is not complete and it shouldn't send any data yet on that connection.

The patch should have no effect when using nginx with buffering enabled: in this case nginx immediately starts reading and buffering the request body anyways, so the 401 response cannot reach git before it starts sending data. A large http.postBuffer and multiple transfers of the push data remain necessary.

Edited by Wayne Haber

Merge request reports