Skip to content

Upgrade rack-proxy to v0.7.2

Stan Hu requested to merge sh-update-rack-proxy into master

What does this MR do and why?

This fixes a bug that manifested with the webpack-dev-server and the thin Web server.

When a chunked transfer is proxied from rack-proxy (see diagram below), the proxied HTTP response would contain the original Transfer-Encoding: chunked HTTP header. However, the body would be stripped of the chunked encoding headers. As a result, Workhorse would fail to parse the body with the error:

httputil: ReverseProxy read error during body copy: invalid byte in chunk length

This occurred because the Golang chunked decoder expected to parse a length represented as an ASCII number followed by a \r\n. Instead, the first byte was a binary character from the gzipped data.

This does not occur with Puma because Puma initiates a request with an HTTP/1.0 header and explicitly disables chunked transfers.

https://github.com/ncr/rack-proxy/pull/59 fixes this problem by dropping the Transfer-Encoding: chunked header so that Workhorse won't handle the HTTP response as a chunked transfer.

See gitlab-development-kit#1443 (comment 880747269) for more details.

Relates to #352649 (closed)

Diff:

Closes gitlab-development-kit#1443 (closed)

Screenshots or screen recordings

The problem happens at step 7:

sequenceDiagram
    autonumber
    curl->>NGINX: GET /assets/webpack/0.chunk.js
    NGINX->>Workhorse: GET /assets/webpack/0.chunk.js
    Workhorse->>Thin: GET /assets/webpack/0.chunk.js
    Thin->>Thin: DevServerMiddleware proxies to rack-proxy
    Thin->>Webpack: thin/request: GET /assets/webpack/0.chunk.js HTTP/1.1
    Webpack->>Thin: HTTP/1.1 chunked, gzip 
    Thin->>Workhorse: gzip body (chunked headers stripped)
    Workhorse->>NGINX: Empty body
    NGINX->>curl: Empty boxy

rack-proxy returns the headers and body as-is, keeping Transfer-Encoding: chunked. However, the body is the original JavaScript asset with the stripped the chunking headers.

How to set up and validate locally

  1. Run gdk thin.
  2. Try to load a project page. You should see missing elements. Alternatively you can curl an asset: curl https://gdk.tests:3443/assets/webpack/0.chunk.js.
  3. Check out this branch.
  4. Hit CTRL-C to cancel thin and run gdk thin again.
  5. Repeat step 2

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Ash McKenzie

Merge request reports

Loading