Class: Falcon::Controller::Virtual

Inherits:
Async::Container::Controller
  • Object
show all
Defined in:
lib/falcon/controller/virtual.rb

Overview

A controller which mananages several virtual hosts. Spawns instances of Proxy and Redirect to handle incoming requests.

A virtual host is an application bound to a specific authority (essentially a hostname). The virtual controller manages multiple hosts and allows a single server to host multiple applications easily.

Instance Method Summary collapse

Constructor Details

#initialize(command, **options) ⇒ Virtual

Initialize the virtual controller.



17
18
19
20
21
22
23
# File 'lib/falcon/controller/virtual.rb', line 17

def initialize(command, **options)
	@command = command
	
	super(**options)
	
	trap(SIGHUP, &self.method(:reload))
end

Instance Method Details

#assume_privileges(path) ⇒ Object

Drop privileges according to the user and group of the specified path.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/falcon/controller/virtual.rb', line 27

def assume_privileges(path)
	stat = File.stat(path)
	
	Process::GID.change_privilege(stat.gid)
	Process::UID.change_privilege(stat.uid)
	
	home = Etc.getpwuid(stat.uid).dir
	
	return {
		'HOME' => home,
	}
end

#falcon_pathObject

The path to the falcon executable from this gem.



56
57
58
# File 'lib/falcon/controller/virtual.rb', line 56

def falcon_path
	File.expand_path("../../../bin/falcon", __dir__)
end

#setup(container) ⇒ Object

Setup the container with Redirect and Proxy child processes. These processes are gracefully restarted if they are already running.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/falcon/controller/virtual.rb', line 63

def setup(container)
	if proxy = container[:proxy]
		proxy.kill(:HUP)
	end
	
	if redirect = container[:redirect]
		redirect.kill(:HUP)
	end
	
	container.reload do
		@command.resolved_paths do |path|
			path = File.expand_path(path)
			root = File.dirname(path)
			
			spawn(path, container, chdir: root)
		end
		
		container.spawn(name: "Falcon Redirector", restart: true, key: :redirect) do |instance|
			instance.exec(falcon_path, "redirect",
				"--bind", @command.bind_insecure,
				"--timeout", @command.timeout.to_s,
				"--redirect", @command.bind_secure,
				*@command.paths, ready: false
			)
		end
		
		container.spawn(name: "Falcon Proxy", restart: true, key: :proxy) do |instance|
			instance.exec(falcon_path, "proxy",
				"--bind", @command.bind_secure,
				"--timeout", @command.timeout.to_s,
				*@command.paths, ready: false
			)
		end
	end
end

#spawn(path, container, **options) ⇒ Object

Spawn an application instance from the specified path.



44
45
46
47
48
49
50
51
52
# File 'lib/falcon/controller/virtual.rb', line 44

def spawn(path, container, **options)
	container.spawn(name: "Falcon Application", restart: true, key: path) do |instance|
		env = assume_privileges(path)
		
		instance.exec(env,
			"bundle", "exec", "--keep-file-descriptors",
			path, ready: false, **options)
	end
end