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": [{
"url": "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

@ -45,7 +45,7 @@ export default class Input extends React.PureComponent {
type="text"
value={message}
/>
<input type="submit" value="Send"/>
<input type="submit" value="Send" />
</form>
)
}

View File

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

View File

@ -1,2 +1,3 @@
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
}
export const baseUrl = valueOf('baseUrl')
export const callId = valueOf('callId')
export const iceServers = JSON.parse(valueOf('iceServers'))

View File

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

View File

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

View File

@ -1,22 +1,32 @@
#!/usr/bin/env node
'use strict'
const config = require('config')
const debug = require('debug')('peercalls')
const express = require('express')
const handleSocket = require('./socket.js')
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 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.baseUrl = BASE_URL
app.set('view engine', 'pug')
app.set('views', path.join(__dirname, '../views'))
app.use('/res', express.static(path.join(__dirname, '../res')))
app.use('/static', express.static(path.join(__dirname, '../../build')))
app.use('/call', require('./routes/call.js'))
app.use('/', require('./routes/index.js'))
const router = express.Router()
router.use('/res', express.static(path.join(__dirname, '../res')))
router.use('/static', express.static(path.join(__dirname, '../../build')))
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))

View File

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

View File

@ -1,2 +1,2 @@
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="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="icon" sizes="256x256" href="../res/icon.png")
link(rel="stylesheet" type="text/css" href="../static/style.css")
link(rel="apple-touch-icon" href=baseUrl + "/res/icon.png")
link(rel="icon" sizes="256x256" href=baseUrl + "/res/icon.png")
link(rel="stylesheet" type="text/css" href=baseUrl + "/static/style.css")
body.call
input#baseUrl(type="hidden" value=baseUrl)
input#callId(type="hidden" value=callId)
input#iceServers(type="hidden" value=JSON.stringify(iceServers))
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="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="icon" sizes="256x256" href="res/icon.png")
link(rel="stylesheet" type="text/css" href="static/style.css")
link(rel="apple-touch-icon" href=baseUrl + "res/icon.png")
link(rel="icon" sizes="256x256" href=baseUrl + "res/icon.png")
link(rel="stylesheet" type="text/css" href=baseUrl + "/static/style.css")
body
include ./_fork.pug
#container
form#form(method="get" action="call")
form#form(method="get" action=baseUrl + "/call")
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.
input(type="submit" value="New Session")