Add ability to set custom base url (reverse proxy)

The URL can be set by either:

1. Setting the `baseUrl` property in `config/default.json`,
   `config/local.json`, or `config/${NODE_ENV}.json` file.
2. Setting the `PEERCALLS_BASE_URL` environment variable.

For example:

```
$ PEERCALLS_BASE_URL=/test1/test2 npm start

> peer-calls@2.0.3 start /peer-calls
> node src/index.js

  peercalls WebSocket URL: /test1/test2/ws +0ms
  peercalls Listening on: 3000 +76ms
```

In this case, opening `http://localhost:3000/test1/test2` would open the
homepage.

Fix #42
This commit is contained in:
Jerko Steiner 2017-08-17 20:14:17 -04:00
parent 434bb2e844
commit 795d31f89f
14 changed files with 3293 additions and 475 deletions

View File

@ -0,0 +1,4 @@
{
"baseUrl": "PEERCALLS_BASE_URL",
"iceServers": "PEERCALLS_ICE_SERVERS"
}

View File

@ -1,4 +1,5 @@
{ {
"baseUrl": "",
"iceServers": [{ "iceServers": [{
"url": "stun:stun.l.google.com:19302", "url": "stun:stun.l.google.com:19302",
"urls": "stun:stun.l.google.com:19302" "urls": "stun:stun.l.google.com:19302"

3694
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,9 @@ jest.mock('../../window.js')
import * as StreamActions from '../../actions/StreamActions.js' import * as StreamActions from '../../actions/StreamActions.js'
import reducers from '../index.js' import reducers from '../index.js'
import { MediaStream } from '../../window.js' import { createObjectURL, MediaStream } from '../../window.js'
import { applyMiddleware, createStore } from 'redux' import { applyMiddleware, createStore } from 'redux'
import { create } from '../../middlewares.js' import { create } from '../../middlewares.js'
import { createObjectURL } from '../../window.js'
describe('reducers/alerts', () => { describe('reducers/alerts', () => {

View File

@ -1,2 +1,3 @@
import SocketIOClient from 'socket.io-client' import SocketIOClient from 'socket.io-client'
export default new SocketIOClient() import { baseUrl } from './window.js'
export default new SocketIOClient('', { path: baseUrl + '/ws' })

View File

@ -37,6 +37,7 @@ export const valueOf = id => {
return el && el.value return el && el.value
} }
export const baseUrl = valueOf('baseUrl')
export const callId = valueOf('callId') export const callId = valueOf('callId')
export const iceServers = JSON.parse(valueOf('iceServers')) export const iceServers = JSON.parse(valueOf('iceServers'))

View File

@ -47,7 +47,7 @@ footer {
} }
body.call { body.call {
background-image: url('/res/peer-calls.svg'); background-image: url('../res/peer-calls.svg');
background-size: 200px; background-size: 200px;
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@ -5,10 +5,13 @@ jest.mock('socket.io', () => {
jest.mock('../socket.js') jest.mock('../socket.js')
const app = require('../app.js') const app = require('../app.js')
const config = require('config')
const handleSocket = require('../socket.js') const handleSocket = require('../socket.js')
const io = require('socket.io')() const io = require('socket.io')()
const request = require('supertest') const request = require('supertest')
const BASE_URL = config.get('baseUrl')
describe('server/app', () => { describe('server/app', () => {
describe('GET /', () => { describe('GET /', () => {
@ -27,14 +30,7 @@ describe('server/app', () => {
return request(app) return request(app)
.get('/call') .get('/call')
.expect(302) .expect(302)
.expect('location', /^call\/[0-9a-f-]{36}$/) .expect('location', new RegExp(`^${BASE_URL}/call/[0-9a-f-]{36}$`))
})
it('redirects to relative url when slash', () => {
return request(app)
.get('/call/')
.expect(302)
.expect('location', /[0-9a-f-]{36}$/)
}) })
}) })

View File

@ -1,22 +1,32 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict' 'use strict'
const config = require('config')
const debug = require('debug')('peercalls')
const express = require('express') const express = require('express')
const handleSocket = require('./socket.js') const handleSocket = require('./socket.js')
const path = require('path') const path = require('path')
const BASE_URL = config.get('baseUrl')
const SOCKET_URL = `${BASE_URL}/ws`
debug(`WebSocket URL: ${SOCKET_URL}`)
const app = express() const app = express()
const http = require('http').Server(app) const http = require('http').Server(app)
const io = require('socket.io')(http) const io = require('socket.io')(http, { path: SOCKET_URL })
app.locals.version = require('../../package.json').version app.locals.version = require('../../package.json').version
app.locals.baseUrl = BASE_URL
app.set('view engine', 'pug') app.set('view engine', 'pug')
app.set('views', path.join(__dirname, '../views')) app.set('views', path.join(__dirname, '../views'))
app.use('/res', express.static(path.join(__dirname, '../res'))) const router = express.Router()
app.use('/static', express.static(path.join(__dirname, '../../build'))) router.use('/res', express.static(path.join(__dirname, '../res')))
app.use('/call', require('./routes/call.js')) router.use('/static', express.static(path.join(__dirname, '../../build')))
app.use('/', require('./routes/index.js')) router.use('/call', require('./routes/call.js'))
router.use('/', require('./routes/index.js'))
app.use(BASE_URL, router)
io.on('connection', socket => handleSocket(socket, io)) io.on('connection', socket => handleSocket(socket, io))

View File

@ -5,12 +5,11 @@ const turn = require('../turn.js')
const router = require('express').Router() const router = require('express').Router()
const uuid = require('uuid') const uuid = require('uuid')
const BASE_URL = config.get('baseUrl')
const cfgIceServers = config.get('iceServers') const cfgIceServers = config.get('iceServers')
router.get('/', (req, res) => { router.get('/', (req, res) => {
let prefix = 'call/' res.redirect(`${BASE_URL}/call/${uuid.v4()}`)
if (req.originalUrl.charAt(req.originalUrl.length - 1) === '/') prefix = ''
res.redirect(prefix + uuid.v4())
}) })
router.get('/:callId', (req, res) => { router.get('/:callId', (req, res) => {

View File

@ -1,2 +1,2 @@
a#github-ribbon(href="https://github.com/jeremija/peer-calls" target="_blank") a#github-ribbon(href="https://github.com/jeremija/peer-calls" target="_blank")
img(src="res/fork.png" alt="Fork me on GitHub") img(src=baseUrl + "/res/fork.png" alt="Fork me on GitHub")

View File

@ -6,14 +6,15 @@ html
meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no") meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")
meta(name="mobile-web-app-capable" content="yes") meta(name="mobile-web-app-capable" content="yes")
meta(name="apple-mobile-web-app-capable" content="yes") meta(name="apple-mobile-web-app-capable" content="yes")
link(rel="apple-touch-icon" href="../res/icon.png") link(rel="apple-touch-icon" href=baseUrl + "/res/icon.png")
link(rel="icon" sizes="256x256" href="../res/icon.png") link(rel="icon" sizes="256x256" href=baseUrl + "/res/icon.png")
link(rel="stylesheet" type="text/css" href="../static/style.css") link(rel="stylesheet" type="text/css" href=baseUrl + "/static/style.css")
body.call body.call
input#baseUrl(type="hidden" value=baseUrl)
input#callId(type="hidden" value=callId) input#callId(type="hidden" value=callId)
input#iceServers(type="hidden" value=JSON.stringify(iceServers)) input#iceServers(type="hidden" value=JSON.stringify(iceServers))
div#container div#container
script(src='../static/index.js') script(src=baseUrl + '/static/index.js')

View File

@ -7,18 +7,18 @@ html
meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no") meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")
meta(name="mobile-web-app-capable" content="yes") meta(name="mobile-web-app-capable" content="yes")
meta(name="apple-mobile-web-app-capable" content="yes") meta(name="apple-mobile-web-app-capable" content="yes")
link(rel="apple-touch-icon" href="res/icon.png") link(rel="apple-touch-icon" href=baseUrl + "res/icon.png")
link(rel="icon" sizes="256x256" href="res/icon.png") link(rel="icon" sizes="256x256" href=baseUrl + "res/icon.png")
link(rel="stylesheet" type="text/css" href="static/style.css") link(rel="stylesheet" type="text/css" href=baseUrl + "/static/style.css")
body body
include ./_fork.pug include ./_fork.pug
#container #container
form#form(method="get" action="call") form#form(method="get" action=baseUrl + "/call")
h1 h1
img(src="res/peer-calls.svg" width="100%" alt="Peer Calls") img(src=baseUrl + "/res/peer-calls.svg" width="100%" alt="Peer Calls")
p Group peer-to-peer calls for everyone. Create a private room. Share the link. p Group peer-to-peer calls for everyone. Create a private room. Share the link.
input(type="submit" value="New Session") input(type="submit" value="New Session")