Skip to content

SOVD server to SOVD server communication #30

@lh-sag

Description

@lh-sag

URL rewriting for private SOVD server access via public gateway

Problem Description

When a SOVD client accesses resources of a private SOVD server through a public SOVD server acting as a gateway/proxy, the URIs returned in API responses point to the private SOVD server instead of the public gateway. This breaks subsequent API calls from external clients that cannot directly reach the private server.

Diagram of Private SOVD Server Setup

    External             :                Vehicle Network
                         :
    +------------+       :       +-------------+       +-------------+
    |            |       :       |             |       |             |
    | SOVD       |-------|------>| Public      |------>| Private     |
    | Client     |       :       | SOVD Server |       | SOVD Server |
    |            |       :       | (Gateway)   |       | (Internal)  |
    +------------+       :       +-------------+       +-------------+
                         :
                    Firewall/NAT

Context

  • External SOVD Client: Connects through public server to access private server resources
  • Public SOVD Server: Accessible from external network, acts as gateway (located in vehicle network)
  • Private SOVD Server: Internal vehicle access only, not directly accessible from outside

Motivation

One of the key motivations for addressing this issue is to enable interoperability among different SOVD server vendors. In a vehicle architecture, the public and private SOVD servers may be provided by different vendors. A standardized approach to URL rewriting ensures that:

  • Public SOVD servers from vendor A can properly proxy requests to private SOVD servers from vendor B
  • Different vendor implementations can work together seamlessly
  • The ecosystem remains open and competitive without vendor lock-in

Example Scenario

  1. External client requests: GET https://public-sovd.example.com/v1/components/PrivateECU/data
  2. Public server forwards to: GET https://private-sovd.internal/v1/components/PrivateECU/data
  3. Private server response contains:
{
  "items": [
    {
      "id": "batteryVoltage",
      "href": "https://private-sovd.internal/v1/components/PrivateECU/data/batteryVoltage"
    }
  ]
}
  1. Problem: Client cannot access https://private-sovd.internal/... directly

Technical Hints for Handling URL Rewriting

Technical Hint 1: Response Payload Rewriting

Approach: The public SOVD server could parse and modify response payloads, replacing private URIs with public ones.

Considerations:

  • Transparent to clients
  • No changes needed to private SOVD servers
  • Performance overhead for parsing/modifying JSON
  • Public server must understand all response formats
  • Complex implementation for nested URIs
  • Risk of missing URIs in dynamic content

Example Implementation:

# Pseudo-code for public server
def rewrite_response(response, private_base, public_base):
    if content_type == "application/json":
        data = json.loads(response.body)
        rewrite_urls_recursive(data, private_base, public_base)
        response.body = json.dumps(data)
    return response

Technical Hint 2: Relative URI Approach

Approach: Private SOVD servers could return relative URIs instead of absolute ones.

Considerations:

  • Simple and standard HTTP approach
  • No payload manipulation needed
  • Better performance
  • Requires changes to private SOVD servers
  • May conflict with ISO 17978-3 if it mandates absolute URIs
  • SSE event streams might have issues with relative paths

Example Implementation:

// Private server could return:
{
  "items": [
    {
      "id": "batteryVoltage",
      "href": "v1/components/PrivateECU/data/batteryVoltage"  // Relative instead of absolute
    }
  ]
}

Technical Hint 3: Forwarded Headers (RFC 7239)

Approach: Use HTTP Forwarded header or X-Forwarded-Host to inform private server about the original request context.

Considerations:

  • Standard HTTP mechanism (RFC 7239)
  • Private server generates correct URIs
  • Clean separation of concerns
  • Widely supported pattern
  • Private servers must be "forwarding-aware"
  • Requires implementation changes in private servers

Example Implementation:

# Public server could add when forwarding:
GET /v1/components/PrivateECU/data HTTP/1.1
Host: private-sovd.internal
Forwarded: host=public-sovd.example.com;proto=https
X-Forwarded-Host: public-sovd.example.com
X-Forwarded-Proto: https
# Private server could generate URIs using forwarded information:
if forwarded_host:
    base_uri = f"{forwarded_proto}://{forwarded_host}"
else:
    base_uri = f"{request.proto}://{request.host}"

Recommended Approach

Technical Hint 3 (Forwarded Headers) appears to be the most suitable approach because:

  1. It follows established HTTP standards (RFC 7239)
  2. Maintains clean architecture boundaries
  3. Commonly used in reverse proxy scenarios
  4. Allows private servers to be proxy-aware while maintaining backward compatibility
  5. No performance overhead from payload manipulation
  6. Enables vendor interoperability through standard HTTP mechanisms

Implementation Considerations

  • Define which headers to use (Forwarded vs X-Forwarded-*)
  • Update public SOVD server to add forwarding headers
  • Update private SOVD servers to honor forwarding headers
  • Handle SSE event streams correctly
  • Test with nested resource references
  • Document the forwarding behavior in API specification
  • Consider security implications (trust boundary for headers)
  • Test interoperability between different vendor implementations

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions