160 lines
5.1 KiB
HTML
160 lines
5.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Reverse Proxy - pyserve</title>
|
|
<link rel="stylesheet" href="../style.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
<script>hljs.highlightAll();</script>
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<div id="header">
|
|
<h1>pyserve</h1>
|
|
<div class="tagline">python application orchestrator</div>
|
|
</div>
|
|
|
|
<div class="breadcrumb">
|
|
<a href="../index.html">Home</a> / <a href="index.html">Guides</a> / Reverse Proxy
|
|
</div>
|
|
|
|
<div id="content">
|
|
<h2>Reverse Proxy</h2>
|
|
|
|
<p>pyserve can act as a reverse proxy, forwarding requests to backend services.</p>
|
|
|
|
<h3>Basic Proxy Configuration</h3>
|
|
<p>Use the <code>proxy_pass</code> directive in routing:</p>
|
|
|
|
<pre><code class="language-yaml">extensions:
|
|
- type: routing
|
|
config:
|
|
regex_locations:
|
|
"~^/api/":
|
|
proxy_pass: "http://localhost:9001"</code></pre>
|
|
|
|
<p>All requests to <code>/api/*</code> will be forwarded to <code>http://localhost:9001/api/*</code>.</p>
|
|
|
|
<h3>Proxy Headers</h3>
|
|
<p>pyserve automatically adds standard proxy headers:</p>
|
|
|
|
<table class="dirindex">
|
|
<tr>
|
|
<td><code>X-Forwarded-For</code></td>
|
|
<td>Client's IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>X-Forwarded-Proto</code></td>
|
|
<td>Original protocol (http/https)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>X-Forwarded-Host</code></td>
|
|
<td>Original Host header</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>X-Real-IP</code></td>
|
|
<td>Client's real IP address</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h3>Custom Headers</h3>
|
|
<p>Add custom headers to proxied requests:</p>
|
|
|
|
<pre><code class="language-bash">"~^/api/":
|
|
proxy_pass: "http://localhost:9001"
|
|
headers:
|
|
- "X-Custom-Header: my-value"
|
|
- "Authorization: Bearer token123"</code></pre>
|
|
|
|
<h3>Dynamic Headers with Captures</h3>
|
|
<p>Use regex capture groups to build dynamic headers:</p>
|
|
|
|
<pre><code class="language-bash">"~^/api/v(?P<version>\\d+)/(?P<service>\\w+)":
|
|
proxy_pass: "http://localhost:9001"
|
|
headers:
|
|
- "X-API-Version: {version}"
|
|
- "X-Service: {service}"
|
|
- "X-Client-IP: $remote_addr"</code></pre>
|
|
|
|
<p>Special variables:</p>
|
|
<ul class="indent">
|
|
<li><code>{capture_name}</code> — Named capture group from regex</li>
|
|
<li><code>$remote_addr</code> — Client's IP address</li>
|
|
</ul>
|
|
|
|
<h3>Proxy Timeout</h3>
|
|
<p>Configure timeout for proxy requests:</p>
|
|
|
|
<pre><code class="language-yaml"># Global default timeout
|
|
server:
|
|
proxy_timeout: 30.0
|
|
|
|
# Per-route timeout
|
|
extensions:
|
|
- type: routing
|
|
config:
|
|
regex_locations:
|
|
"~^/api/slow":
|
|
proxy_pass: "http://localhost:9001"
|
|
timeout: 120 # 2 minutes for slow endpoints</code></pre>
|
|
|
|
<h3>URL Rewriting</h3>
|
|
<p>The proxy preserves the original request path by default:</p>
|
|
|
|
<pre><code class="language-bash"># Request: GET /api/users/123
|
|
# Proxied: GET http://backend:9001/api/users/123
|
|
"~^/api/":
|
|
proxy_pass: "http://backend:9001"</code></pre>
|
|
|
|
<p>To proxy to a specific path:</p>
|
|
|
|
<pre><code class="language-bash"># Request: GET /api/users/123
|
|
# Proxied: GET http://backend:9001/v2/users/123 (path preserved)
|
|
"~^/api/":
|
|
proxy_pass: "http://backend:9001/v2"</code></pre>
|
|
|
|
<h3>Load Balancing Example</h3>
|
|
<p>Route different services to different backends:</p>
|
|
|
|
<pre><code class="language-yaml">extensions:
|
|
- type: routing
|
|
config:
|
|
regex_locations:
|
|
"~^/api/users":
|
|
proxy_pass: "http://user-service:8001"
|
|
|
|
"~^/api/orders":
|
|
proxy_pass: "http://order-service:8002"
|
|
|
|
"~^/api/products":
|
|
proxy_pass: "http://product-service:8003"</code></pre>
|
|
|
|
<h3>Error Handling</h3>
|
|
<p>pyserve returns appropriate error codes for proxy failures:</p>
|
|
|
|
<table class="dirindex">
|
|
<tr>
|
|
<td><code>502 Bad Gateway</code></td>
|
|
<td>Backend connection failed or returned invalid response</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>504 Gateway Timeout</code></td>
|
|
<td>Backend did not respond within timeout</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<div class="note">
|
|
<strong>Note:</strong> pyserve uses <code>httpx</code> for async HTTP requests
|
|
to backend services, supporting HTTP/1.1 and HTTP/2.
|
|
</div>
|
|
</div>
|
|
|
|
<div id="footer">
|
|
<p>pyserve © 2024-2025 | MIT License</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|