Skip to content

Malformed HTTP requests bypass ProxyHttp layer, preventing custom error handling and logging #919

Description

@rxdiscovery

Hello,

Context & Current Behavior

When Pingora receives an HTTP request with a malformed URL, the error is handled internally at the Server layer. Consequently, the request never reaches the ProxyHttp layer. Because of this, it is impossible to intercept or log these invalid requests via fail_to_proxy or any other phase of the proxy lifecycle.

Instead, Pingora automatically generates a hardcoded response using generate_error():

--- server.rs

pub fn generate_error(error: u16) -> ResponseHeader {
    match error {
        /* common error responses are pre-generated */
        502 => error_resp::HTTP_502_RESPONSE.clone(),
        400 => error_resp::HTTP_400_RESPONSE.clone(),
        _ => error_resp::gen_error_response(error),
    }
}

--- error_resp.rs

pub fn gen_error_response(code: u16) -> ResponseHeader {
    let mut resp = ResponseHeader::build(code, Some(4)).unwrap();
    resp.insert_header(header::SERVER, &SERVER_NAME[..])
        .unwrap();
    resp.insert_header(header::DATE, "Sun, 06 Nov 1994 08:49:37 GMT")
        .unwrap(); // placeholder
    resp.insert_header(header::CONTENT_LENGTH, "0").unwrap();
    resp.insert_header(header::CACHE_CONTROL, "private, no-store")
        .unwrap();
    resp
}

The Problem

This behavior creates a major limitation for production environments where every single request needs to be processed, logged, or analyzed (e.g., for security auditing, SIEM logging, or WAF/attack detection).

Currently, I am forced to maintain a local patched version of Pingora to bypass this, which is unsustainable for long-term production use.

There are 4 critical points regarding the current implementation:

  1. Lack of Propagation: Internal server errors (like a 400 Bad Request due to a malformed URL) should ideally be forwarded to the ProxyHttp layer so users can catch and handle them (ex: fail_to_proxy).
  2. Hardcoded / Inconsistent Headers: The generated response is not customizable. Furthermore, it includes a hardcoded placeholder date (Sun, 06 Nov 1994 08:49:37 GMT) which is inconsistent with real-time traffic.
  3. Security Information Disclosure: Leaking the SERVER header (Pingora) in these errors exposes the underlying technology stack to potential attackers. Security best practices recommend stripping or customizing these headers to prevent fingerprinting.
  4. Risk of Panics: The extensive use of .unwrap() during the header insertion sequence presents a potential crash/panic risk in edge-case scenarios.

Proposed Solution / Discussion

We need a structural solution to allow these early-stage errors to be intercepted or customized within the ProxyHttp ecosystem, or at least provide a hook to override the default error response generation.

Is there already a planned roadmap or architectural design to address this architectural gap?

I would be more than happy to contribute and open a PR for this, but since it impacts the internal core workflow of the framework, I would appreciate some guidance from the maintainers on the preferred alignment and design pattern to follow.


Pingora version: 0.8.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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