-
-
Notifications
You must be signed in to change notification settings - Fork 756
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
===================== | ||
Reverse Proxy Example | ||
===================== | ||
|
||
This example demonstrates how to run a connexion application behind a path-altering reverse proxy. | ||
|
||
You can either set the path in your app, or set the ``X-Forwarded-Path`` header. | ||
|
||
Running: | ||
|
||
.. code-block:: bash | ||
$ sudo pip3 install --upgrade connexion[swagger-ui] # install Connexion from PyPI | ||
$ ./app.py | ||
Now open your browser and go to http://localhost:8080/reverse_proxied/ui/ to see the Swagger UI. | ||
|
||
|
||
You can also use the ``X-Forwarded-Path`` header to modify the reverse proxy path. | ||
For example: | ||
|
||
.. code-block:: bash | ||
curl -H "X-Forwarded-Path: /banana/" http://localhost:8080/openapi.json | ||
{ | ||
"servers" : [ | ||
{ | ||
"url" : "banana" | ||
} | ||
], | ||
"paths" : { | ||
"/hello" : { | ||
"get" : { | ||
"responses" : { | ||
"200" : { | ||
"description" : "hello", | ||
"content" : { | ||
"text/plain" : { | ||
"schema" : { | ||
"type" : "string" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"operationId" : "app.hello", | ||
"summary" : "say hi" | ||
} | ||
} | ||
}, | ||
"openapi" : "3.0.0", | ||
"info" : { | ||
"version" : "1.0", | ||
"title" : "Path-Altering Reverse Proxy Example" | ||
} | ||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/usr/bin/env python3 | ||
''' | ||
example of aiohttp connexion running behind a path-altering reverse-proxy | ||
''' | ||
|
||
import json | ||
import connexion | ||
from yarl import URL | ||
from aiohttp import web | ||
from aiohttp_remotes.x_forwarded import XForwardedBase | ||
from aiohttp_remotes.exceptions import RemoteError, TooManyHeaders | ||
|
||
X_FORWARDED_PATH = "X-Forwarded-Path" | ||
|
||
|
||
class XPathForwarded(XForwardedBase): | ||
|
||
def __init__(self, num=1): | ||
self._num = num | ||
|
||
def get_forwarded_path(self, headers): | ||
forwarded_host = headers.getall(X_FORWARDED_PATH, []) | ||
if len(forwarded_host) > 1: | ||
raise TooManyHeaders(X_FORWARDED_PATH) | ||
return forwarded_host[0] if forwarded_host else None | ||
|
||
@web.middleware | ||
async def middleware(self, request, handler): | ||
try: | ||
overrides = {} | ||
headers = request.headers | ||
|
||
forwarded_for = self.get_forwarded_for(headers) | ||
if forwarded_for: | ||
overrides['remote'] = str(forwarded_for[-self._num]) | ||
|
||
proto = self.get_forwarded_proto(headers) | ||
if proto: | ||
overrides['scheme'] = proto[-self._num] | ||
|
||
host = self.get_forwarded_host(headers) | ||
if host is not None: | ||
overrides['host'] = host | ||
|
||
prefix = self.get_forwarded_path(headers) | ||
if prefix is not None: | ||
prefix = '/' + prefix.strip('/') + '/' | ||
request_path = URL(request.path.lstrip('/')) | ||
overrides['rel_url'] = URL(prefix).join(request_path) | ||
|
||
request = request.clone(**overrides) | ||
|
||
return await handler(request) | ||
except RemoteError as exc: | ||
exc.log(request) | ||
await self.raise_error(request) | ||
|
||
|
||
def hello(request): | ||
ret = { | ||
"host": request.host, | ||
"scheme": request.scheme, | ||
"path": request.path, | ||
"_href": str(request.url) | ||
} | ||
return web.Response(text=json.dumps(ret), status=200) | ||
|
||
|
||
if __name__ == '__main__': | ||
app = connexion.AioHttpApp(__name__) | ||
app.add_api('openapi.yaml', pass_context_arg_name='request') | ||
aio = app.app | ||
reverse_proxied = XPathForwarded() | ||
aio.middlewares.append(reverse_proxied.middleware) | ||
app.run(port=8080) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
worker_processes 1; | ||
error_log stderr; | ||
daemon off; | ||
pid nginx.pid; | ||
|
||
events { | ||
worker_connections 1024; | ||
} | ||
|
||
http { | ||
include /etc/nginx/mime.types; | ||
default_type application/octet-stream; | ||
|
||
sendfile on; | ||
|
||
keepalive_timeout 65; | ||
|
||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | ||
ssl_prefer_server_ciphers on; | ||
access_log access.log; | ||
server { | ||
|
||
listen localhost:9000; | ||
|
||
location /reverse_proxied/ { | ||
# Define the location of the proxy server to send the request to | ||
proxy_pass http://localhost:8080/; | ||
# Add prefix header | ||
proxy_set_header X-Forwarded-Path /reverse_proxied/; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
proxy_set_header X-Forwarded-Host $host:$server_port; | ||
proxy_set_header X-Forwarded-Server $host; | ||
proxy_set_header X-Forwarded-Port $server_port; | ||
proxy_set_header X-Forwarded-Proto http; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
openapi: 3.0.0 | ||
info: | ||
title: Path-Altering Reverse Proxy Example | ||
version: '1.0' | ||
servers: | ||
- url: /api | ||
paths: | ||
/hello: | ||
get: | ||
summary: say hi | ||
operationId: app.hello | ||
responses: | ||
'200': | ||
description: hello | ||
content: | ||
text/plain: | ||
schema: | ||
type: string |