FrankChen021 opened a new pull request, #20268:
URL: https://github.com/apache/druid/pull/20268

   ### Description
   
   This PR adds opt-in response headers that identify the Druid process which 
generated an HTTP response:
   
   - `X-Druid-Response-Server`: advertised host and port
   - `X-Druid-Response-Service`: configured `druid.service` name
   
   The feature is disabled by default and can be enabled with:
   
   ```properties
   druid.server.http.enableResponseIdentityHeaders=true
   ```
   
   The identity handler wraps the complete Jetty handler chain, so locally 
generated responses, including early HTTP errors, receive the headers when 
enabled.
   
   #### Router proxy behavior
   
   For query and management requests proxied by a Router:
   
   - If the upstream returns both identity headers, the Router forwards the 
upstream identity.
   - If the upstream returns neither header or only one header, the Router 
returns neither identity header.
   - If no upstream response is received and the Router generates the response, 
the headers identify the Router.
   - A Router with the feature disabled suppresses upstream identity headers.
   
   Treating the two headers as an all-or-nothing pair prevents clients from 
receiving an ambiguous partial identity during rolling upgrades or partial 
configuration.
   
   #### Security
   
   The server header can reveal internal hostnames, IP addresses, and ports. 
The setting remains disabled by default and should only be enabled when clients 
are authorized to receive cluster topology information.
   
   #### Automated tests
   
   - 45 focused configuration, handler, management-proxy, and query-proxy tests 
passed.
   - `ResponseIdentityHeaderTest`: 6 embedded end-to-end tests passed.
   - The embedded coverage includes Coordinator and Overlord APIs directly and 
through Router, Broker SQL and native queries directly and through Router, a 
native query directly to Historical, and Router-generated responses.
   - `git diff --check origin/master...HEAD` passed.
   
   #### Real nano cluster validation
   
   The feature was also tested against a locally built 
`apache-druid-39.0.0-SNAPSHOT` nano-quickstart cluster. All 16 requests 
returned the expected status and process identity.
   
   | URL | Request | Status | Response server | Response service |
   |---|---|---:|---|---|
   | `http://localhost:8888/status/health` | Router health | 200 | 
`localhost:8888` | `druid/router` |
   | `http://localhost:8082/status/health` | Broker health | 200 | 
`localhost:8082` | `druid/broker` |
   | `http://localhost:8081/status/health` | Coordinator/Overlord health | 200 
| `localhost:8081` | `druid/coordinator` |
   | `http://localhost:8083/status/health` | Historical health | 200 | 
`localhost:8083` | `druid/historical` |
   | `http://localhost:8091/status/health` | Middle Manager health | 200 | 
`localhost:8091` | `druid/middleManager` |
   | `http://localhost:8081/druid/coordinator/v1/isLeader` | Coordinator API 
direct | 200 | `localhost:8081` | `druid/coordinator` |
   | `http://localhost:8888/druid/coordinator/v1/isLeader` | Coordinator API 
via Router | 200 | `localhost:8081` | `druid/coordinator` |
   | `http://localhost:8081/druid/indexer/v1/isLeader` | Overlord API direct | 
200 | `localhost:8081` | `druid/coordinator` |
   | `http://localhost:8888/druid/indexer/v1/isLeader` | Overlord API via 
Router | 200 | `localhost:8081` | `druid/coordinator` |
   | `http://localhost:8082/druid/v2/sql` | SQL direct to Broker | 200 | 
`localhost:8082` | `druid/broker` |
   | `http://localhost:8888/druid/v2/sql` | SQL via Router | 200 | 
`localhost:8082` | `druid/broker` |
   | `http://localhost:8082/druid/v2` | Native query direct to Broker | 200 | 
`localhost:8082` | `druid/broker` |
   | `http://localhost:8888/druid/v2` | Native query via Router | 200 | 
`localhost:8082` | `druid/broker` |
   | `http://localhost:8083/druid/v2` | Native query direct to Historical | 200 
| `localhost:8083` | `druid/historical` |
   | `http://localhost:8888/status/health` | Router-generated `PATCH` rejection 
| 405 | `localhost:8888` | `druid/router` |
   | `http://localhost:8888/not-a-druid-endpoint` | Router-generated missing 
endpoint | 404 | `localhost:8888` | `druid/router` |
   
   The nano configuration runs Coordinator and Overlord in one process on port 
`8081` with `druid.service=druid/coordinator`, so requests to Overlord 
endpoints correctly report that process identity.
   
   #### Release note
   
   Druid can optionally return `X-Druid-Response-Server` and 
`X-Druid-Response-Service` on HTTP responses, allowing operators to identify 
the process that served a direct or Router-proxied request. Enable the feature 
with `druid.server.http.enableResponseIdentityHeaders=true` only for clients 
permitted to receive cluster topology information.
   
   <hr>
   
   ##### Key changed/added classes in this PR
   
   - `ResponseIdentityHeaderHandler`
   - `AsyncManagementForwardingServlet`
   - `AsyncQueryForwardingServlet`
   - `ResponseIdentityHeaderTest`
   
   <hr>
   
   This PR has:
   
   - [x] been self-reviewed.
   - [x] added documentation for new or modified features or behaviors.
   - [x] a release note entry in the PR description.
   - [x] added comments explaining the "why" and the intent of the code 
wherever it would not be obvious for an unfamiliar reader.
   - [x] added unit tests or modified existing tests to cover new code paths.
   - [x] added integration tests.
   - [x] been tested in a test Druid cluster.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to