Workhorse handlers
Long HTTP requests are hard to handle efficiently in Rails.
The requests are either memory-inefficient (file uploads) or impossible at all due to shorter timeouts
(for example, Puma server has 60-second timeout).
Workhorse can efficiently handle a large number of long HTTP requests.
Workhorse acts as a proxy that intercepts all HTTP requests and either propagates them without
changing or handles them itself by performing additional logic.
Injectors
Rails Workhorse Client Rails Workhorse Client Request Propagate the request as-is Respond with a special header that contains instructions for proceeding with the request Response
Example: Send a Git blob
Gitaly Rails Workhorse Client Gitaly Rails Workhorse Client HTTP Request for a blob Propagate the request as-is Respond with a git-blob:{encoded_data} header BlobService.GetBlob gRPC request BlobService.GetBlob gRPC request Stream the data
How GitLab Rails processes the request
Example: Send a file
Object Storage Rails Workhorse Client Object Storage Rails Workhorse Client HTTP Request for a file Propagate the request as-is Respond with a send-url:{encoded_data} header Request for a file Stream the data Stream the data
Pre-authorized requests
Object Storage Rails Workhorse Client Object Storage Rails Workhorse Client Append `/authorize` to the original URL and call Rails for an Auth check Workhorse calls the original URL to create a database record PUT /artifacts/uploads GET /artifacts/uploads/authorize Authorized successfully Stream the file content Upload the file Success Finalize the request Finalized successfully Uploaded successfully
Git over HTTP(S)
Workhorse accelerates Git over HTTP(S) by handling Git HTTP protocol requests. For example, Git push/pull may require serving large amounts of data. To avoid transferring it through GitLab Rails, Workhorse only performs authorization checks against GitLab Rails, then performs a Gitaly gRPC request directly, and streams the data from Gitaly to the Git client.
Git pull
Gitaly Rails Workhorse Git on client Gitaly Rails Workhorse Git on client git clone/fetch Access check/Log activity Access check/Update statistics GET /foo/bar.git/info/refs/?service=git-upload-pack GET Repositories::GitHttpController 200 OK, Gitlab::Workhorse.git_http_ok SmartHTTPService.InfoRefsUploadPack gRPC request SmartHTTPService.InfoRefsUploadPack gRPC response send info-refs response GET /foo/bar.git/info/refs/?service=git-upload-pack GET Repositories::GitHttpController 200 OK, Gitlab::Workhorse.git_http_ok SmartHTTPService.PostUploadPackWithSidechannel gRPC request SmartHTTPService.PostUploadPackWithSidechannel gRPC response send response
Git push
Gitaly Rails Workhorse Git on client Gitaly Rails Workhorse Git on client git push Access check/Log activity Access check/Update statistics GET /foo/bar.git/info/refs/?service=git-receive-pack GET Repositories::GitHttpController 200 OK, Gitlab::Workhorse.git_http_ok SmartHTTPService.InfoRefsReceivePack gRPC request SmartHTTPService.InfoRefsReceivePack gRPC response send info-refs response GET /foo/bar.git/info/refs/?service=git-receive-pack GET Repositories::GitHttpController 200 OK, Gitlab::Workhorse.git_http_ok SmartHTTPService.PostReceivePackWithSidechannel gRPC request SmartHTTPService.PostReceivePackWithSidechannel gRPC response send response