net/server.lua
author Matthew Wild <mwild1@gmail.com>
Mon, 20 Feb 2023 18:10:15 +0000
branch0.12
changeset 12898 0598d822614f
parent 11768 e2650d59db2d
child 12485 2ee27587fec7
permissions -rw-r--r--
mod_websocket: Fire pre-session-close event (fixes #1800) This event was added in a7c183bb4e64 and is required to make mod_smacks know that a session was intentionally closed and shouldn't be hibernated (see fcea4d9e7502). Because this was missing from mod_websocket's session.close(), mod_smacks would always attempt to hibernate websocket sessions even if they closed cleanly. That mod_websocket has its own copy of session.close() is something to fix another day (probably not in the stable branch). So for now this commit makes the minimal change to get things working again. Thanks to Damian and the Jitsi team for reporting.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2925
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     1
-- Prosody IM
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5531
diff changeset
     4
--
2925
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     6
-- COPYING file in the source package for more information.
692b3c6c5bd2 Merge 0.6->0.7
Matthew Wild <mwild1@gmail.com>
parents: 2645 2923
diff changeset
     7
--
2162
22b6b1899a55 net.server: Log an error when libevent is requested, but luaevent is unavailable, and don't load luaevent when not requested.
Waqas Hussain <waqas20@gmail.com>
parents: 2136
diff changeset
     8
9218
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
     9
if not (prosody and prosody.config_loaded) then
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    10
	-- This module only supports loading inside Prosody, outside Prosody
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    11
	-- you should directly require net.server_select or server_event, etc.
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    12
	error(debug.traceback("Loading outside Prosody or Prosody not yet initialized"), 0);
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    13
end
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    14
8714
9932a2a5b6de net.server: Init a local logger (fixes traceback on attempt to warn about missing luaevent due to later loggingmanager initialization)
Kim Alvefur <zash@zash.se>
parents: 8703
diff changeset
    15
local log = require "util.logger".init("net.server");
10857
0107ed6744aa net.server: Switch to epoll backend by default
Matthew Wild <mwild1@gmail.com>
parents: 9218
diff changeset
    16
11767
e273ef869794 net.server: Pikc server_epoll as unconditional default
Kim Alvefur <zash@zash.se>
parents: 11766
diff changeset
    17
local default_backend = "epoll";
10857
0107ed6744aa net.server: Switch to epoll backend by default
Matthew Wild <mwild1@gmail.com>
parents: 9218
diff changeset
    18
0107ed6744aa net.server: Switch to epoll backend by default
Matthew Wild <mwild1@gmail.com>
parents: 9218
diff changeset
    19
local server_type = require "core.configmanager".get("*", "network_backend") or default_backend;
9218
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    20
b087b5047f86 net.server: Throw error when loading outside Prosody or Prosody config not loaded
Matthew Wild <mwild1@gmail.com>
parents: 8714
diff changeset
    21
if require "core.configmanager".get("*", "use_libevent") then
8703
d611c46c6787 Backed out changeset a0f728c3aa69 in favor of 580c13ed0ca1
Kim Alvefur <zash@zash.se>
parents: 8689
diff changeset
    22
	server_type = "event";
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    23
end
2094
c69cb5c171e0 net.server: New net.server to choose the appropriate library from server_select/server_event based on the availability of luaevent and the use_libevent config option
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    25
if server_type == "event" then
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    26
	if not pcall(require, "luaevent.core") then
11766
54530085dffe net.server: Fall back to default backend from libevent instead of always select
Kim Alvefur <zash@zash.se>
parents: 10857
diff changeset
    27
		log("error", "libevent not found, falling back to %s", default_backend);
54530085dffe net.server: Fall back to default backend from libevent instead of always select
Kim Alvefur <zash@zash.se>
parents: 10857
diff changeset
    28
		server_type = default_backend;
2162
22b6b1899a55 net.server: Log an error when libevent is requested, but luaevent is unavailable, and don't load luaevent when not requested.
Waqas Hussain <waqas20@gmail.com>
parents: 2136
diff changeset
    29
	end
22b6b1899a55 net.server: Log an error when libevent is requested, but luaevent is unavailable, and don't load luaevent when not requested.
Waqas Hussain <waqas20@gmail.com>
parents: 2136
diff changeset
    30
end
22b6b1899a55 net.server: Log an error when libevent is requested, but luaevent is unavailable, and don't load luaevent when not requested.
Waqas Hussain <waqas20@gmail.com>
parents: 2136
diff changeset
    31
2094
c69cb5c171e0 net.server: New net.server to choose the appropriate library from server_select/server_event based on the availability of luaevent and the use_libevent config option
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
local server;
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    33
local set_config;
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    34
if server_type == "event" then
4811
1d1fdfa29f06 net.server: server_select != server_event (thanks Nulani, Florob)
Matthew Wild <mwild1@gmail.com>
parents: 4808
diff changeset
    35
	server = require "net.server_event";
4808
07d0a3a75c8a net.server, net.timer, net.server_select: Rearrange dependencies between these three modules. server.addtimer() is no longer a public function (renamed to _addtimer) and is not available at all from server_event (compat code removed to prevent traceback) (thanks Nulani)
Matthew Wild <mwild1@gmail.com>
parents: 3461
diff changeset
    36
5385
d663483036db net.server, _select: Reorganise configuration of server_select to be more like server_event
Kim Alvefur <zash@zash.se>
parents: 5383
diff changeset
    37
	local defaults = {};
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    38
	for k,v in pairs(server.cfg) do
5385
d663483036db net.server, _select: Reorganise configuration of server_select to be more like server_event
Kim Alvefur <zash@zash.se>
parents: 5383
diff changeset
    39
		defaults[k] = v;
d663483036db net.server, _select: Reorganise configuration of server_select to be more like server_event
Kim Alvefur <zash@zash.se>
parents: 5383
diff changeset
    40
	end
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    41
	function set_config(settings)
7546
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    42
		local event_settings = {
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    43
			ACCEPT_DELAY = settings.accept_retry_interval;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    44
			ACCEPT_QUEUE = settings.tcp_backlog;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    45
			CLEAR_DELAY = settings.event_clear_interval;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    46
			CONNECT_TIMEOUT = settings.connect_timeout;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    47
			DEBUG = settings.debug;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    48
			HANDSHAKE_TIMEOUT = settings.ssl_handshake_timeout;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    49
			MAX_CONNECTIONS = settings.max_connections;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    50
			MAX_HANDSHAKE_ATTEMPTS = settings.max_ssl_handshake_roundtrips;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    51
			MAX_READ_LENGTH = settings.max_receive_buffer_size;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    52
			MAX_SEND_LENGTH = settings.max_send_buffer_size;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    53
			READ_TIMEOUT = settings.read_timeout;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    54
			WRITE_TIMEOUT = settings.send_timeout;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    55
		};
5198
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
    56
7546
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    57
		for k,default in pairs(defaults) do
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    58
			server.cfg[k] = event_settings[k] or default;
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    59
		end
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    60
	end
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    61
elseif server_type == "select" then
11768
e2650d59db2d net.server_select: Deprecate and warn about it
Kim Alvefur <zash@zash.se>
parents: 11767
diff changeset
    62
	-- TODO Remove completely.
e2650d59db2d net.server_select: Deprecate and warn about it
Kim Alvefur <zash@zash.se>
parents: 11767
diff changeset
    63
	log("warn", "select is deprecated, the new default is epoll. For more info see https://prosody.im/doc/network_backend");
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    64
	server = require "net.server_select";
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    65
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    66
	local defaults = {};
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    67
	for k,v in pairs(server.getsettings()) do
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    68
		defaults[k] = v;
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    69
	end
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
    70
	function set_config(settings)
7546
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    71
		local select_settings = {};
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    72
		for k,default in pairs(defaults) do
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    73
			select_settings[k] = settings[k] or default;
5198
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
    74
		end
7546
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    75
		server.changesettings(select_settings);
23a8a26e8912 net.server: Fix whitespace
Kim Alvefur <zash@zash.se>
parents: 7102
diff changeset
    76
	end
2094
c69cb5c171e0 net.server: New net.server to choose the appropriate library from server_select/server_event based on the availability of luaevent and the use_libevent config option
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
else
7548
0941b3ab77c0 net.server: Allow arbitrary network backends to be configured
Kim Alvefur <zash@zash.se>
parents: 7547
diff changeset
    78
	server = require("net.server_"..server_type);
0941b3ab77c0 net.server: Allow arbitrary network backends to be configured
Kim Alvefur <zash@zash.se>
parents: 7547
diff changeset
    79
	set_config = server.set_config;
7549
9606a99f8617 net.server: Monkey-patch in a fallback get_backend method if missing
Kim Alvefur <zash@zash.se>
parents: 7548
diff changeset
    80
	if not server.get_backend then
9606a99f8617 net.server: Monkey-patch in a fallback get_backend method if missing
Kim Alvefur <zash@zash.se>
parents: 7548
diff changeset
    81
		function server.get_backend()
9606a99f8617 net.server: Monkey-patch in a fallback get_backend method if missing
Kim Alvefur <zash@zash.se>
parents: 7548
diff changeset
    82
			return server_type;
9606a99f8617 net.server: Monkey-patch in a fallback get_backend method if missing
Kim Alvefur <zash@zash.se>
parents: 7548
diff changeset
    83
		end
9606a99f8617 net.server: Monkey-patch in a fallback get_backend method if missing
Kim Alvefur <zash@zash.se>
parents: 7548
diff changeset
    84
	end
2094
c69cb5c171e0 net.server: New net.server to choose the appropriate library from server_select/server_event based on the availability of luaevent and the use_libevent config option
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
end
c69cb5c171e0 net.server: New net.server to choose the appropriate library from server_select/server_event based on the availability of luaevent and the use_libevent config option
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
6485
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    87
-- If server.hook_signal exists, replace signal.signal()
6488
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
    88
local has_signal, signal = pcall(require, "util.signal");
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
    89
if has_signal then
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
    90
	if server.hook_signal then
6485
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    91
		function signal.signal(signal_id, handler)
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    92
			if type(signal_id) == "string" then
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    93
				signal_id = signal[signal_id:upper()];
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    94
			end
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    95
			if type(signal_id) ~= "number" then
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    96
				return false, "invalid-signal";
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    97
			end
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    98
			return server.hook_signal(signal_id, handler);
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
    99
		end
6488
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   100
	else
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   101
		server.hook_signal = signal.signal;
6485
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
   102
	end
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
   103
else
6488
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   104
	if not server.hook_signal then
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   105
		server.hook_signal = function()
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   106
			return false, "signal hooking not supported"
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   107
		end
4224abbf0fdd net/server: Handle lack of util.signal correctly
daurnimator <quae@daurnimator.com>
parents: 6487
diff changeset
   108
	end
6485
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
   109
end
410067cdeb2f net/server: If server.hook_signal exists, overwrite signal.signal; else make server.hook_signal == signal.signal
daurnimator <quae@daurnimator.com>
parents: 6483
diff changeset
   110
7547
fb68aad9dc4d net.server: Only update configuration if server backend supports changing settings
Kim Alvefur <zash@zash.se>
parents: 7546
diff changeset
   111
if prosody and set_config then
5198
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   112
	local config_get = require "core.configmanager".get;
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   113
	local function load_config()
5383
143670deee3e net.server: No sections in config anymore
Kim Alvefur <zash@zash.se>
parents: 5284
diff changeset
   114
		local settings = config_get("*", "network_settings") or {};
6483
37b12475f648 net/server: Split up different backends in a nicer way. Add global config option 'server'
daurnimator <quae@daurnimator.com>
parents: 5776
diff changeset
   115
		return set_config(settings);
5198
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   116
	end
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   117
	load_config();
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   118
	prosody.events.add_handler("config-reloaded", load_config);
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   119
end
430797a8fc81 net.server: Make server_* configurable in the config file.
Kim Alvefur <zash@zash.se>
parents: 4811
diff changeset
   120
2136
23c687039652 net.server: Add some comments to explain to waqas how it all works :)
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
   121
-- require "net.server" shall now forever return this,
23c687039652 net.server: Add some comments to explain to waqas how it all works :)
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
   122
-- ie. server_select or server_event as chosen above.
2645
625d02b2a1a0 net.server: Remove redundant commented code and some trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2435
diff changeset
   123
return server;