Skip to content
Closed
Show file tree
Hide file tree
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
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

The flexibility of MasterProxy has been increased and it is now possible to
generate configuration at runtime during application startup.

Breaking change: You must create a `MyApp.Proxy` module that calls `use
MasterProxy`. This allows configuration to be generated at runtime which is
important for usage with SiteEncrypt along with other setups.

Example module:

```elixir
defmodule MyApp.Proxy do
use MasterProxy.Proxy
end
```

The proxy must then be explicitly started as part of your application
supervision tree. Proxies can be added to the supervision tree as follows
(usually in `MyApp.Application`):

```elixir
children = [
# ... other children
MyApp.Proxy,
]
```

You can also move your `backends` configuration into your `MyApp.Proxy` module
instead of inside application configuration. This change is in line with the
["Avoid application
configuration"](https://hexdocs.pm/elixir/1.13/library-guidelines.html#avoid-application-configuration)
library guideline.

See `MasterProxy.Proxy` docs for details about the new module.

## 0.1.4 - 2022-01-21
### Added
- Add server and domain options [#16](https://github.com/jesseshieh/master_proxy/pull/16)
Expand Down
105 changes: 78 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,61 @@ def deps do
end
```

Configure rules for routing requests by adding something like this in your configuration (i.e. `config/config.exs`).
Configure rules for routing requests by adding configuration (i.e.
`config/config.exs`). Backend configuration is optional and can be replaced by
the `merge_config/2` callback of your proxy module (more info below) if you need
to generate configuration at runtime.

```elixir
config :master_proxy,
config :master_proxy,
# any Cowboy options are allowed
http: [:inet6, port: 4080],
https: [:inet6, port: 4443],
backends: [
%{
domain: "my-cool-app.com",
phoenix_endpoint: MyCoolAppWeb.Endpoint
},
%{
domain: "members.my-cool-app.com",
phoenix_endpoint: MyAppMembersWeb.Endpoint
},
%{
verb: ~r/get/i,
path: ~r{^/master-proxy-plug-test$},
plug: MasterProxy.Plug.Test,
opts: [1, 2, 3]
}
]
https: [:inet6, port: 4443]
```

Note: backends can also be configured via configuration, but configuring the
backends via your proxy module (see the `use MasterProxy.Proxy` example below)
is recommended.

See [Configuration Examples](#module-configuration-examples) for more.

Then create the proxy module and add it to your application startup (often in `MyApp.Application`):

module:
``` elixir
defmodule MyApp.Proxy do
use MasterProxy.Proxy

@impl MasterProxy.Proxy
def backends do
[
%{
domain: "my-cool-app.com",
phoenix_endpoint: MyCoolAppWeb.Endpoint
},
%{
domain: "members.my-cool-app.com",
phoenix_endpoint: MyAppMembersWeb.Endpoint
},
%{
verb: ~r/get/i,
path: ~r{^/master-proxy-plug-test$},
plug: MasterProxy.Plug.Test,
opts: [1, 2, 3]
}
]
end
end
```

Proxies must be explicitly started as part of your application supervision tree.
Proxies can be added to the supervision tree as follows (usually in `MyApp.Application`):

children = [
# ... other children
MyApp.Proxy,
]

To avoid the platform routing requests directly to your Web apps' Endpoints, and thus bypassing the Endpoint on which MasterProxy is running, you can configure your other Web apps' Endpoints to not start a server in your production config.

```elixir
Expand All @@ -62,6 +90,7 @@ config :my_app_web, MyAppWeb.Endpoint,
- `:https` - the configuration for the HTTPS server. It accepts all options as defined by [Plug.Cowboy](https://hexdocs.pm/plug_cowboy/).
- `:server` - `true` by default. If you are running application with `mix phx.server`, this option is ignored, and the server will always be started.
- `:backends` - the rule for routing requests. See [Configuration Examples](#configuration-examples) for more.
- `:domain`
- `:verb`
- `:host`
- `:path`
Expand All @@ -75,6 +104,36 @@ config :my_app_web, MyAppWeb.Endpoint,
### Route requests to apps based on hostname

```elixir
defmodule MyApp.Proxy do
use MasterProxy.Proxy

@impl MasterProxy.Proxy
def backends do
[
%{
host: ~r{^app-name\.gigalixirapp\.com$},
phoenix_endpoint: MyAppWeb.Endpoint
},
%{
host: ~r{^www\.example\.com$},
phoenix_endpoint: MyAppWeb.Endpoint
},
%{
host: ~r{^api\.example\.com$},
phoenix_endpoint: MyAppApiWeb.Endpoint
},
%{
host: ~r{^members\.example\.com$},
phoenix_endpoint: MyAppMembersWeb.Endpoint
}
]
end
end
```

### Configuration via application config

``` elixir
config :master_proxy,
http: [port: 80],
backends: [
Expand All @@ -85,14 +144,6 @@ config :master_proxy,
%{
host: ~r{^www\.example\.com$},
phoenix_endpoint: MyAppWeb.Endpoint
},
%{
host: ~r{^api\.example\.com$},
phoenix_endpoint: MyAppApiWeb.Endpoint
},
%{
host: ~r{^members\.example\.com$},
phoenix_endpoint: MyAppMembersWeb.Endpoint
}
]
```
Expand Down
54 changes: 0 additions & 54 deletions lib/master_proxy/application.ex

This file was deleted.

5 changes: 2 additions & 3 deletions lib/master_proxy/cowboy2_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ defmodule MasterProxy.Cowboy2Handler do

# endpoint and opts are not passed in because they
# are dynamically chosen
def init(req, {_endpoint, _opts}) do
def init(req, {_endpoint, opts}) do
log_request("MasterProxy.Cowboy2Handler called with req: #{inspect(req)}")

conn = connection().conn(req)

# extract this and pass in as a param somehow
backends = Application.get_env(:master_proxy, :backends)
backends = Keyword.get(opts, :backends)

backend = choose_backend(conn, backends)
log_request("Backend chosen: #{inspect(backend)}")
Expand Down
Loading