forked from fedwiki/wiki
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfarm.coffee
More file actions
71 lines (61 loc) · 2.35 KB
/
Copy pathfarm.coffee
File metadata and controls
71 lines (61 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# **farm.coffee**
# The farm module works by putting a bouncy host based proxy
# in front of servers that it creates
path = require 'path'
bouncy = require 'bouncy'
server = require 'wiki-server'
module.exports = exports = (argv) ->
# Map incoming hosts to their wiki's port
hosts = {}
# Keep an array of servers that are currently active
runningServers = []
# Get the next available port.
nextport = do ->
# Start port as farm port -1 so it returns the original farm
# port the first time it is used.
# TODO: Call out to the os to make sure we return an open and valid port.
port = argv.farmPort - 1
-> port += 1
# Bouncy watches for incoming requests on the listen port at the bottom,
# and passes them to the callback it's called with,
# redirecting the requests at the port specified when
# the bounce function is called.
bouncy( (req, bounce) ->
# If the incoming request has a host, asign it to incHost
# otherwise do nothing and return.
if req.headers?.host
incHost = req.headers.host
else
return
# If the host starts with "www." treat it the same as if it didn't
if incHost[0..3] is "www."
incHost = incHost[4..]
# if we already have a port for this host, forward the request to it.
if hosts[incHost]
bounce(argv.host, hosts[incHost])
else
hosts[incHost] = nextport()
# Create a new options object, copy over the options used to start the
# farm, and modify them to make sense for servers spawned from the farm.
newargv = {}
for key, value of argv
newargv[key] = value
newargv.port = hosts[incHost]
newargv.data = if argv.data
path.join(argv.data, incHost.split(':')[0])
else
path.join(argv.root, 'data', incHost.split(':')[0])
newargv.url = "http://#{incHost}"
# Create a new server, add it to the list of servers, and
# once it's ready send the request to it.
local = server(newargv)
runningServers.push(local)
# patch in new neighbors
if argv.autoseed
neighbors = if argv.neighbors then argv.neighbors + ',' else ''
neighbors += Object.keys(hosts).join(',')
runningServers.forEach (server) ->
server.startOpts.neighbors = neighbors
local.once "listening", ->
bounce(argv.host, hosts[incHost])
).listen(argv.port, argv.host)