Skip to content

ContextHandler sends redirect on BaseResponse instead of Wrapped Response object from Handler chain #9285

Description

@venkatvb

Jetty version(s)
11.0.13

Java version/vendor (use: java -version)
openjdk version "1.8.0_352"

OS type/version
MacOS 12.6.1

Description

Issue: ContextHandler sends redirect on BaseResponse instead of Wrapped Response object from Handler chain. This doesn't preserve any wrapping done by up stream handlers & renders the overridden functionality useless.

Use case: In my case, I have hosted embedded Jetty server behind a reverse proxy. All of the requests would have a proxy-prefix. In order to handle the redirects, I've implemented a ProxyRedirecteHandler to re-wire the proxy url location. But as the ContextHandler sends redirect to the base response instead of wrapped response object, I'm not getting my overridden sendRedirect method invoked.

The ContextHandler expects the request must end with /, otherwise it sends a redirect (302) to the same request URI but with a trailing /. Code reference.

// context request must end with /
baseRequest.setHandled(true);
String queryString = baseRequest.getQueryString();
baseRequest.getResponse().sendRedirect(
    HttpServletResponse.SC_MOVED_TEMPORARILY,
    baseRequest.getRequestURI() + (queryString == null ? "/" : ("/?" + queryString)),
    true);

How to reproduce?
I'm created a minimal repo to reproduce the issue: https://github.com/venkatvb/jetty-proxy-redirect-issue-repro

Can run the org.jettyissue.ProxyRedirectTest behind a simple reverse proxy server.

Behind a proxy (base-path: shs, port: 3000)

venkaar@147ddae4c87f spark % curl -IL "http://localhost:3000/shs/demo"
HTTP/1.1 302 Found
X-Powered-By: Express
date: Wed, 01 Feb 2023 23:34:55 GMT
connection: close
location: http://localhost:3000/demo/ --> Notice the redirect location doesn't have proxy-base - as it didn't went through the ProxyRedirectHandler
server: Jetty(11.0.13)

HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 145
Date: Wed, 01 Feb 2023 23:34:59 GMT
Connection: keep-alive

Without a proxy (port: 5002)

venkaar@147ddae4c87f spark % curl -IL "http://localhost:5002/demo"

HTTP/1.1 302 Found
Date: Wed, 01 Feb 2023 23:37:12 GMT
Location: http://localhost:5002/demo/
Content-Length: 0
Server: Jetty(11.0.13)

HTTP/1.1 200 OK
Date: Wed, 01 Feb 2023 23:37:22 GMT
Content-Type: text/html
Content-Length: 39
Server: Jetty(11.0.13)

Metadata

Metadata

Assignees

Labels

BugFor general bugs on Jetty side

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions