Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite README #8

Merged
merged 1 commit into from
Jul 31, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 49 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,79 @@
# proxyprefix

Let a reverse proxied app know what path it's proxied at. This will allow it
to prefix URL paths accordingly.
Let a proxied service know how it should construct URLs in the response.

This is achieved using a WSGI middleware that prefixes `SCRIPT_NAME` with an
`X-Forwarded-Prefix` header if present.

## Installation
It will also update the WSGI environ to set `wsgi.url_scheme` and `HTTPS`
according to the `X-Forwarded-Proto` header if present.

```
pip install proxyprefix
```
## Example

```python
from proxyprefix.wsgi import ReverseProxiedApp
Let's say:

# flask example:
app.wsgi_app = ReverseProxiedApp(app.wsgi_app)
`curl https://service.com/posts/`

# django example:
application = ReverseProxiedApp(get_wsgi_application())
responds with:

```
{
"posts": [...],
"next": "https://service.com/posts/?page=2"
}
```

## Usage
If we put `service` behind a proxy at `http://client.com/service/`, we want to
make the following changes to that `next` URL:

Let's say `client.com` is proxying `service.com` at `client.com/service`.
1. The host name should be `client.com` instead of `service.com`.
2. The protocol should be `http` instead of `https`.
3. The path should start with `/service/`.

Let's also say we are already handling the host name change using
`X-Forwarded-For` / `X-Forwarded-Host` (this middleware does not alter host
name).
If you're using django, you can do all three by setting
`settings.USE_X_FORWARDED_HOST` to `True`, installing the `proxyprefix` WSGI
middleware, and making sure your proxy sends these headers with its request to
`service`:

```
curl \
--header X-Forwarded-Host: client.com \
--header X-Forwarded-Proto: http \
--header X-Forwarded-Prefix: /service/ \
https://service.com/posts/
```

Let's also say `service.com/posts` returns paginated posts with `next` URLs in
the responses:
Which gives you a response with links to the proxy, not the service:

```
curl -H 'X-Forwarded-Host: client.com' http://service.com/posts
{
"next": "http://client.com/posts?page=2",
...
"posts": [...],
"next": "http://client.com/service/posts/?page=2"
}
```

That URL will 404, since the posts live at `/service/posts` on the client.
Assuming `service.com` honors `SCRIPT_NAME`/`SCRIPT_URL` when generating urls,
you can fix this by adding the proxyprefix middleware to `service.com` and
making sure `client.com` passes a `X-Forwarded-Prefix` header.
For example:
## Installation

```
curl -H 'X-Forwarded-Host: client.com' -H 'X-Forwarded-Prefix: service` \
http://service.com/posts
{
"next": "http://client.com/service/posts?page=2",
...
}
pip install proxyprefix
```

```python
from proxyprefix.wsgi import ReverseProxiedApp

# flask example:
app.wsgi_app = ReverseProxiedApp(app.wsgi_app)

# django example:
application = ReverseProxiedApp(get_wsgi_application())
```

### Sending X-Forwarded-For header in local development:
### Sending `X-Forwarded-*` headers in local development

If you use [djproxy](https://github.com/thomasw/djproxy) to proxy services in
local development, you can send the `X-Forwarded-Prefix` by using the
`XForwardedPrefix` proxy middleware included in this package. For example:
local development, it will send `X-Forwarded-Host` and `X-Forwarded-Proto` for
you. But `X-Forwarded-Prefix` is a non-standard header, so you will need to use
the middleware provided by proxyprefix:

```python
from djproxy.urls import generate_routes
Expand All @@ -76,9 +89,6 @@ configuration = {
urlpatterns += generate_routes(configuration)
```

This will tell djproxy to send `X-Forwarded-Prefix: /service_prefix/` in the
request to service.com.

**Middleware support was added in djproxy 2.0.0.**

## Development
Expand Down