# # # patch "doc/documentation.html" # from [5c0ee5ef7d5ed30a0d018f27c862cb73d3c54a89] # to [222c3661ca7cb6438d172a8a0c022d3fa4878982] # # patch "src/administrator.cc" # from [96ff493c2ebd661a99f15114338c0d595b160ceb] # to [c87e8a0f48349476ae5793a6ad99d6cfe08afe07] # # patch "src/server_manager.cc" # from [1d4f3adcaa7e1b3042e9b57387b9025c01144781] # to [99fb14619b14c4ebccaf1fe7775a08452b99ad70] # # patch "src/server_manager.hh" # from [5808402a36b08a92cf0ed904d5c0a88807238be5] # to [8d75c6dae7590e8ecec5a7ae22b1ee585d1e78ec] # # patch "test/run-tests.sh" # from [788d4990135232caa3177afe126c4e90a0074b3f] # to [db2dc5562ef5a681219cd92a7d0fdd539bc1c988] # # patch "test/test1/script.txt" # from [4a9bfacbd8cbb34c591ceef0d385290db2b4bac4] # to [33b921a8fc5d016e41c354563db7dafe75f838b2] # ============================================================ --- doc/documentation.html 5c0ee5ef7d5ed30a0d018f27c862cb73d3c54a89 +++ doc/documentation.html 222c3661ca7cb6438d172a8a0c022d3fa4878982 @@ -1,6 +1,7 @@ + Usher Documentation

Introduction

@@ -101,8 +102,8 @@ things. If the given username and passwo things. If the given username and password don't match any of the userpass lines in the config file, the connection will be closed.
MATCH host pattern
Looks up the name of the server that would be used for an -incoming connection having the given host and pattern. Returns the name -if a match is found, or a blank line if no match is found.
+incoming connection having the given host and pattern. Returns "OK: <servername>" +if a match is found, or "ERROR: <message>" if no match is found.
STATUS [servername]
Get the status of a particular server, or of the usher as a whole if no server is specified.
If a server is specified, the result will be one of
============================================================ --- src/administrator.cc 96ff493c2ebd661a99f15114338c0d595b160ceb +++ src/administrator.cc c87e8a0f48349476ae5793a6ad99d6cfe08afe07 @@ -86,11 +86,12 @@ administrator::process(cstate & cs) iss>>host; string pattern; iss>>pattern; - string const *name = manager.lookup_server_name(host, pattern); - if (name) - cs.buf = *name + "\n"; - else - cs.buf = "\n"; + try { + string const &name = manager.lookup_server_name(host, pattern); + cs.buf = "OK: " + name + "\n"; + } catch (errstr & e) { + cs.buf = "ERROR: " + e.name + "\n"; + } } else if (cmd == "STATUS") { string srv; iss>>srv; ============================================================ --- src/server_manager.cc 1d4f3adcaa7e1b3042e9b57387b9025c01144781 +++ src/server_manager.cc 99fb14619b14c4ebccaf1fe7775a08452b99ad70 @@ -173,58 +173,88 @@ shared_ptr } shared_ptr -server_manager::find_server(string const &host, +server_manager::find_server(string peername, string const &pattern) { + if (servers.empty()) + throw errstr("There are no servers defined."); + // peername can be a bare host:port, a scheme://host:port, + // or a scheme://host:port/name + if (peername.find('/') != string::npos) { + size_t scheme_delim = peername.find("://"); + if (scheme_delim != string::npos && scheme_delim < peername.size()-3) { + size_t slash = peername.find('/', scheme_delim + 3); + if (slash != string::npos && slash < peername.size()-1) { + string name(peername, slash+1); + name = lowercase(name); + map >::iterator iter = by_name.find(name); + if (iter != by_name.end()) + return iter->second; + else + throw errstr("No server named '" + name + "'"); + } else { + peername.erase(0, scheme_delim + 3); + } + } + } shared_ptr srv; - if (!host.empty() && !by_host.empty()) - srv = find_by_prefix(by_host, lowercase(host)); - if (!srv && !pattern.empty() && !by_pattern.empty()) + if (!peername.empty() && !by_host.empty()) { + srv = find_by_prefix(by_host, lowercase(peername)); + if (srv) + return srv; + else if (by_pattern.empty()) + throw errstr("No server for hostname '" + peername + "'"); + } + if (!pattern.empty() && !by_pattern.empty()) { srv = find_by_prefix(by_pattern, pattern); - return srv; + if (srv) + return srv; + else if (by_host.empty()) + throw errstr("No server for pattern '" + pattern + "'"); + } + if (srv) + return srv; + else + throw errstr("No server for host '" + peername + "' or pattern '" + pattern + "'"); } -string const * -server_manager::lookup_server_name(string const &host, +string const & +server_manager::lookup_server_name(string const &peername, string const &pattern) { - shared_ptr srv = find_server(host, pattern); + shared_ptr srv = find_server(peername, pattern); typedef map, serverdata>::iterator iter; iter i = servers.find(srv); if (i != servers.end()) - return &(i->second.name); + return i->second.name; else - return 0; + throw errstr("server_manager is inconsistent"); } serversock -server_manager::connect_to_server(string const &host, +server_manager::connect_to_server(string const &peername, string const &pattern, string const &name) { if (!connections_allowed) throw errstr("All servers are disabled."); - shared_ptr srv = find_server(host, pattern); + shared_ptr srv = find_server(peername, pattern); - if (srv) + if (!srv) + throw errstr("usher internal error"); + sock s = srv->connect(name); + serversock ss(s); + map, serverdata>::iterator i = servers.find(srv); + if (i == servers.end()) + throw errstr("server_manager is inconsistent"); + ss.srv = i->second.name; + ++total_connections; + if (srv->local && srv->connection_count == 1) { - sock s = srv->connect(name); - serversock ss(s); - map, serverdata>::iterator i = servers.find(srv); - if (i == servers.end()) - throw errstr("server_manager is inconsistent"); - ss.srv = i->second.name; - ++total_connections; - if (srv->local && srv->connection_count == 1) - { - live.insert(srv); - } - return ss; + live.insert(srv); } - else { - throw errstr("Could not find a monotone instance for the pattern '" + pattern + "', perhaps make it less generic?."); - } + return ss; } void server_manager::disconnect_from_server(serversock const &s, ============================================================ --- src/server_manager.hh 5808402a36b08a92cf0ed904d5c0a88807238be5 +++ src/server_manager.hh 8d75c6dae7590e8ecec5a7ae22b1ee585d1e78ec @@ -64,12 +64,12 @@ private: void kill_server_now(string const &srv); void reload_servers(); private: - shared_ptr find_server(string const &host, + shared_ptr find_server(string peername, string const &pattern); public: - string const *lookup_server_name(string const &host, + string const &lookup_server_name(string const &peername, string const &pattern); - serversock connect_to_server(string const &host, + serversock connect_to_server(string const &peername, string const &pattern, string const &name); void disconnect_from_server(serversock const &s, ============================================================ --- test/run-tests.sh 788d4990135232caa3177afe126c4e90a0074b3f +++ test/run-tests.sh db2dc5562ef5a681219cd92a7d0fdd539bc1c988 @@ -50,9 +50,12 @@ check_match() { check_match() { local host=$1 local pattern="$2" - local wanted_server=$3 + local wanted_server="$3" + if ! [ "$wanted_server" = "-" ]; then + wanted_server="OK: $wanted_server" + fi local got_server=$(msg_usher MATCH $host $pattern) - if [ ! -n "$got_server" ]; then + if [ ! -n "$got_server" -o "${got_server:0:5}" = "ERROR" ]; then got_server=- fi if ! [ "$wanted_server" = "$got_server" ]; then ============================================================ --- test/test1/script.txt 4a9bfacbd8cbb34c591ceef0d385290db2b4bac4 +++ test/test1/script.txt 33b921a8fc5d016e41c354563db7dafe75f838b2 @@ -28,3 +28,11 @@ check_match prjek-other net.prjek prjek-s check_match prjek.net org.example.foobar prjek check_match example.com com.example - + +# explicit server name +check_match mtn://asdf/prjek - prjek +check_match mtn://asdf/prjek-s - prjek-s +check_match mtn://example.org - example +check_match mtn://example.org/ - example +check_match mtn://example.org/prjek - prjek +check_match mtn://prjek.net/foobar net.prjek -