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.



34
35
36
37
38
39
40
# File 'lib/falcon/controller/virtual.rb', line 34

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.



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

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.



73
74
75
# File 'lib/falcon/controller/virtual.rb', line 73

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.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/falcon/controller/virtual.rb', line 80

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.



61
62
63
64
65
66
67
68
69
# File 'lib/falcon/controller/virtual.rb', line 61

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