Skip to content

Commit

Permalink
feat: configurable DNS resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
samialdury committed Oct 31, 2023
1 parent 38f4d91 commit 2268331
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 69 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ help:

##@ Development

.PHONY: install
install: ## install dep
pnpm install

.PHONY: dev
dev: ## run TS (watch mode)
docker compose up
docker compose up --build

##@ Build

Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ You have now installed and deployed the Smartlook relay proxy. You can check if

| Name | Type | Default value | Description | Notes |
| --------------------- | -------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `ERROR_LOG_LEVEL` | `string` | `error` | [Nginx error log level](https://nginx.org/en/docs/ngx_core_module.html#error_log). One of `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. | Can be overridden |
| `CLIENT_MAX_BODY_SIZE` | `string` | `20m` | [Nginx client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). | Can be overridden |
| `PROXY_PORT` | `number` | `8000` | Port which will the HTTP server listen on | Can be overridden |
| `LISTEN_IPV6` | `boolean` | `false` (unset) | If set to `true`, the server will also listen on IPv6. The port will be the value of `PROXY_PORT` environment variable | Can be overridden |
| `WEB_SDK_HOST` | `string` | `web-sdk.smartlook.com` | Smartlook Web SDK host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `MANAGER_HOST` | `string` | `manager.eu.smartlook.cloud` | Smartlook Manager host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `WEB_SDK_WRITER_HOST` | `string` | `web-writer.eu.smartlook.cloud` | Smartlook Web Writer host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `ASSETS_PROXY_HOST` | `string` | `assets-proxy.smartlook.cloud` | Smartlook Assets Proxy host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `ERROR_LOG_LEVEL` | `string` | `error` | [Nginx error log level](https://nginx.org/en/docs/ngx_core_module.html#error_log). One of `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. | Can be safely overridden. |
| `CLIENT_MAX_BODY_SIZE` | `string` | `20m` | [Nginx client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). | Can be safely overridden. |
| `PROXY_PORT` | `number` | `8000` | Port which will the HTTP server listen on. | Can be safely overridden. |
| `LISTEN_IPV6` | `boolean` | `false` (unset) | If set to `true`, the server will also listen on IPv6. The port will be the value of `PROXY_PORT` environment variable. | Can be safely overridden. |
| `DNS_RESOLVER` | `string` | `1.1.1.1 1.0.0.1 valid=5m` | [Nginx resolver](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver). | Can be safely overridden. | |
| `WEB_SDK_HOST` | `string` | `web-sdk.smartlook.com` | Smartlook Web SDK host | Only edit this value if using a region other than EU, or if instructed by customer support. |
| `MANAGER_HOST` | `string` | `manager.eu.smartlook.cloud` | Smartlook Manager host | Only edit this value if using a region other than EU, or if instructed by customer support. |
| `WEB_SDK_WRITER_HOST` | `string` | `web-writer.eu.smartlook.cloud` | Smartlook Web Writer host | Only edit this value if using a region other than EU, or if instructed by customer support. |
| `ASSETS_PROXY_HOST` | `string` | `assets-proxy.smartlook.cloud` | Smartlook Assets Proxy host | Only edit this value if using a region other than EU, or if instructed by customer support. |

## Regional setup

Expand Down
8 changes: 5 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
version: '3'

services:
nginx:
image: nginx:1-alpine
build:
context: .
dockerfile: Dockerfile
container_name: nginx
restart: unless-stopped
ports:
- 80:8000
environment:
COMMIT_SHA: dev
PROXY_PORT: 8000
DNS_RESOLVER: '127.0.0.11 valid=0s'
LISTEN_IPV6: 'true'
CLIENT_MAX_BODY_SIZE: 20m
ERROR_LOG_LEVEL: error
WEB_SDK_HOST: web-sdk.smartlook.com
Expand Down
15 changes: 10 additions & 5 deletions nginx/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ set -e

nginx_conf=/etc/nginx/conf.d/default.conf

echo -e "\n\nSmartlook Relay Proxy - initializing..."

if [ "$LISTEN_IPV6" = "true" ]; then
echo ""
echo "Smartlook Relay Proxy"
echo "Environment variable LISTEN_IPV6 is set to ${LISTEN_IPV6}, enabling IPv6 support."
echo "Adding listen directive to nginx configuration."
echo ""
echo -e "\nEnvironment variable LISTEN_IPV6 is set to \`${LISTEN_IPV6}\`, enabling IPv6 support."
sed -i "/server {/a \ listen [::]:${PROXY_PORT};" $nginx_conf
fi

if [ -n "$DNS_RESOLVER" ]; then
echo -e "\nEnvironment variable DNS_RESOLVER is set to \`${DNS_RESOLVER}\`, replacing default resolver."
sed -i "s/resolver .*/resolver ${DNS_RESOLVER};/" $nginx_conf
fi

echo -e "\nSmartlook Relay Proxy - initialization finished. Starting nginx...\n\n"
66 changes: 31 additions & 35 deletions nginx/templates/default.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ map $status $loggable {

server {
listen ${PROXY_PORT};

proxy_cache off;

server_tokens off;
client_max_body_size ${CLIENT_MAX_BODY_SIZE};
Expand All @@ -18,78 +20,72 @@ server {
return 200 '{ "app": "smartlook-relay-proxy", "version": "${COMMIT_SHA}" }';
}

set $manager_host ${MANAGER_HOST};
set $assets_proxy_host ${ASSETS_PROXY_HOST};
set $web_sdk_writer_host ${WEB_SDK_WRITER_HOST};
set $mobile_sdk_writer_host ${MOBILE_SDK_WRITER_HOST};
set $web_sdk_host ${WEB_SDK_HOST};

proxy_pass_header Server;

resolver 1.1.1.1 1.0.0.1 valid=5m;

location /manager/ {
proxy_pass https://${MANAGER_HOST}/;
rewrite ^/manager(/.*)$ $1 break;
proxy_pass https://$manager_host;

proxy_set_header Host ${MANAGER_HOST};
proxy_set_header X-Forwarded-Host ${MANAGER_HOST};
proxy_set_header Host $manager_host;
proxy_set_header X-Forwarded-Host $manager_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By smartlook-relay-proxy;

proxy_pass_header Server;

proxy_redirect default;
}

location /assets/ {
proxy_pass https://${ASSETS_PROXY_HOST}/;
rewrite ^/assets(/.*)$ $1 break;
proxy_pass https://$assets_proxy_host;

proxy_set_header Host ${ASSETS_PROXY_HOST};
proxy_set_header X-Forwarded-Host ${ASSETS_PROXY_HOST};
proxy_set_header Host $assets_proxy_host;
proxy_set_header X-Forwarded-Host $assets_proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By smartlook-relay-proxy;

proxy_pass_header Server;

proxy_redirect default;
}

location /web-writer/ {
proxy_pass https://${WEB_SDK_WRITER_HOST}/;
rewrite ^/web-writer(/.*)$ $1 break;
proxy_pass https://$web_sdk_writer_host;

proxy_set_header Host ${WEB_SDK_WRITER_HOST};
proxy_set_header X-Forwarded-Host ${WEB_SDK_WRITER_HOST};
proxy_set_header Host $web_sdk_writer_host;
proxy_set_header X-Forwarded-Host $web_sdk_writer_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By smartlook-relay-proxy;

proxy_pass_header Server;

proxy_redirect off;
}

location /sdk-writer/ {
proxy_pass https://${MOBILE_SDK_WRITER_HOST}/;
rewrite ^/sdk-writer(/.*)$ $1 break;
proxy_pass https://$mobile_sdk_writer_host;

proxy_set_header Host ${MOBILE_SDK_WRITER_HOST};
proxy_set_header X-Forwarded-Host ${MOBILE_SDK_WRITER_HOST};
proxy_set_header Host $mobile_sdk_writer_host;
proxy_set_header X-Forwarded-Host $mobile_sdk_writer_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By smartlook-relay-proxy;

proxy_pass_header Server;

proxy_redirect default;
}

location / {
proxy_pass https://${WEB_SDK_HOST}/;
proxy_pass https://$web_sdk_host;

proxy_set_header Host ${WEB_SDK_HOST};
proxy_set_header X-Forwarded-Host ${WEB_SDK_HOST};
proxy_set_header Host $web_sdk_host;
proxy_set_header X-Forwarded-Host $web_sdk_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By smartlook-relay-proxy;

proxy_pass_header Server;

proxy_redirect default;
}
}
50 changes: 33 additions & 17 deletions test/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */

type StatusResponse = {
ok: boolean
version: string
}

type CommonStatusResponse = [StatusResponse, StatusResponse]

describe('Proxy server', () => {
it('Should return relay proxy status on /proxy/status', async () => {
const response = await fetch('http://localhost:80/proxy/status')
Expand All @@ -19,10 +27,10 @@ describe('Proxy server', () => {
fetch('http://localhost:80/manager/status'),
])

const [ogResponseJson, proxyResponseJson] = await Promise.all([
const [ogResponseJson, proxyResponseJson] = (await Promise.all([
ogResponse.json(),
proxyResponse.json(),
])
])) as CommonStatusResponse

expect(ogResponse.status).toBe(200)
expect(proxyResponse.status).toBe(200)
Expand All @@ -32,7 +40,9 @@ describe('Proxy server', () => {
expect(proxyResponse.headers.get('content-type')).toBe(
'application/json; charset=utf-8',
)
expect(ogResponseJson).toEqual(proxyResponseJson)

expect(ogResponseJson.ok).toBe(proxyResponseJson.ok)
expect(ogResponseJson.version).toBe(proxyResponseJson.version)
})

it('Should return assets proxy status on /assets/status', async () => {
Expand All @@ -41,18 +51,20 @@ describe('Proxy server', () => {
fetch('http://localhost:80/assets/status'),
])

const [ogResponseJson, proxyResponseJson] = await Promise.all([
const [ogResponseJson, proxyResponseJson] = (await Promise.all([
ogResponse.json(),
proxyResponse.json(),
])
])) as CommonStatusResponse

expect(ogResponse.status).toBe(200)
expect(proxyResponse.status).toBe(200)
expect(ogResponse.headers.get('content-type')).toBe('application/json')
expect(proxyResponse.headers.get('content-type')).toBe(
'application/json',
)
expect(ogResponseJson).toEqual(proxyResponseJson)

expect(ogResponseJson.ok).toBe(proxyResponseJson.ok)
expect(ogResponseJson.version).toBe(proxyResponseJson.version)
})

it('Should return web writer status on /web-writer/status', async () => {
Expand All @@ -61,10 +73,10 @@ describe('Proxy server', () => {
fetch('http://localhost:80/web-writer/status'),
])

const [ogResponseJson, proxyResponseJson] = await Promise.all([
ogResponse.json() as Promise<{ version: string }>,
proxyResponse.json() as Promise<{ version: string }>,
])
const [ogResponseJson, proxyResponseJson] = (await Promise.all([
ogResponse.json(),
proxyResponse.json(),
])) as CommonStatusResponse

expect(ogResponse.status).toBe(200)
expect(proxyResponse.status).toBe(200)
Expand All @@ -74,7 +86,9 @@ describe('Proxy server', () => {
expect(proxyResponse.headers.get('content-type')).toBe(
'application/json; charset=utf-8',
)
expect(ogResponseJson.version).toEqual(proxyResponseJson.version)

expect(ogResponseJson.ok).toBe(proxyResponseJson.ok)
expect(ogResponseJson.version).toBe(proxyResponseJson.version)
})

it('Should return sdk writer status on /sdk-writer/status', async () => {
Expand All @@ -83,10 +97,10 @@ describe('Proxy server', () => {
fetch('http://localhost:80/sdk-writer/status'),
])

const [ogResponseJson, proxyResponseJson] = await Promise.all([
const [ogResponseJson, proxyResponseJson] = (await Promise.all([
ogResponse.json(),
proxyResponse.json(),
])
])) as CommonStatusResponse

expect(ogResponse.status).toBe(200)
expect(proxyResponse.status).toBe(200)
Expand All @@ -96,7 +110,8 @@ describe('Proxy server', () => {
expect(proxyResponse.headers.get('content-type')).toBe(
'application/json; charset=utf-8',
)
expect(ogResponseJson).toEqual(proxyResponseJson)
expect(ogResponseJson.ok).toBe(proxyResponseJson.ok)
expect(ogResponseJson.version).toBe(proxyResponseJson.version)
})

it('Should return web sdk status on /status', async () => {
Expand All @@ -105,18 +120,19 @@ describe('Proxy server', () => {
fetch('http://localhost:80/status'),
])

const [ogResponseJson, proxyResponseJson] = await Promise.all([
const [ogResponseJson, proxyResponseJson] = (await Promise.all([
ogResponse.json(),
proxyResponse.json(),
])
])) as CommonStatusResponse

expect(ogResponse.status).toBe(200)
expect(proxyResponse.status).toBe(200)
expect(ogResponse.headers.get('content-type')).toBe('application/json')
expect(proxyResponse.headers.get('content-type')).toBe(
'application/json',
)
expect(ogResponseJson).toEqual(proxyResponseJson)
expect(ogResponseJson.ok).toBe(proxyResponseJson.ok)
expect(ogResponseJson.version).toBe(proxyResponseJson.version)
})

it('Should return web sdk recorder on /recorder.js', async () => {
Expand Down

0 comments on commit 2268331

Please sign in to comment.