I'm trying to set up a host so that it will be used for any incoming
request, whatever the name the user is using to refer to my server. I
would expect that you could do this using 'matching=""' in the Host
declaration, but that isn't working for me. My current config (after
playing with the matching declaration for a bit) is this:
servers = [Server(
uuid="f400bf85-4538-4f7a-8908-67e313d515c2",
chroot="./",
access_log="./logs/access.log",
error_log="./logs/error.log",
pid_file="./some.pid",
default_host="myhost",
port=8080,
name="myserver",
hosts = [
Host(name="myhost",
matching=".*",
routes={
'/' : Proxy(addr='localhost', port=3000),
'/comet' : Handler(send_spec="tcp://127.0.0.1:9998",
send_ident="sender",
recv_spec="tcp://127.0.0.1:9999",
recv_ident="sender")
})])]
Any attempt to contact the server gives a 404 on the client, and this
message on mongrel2:
src/connection.c:104: errno: Resource temporarily unavailable) Request
for a host we don't have registered: localhost
A sample telnet looks like this:
GET / HTTP/1.1
Host: localhost
HTTP/1.1 404 Not Found
Content-Type: text/plain
Connection: close
Content-Length: 9
Server: Mongrel2/1.4-561cb4b4a4
Not Found
If I instead use "myhost" as the Host, it does work as it should. Is
the matching directive being ignored, or is it broken in the random
fossil checkout that I grabbed, or am I doing something wrong?
On Wed, Dec 29, 2010 at 09:47:19PM -0600, tsuraan wrote: > I'm trying to set up a host so that it will be used for any incoming > request, whatever the name the user is using to refer to my server. I > would expect that you could do this using 'matching=""' in the Host > declaration, but that isn't working for me. My current config (after > playing with the matching declaration for a bit) is this: Try this: main = Server( uuid="5c7e6342-88c5-44d0-ad9a-3526128039a1", access_log="/logs/access.log", error_log="/logs/error.log", chroot="./", default_host="(.+)", name="test", pid_file="/run/mongrel2.pid", port=6767, hosts = [ Host(name="(.+)", routes={ }) ] ) servers = [main] Just use a (.+) pattern which matches everything, then say that's the default host. -- Zed A. Shaw http://zedshaw.com/
> Try this: > > main = Server( > uuid="5c7e6342-88c5-44d0-ad9a-3526128039a1", > access_log="/logs/access.log", > error_log="/logs/error.log", > chroot="./", > default_host="(.+)", > name="test", > pid_file="/run/mongrel2.pid", > port=6767, > hosts = [ > Host(name="(.+)", routes={ > }) > ] > ) Ok, that does seem to work. Why does setting name to a pattern work, but setting matching to the same pattern not? Is that just a bug?
On Thu, Dec 30, 2010 at 09:35:16AM -0600, tsuraan wrote: > Ok, that does seem to work. Why does setting name to a pattern work, > but setting matching to the same pattern not? Is that just a bug? Not sure what you mean, why don't you write out what you think should be happening. That might be a better way to try to understand what's going on. For example: "I think that mongrel2 should do: 1. A request comes in for foobarbaz.com. 2. There is a host named "(.+)". ..." -- Zed A. Shaw http://zedshaw.com/
> Not sure what you mean, why don't you write out what you think should be > happening. That might be a better way to try to understand what's going > on. For example: > > "I think that mongrel2 should do: > > 1. A request comes in for foobarbaz.com. > 2. There is a host named "(.+)". > ..." Given a Host with both a name and a matching declaration, like so: ... Host(name="bob", matching="(.*)", ... So the host's name is bob, but his matching spec should match anything. In the absence of any other hosts, I would expect any request to be routed to this host. If there were some other hosts, with more specific matching declarations (or host names) that match the request, then I would expect the request to be dispatched to those other hosts. So, I guess my understanding (misunderstanding?) was that the name was used for matching unless a matching declaration was given; if a matching declaration is given, then I thought the host part would be ignored, or at least not be exclusively used for matching requests against hosts. Does that make sense?
>> Not sure what you mean, why don't you write out what you think should be >> happening. That might be a better way to try to understand what's going >> on. For example: >> >> "I think that mongrel2 should do: >> >> 1. A request comes in for foobarbaz.com. >> 2. There is a host named "(.+)". >> ..." > > Given a Host with both a name and a matching declaration, like so: > > ... > Host(name="bob", > matching="(.*)", > ... > > So the host's name is bob, but his matching spec should match > anything. In the absence of any other hosts, I would expect any > request to be routed to this host. If there were some other hosts, > with more specific matching declarations (or host names) that match > the request, then I would expect the request to be dispatched to those > other hosts. So, I guess my understanding (misunderstanding?) was > that the name was used for matching unless a matching declaration was > given; if a matching declaration is given, then I thought the host > part would be ignored, or at least not be exclusively used for > matching requests against hosts. Does that make sense? Just noticed that Zed is still alive, so re-sending this in case it got lost in transit or something.
On Fri, Jan 07, 2011 at 02:33:45PM -0600, tsuraan wrote: > > So the host's name is bob, but his matching spec should match > > anything. In the absence of any other hosts, I would expect any > > request to be routed to this host. If there were some other hosts, > > with more specific matching declarations (or host names) that match > > the request, then I would expect the request to be dispatched to those > > other hosts. So, I guess my understanding (misunderstanding?) was > > that the name was used for matching unless a matching declaration was > > given; if a matching declaration is given, then I thought the host > > part would be ignored, or at least not be exclusively used for > > matching requests against hosts. Does that make sense? > > Just noticed that Zed is still alive, so re-sending this in case it > got lost in transit or something. Yes, this is too complicated I think. It's literally: 1. Request comes in for a host to the port. 2. Server listening on that port runs the Host.name against the routing list. 3. If it finds a match (by name), it uses that Host. 4. If not, it uses the host set in Server.default_host. I think the confusion is the existence of Host.name and Host.matching, so probably need a ticket for making one of those not exist or clarifying it. -- Zed A. Shaw http://zedshaw.com/
> I'm trying to set up a host so that it will be used for any incoming > request, whatever the name the user is using to refer to my server. I > would expect that you could do this using 'matching=""' in the Host > declaration, but that isn't working for me. My current config (after > playing with the matching declaration for a bit) is this: Poking around a bit, the config I gave results in this hosts table: sqlite> select * from host; 1|1|0|myhost|myhost So, my matching declaration isn't being set. If I do set matching to an empty string, or a string that is simply '.', I still get the unregistered host error when I make a request with the Host set to anything other than myhost. So, even though matching is set to something other than myhost, myhost is the only host that mongrel2 will accept. I'll keep poking around.
> sqlite> select * from host; > 1|1|0|myhost|myhost > > So, my matching declaration isn't being set. If I do set matching to > an empty string, or a string that is simply '.', I still get the > unregistered host error when I make a request with the Host set to > anything other than myhost. So, even though matching is set to > something other than myhost, myhost is the only host that mongrel2 > will accept. I'll keep poking around. Ok, so aside from the problem with the matching column of the table not being set by m2sh, it doesn't look like the host matching uses patterns, as described in the "Routing and Host Patterns" section of the m2 book. If I set the match to '.', then any Host that ends with a "." character is matched with my Host declaration, but the "." is not acting as a wildcard character. The RouteMap_match_suffix function calls tst_search_suffix, which doesn't appear to have any sort of pattern expansion built into it. Is this a bug, or a mis-reading of the manual? Also, it still seems like tst_search_suffix should match any string against an empty string, but it doesn't. More poking around to come :)
> Ok, so aside from the problem with the matching column of the table > not being set by m2sh, it doesn't look like the host matching uses > patterns, as described in the "Routing and Host Patterns" section of > the m2 book. If I set the match to '.', then any Host that ends with > a "." character is matched with my Host declaration, but the "." is > not acting as a wildcard character. The RouteMap_match_suffix > function calls tst_search_suffix, which doesn't appear to have any > sort of pattern expansion built into it. Is this a bug, or a > mis-reading of the manual? Also, it still seems like > tst_search_suffix should match any string against an empty string, but > it doesn't. More poking around to come :) I looked at the docs again, and I think the match that I'm looking for should be "(.)" or "(.*)", not just ".". Neither of those work for me though. Looking more into why empty strings don't work, I found that if the string being inserted into the tst (using tst_insert) is blank, then its len is 0 and (I think) the *s in the tst_insert_base function is always 0. So, we're inserting a node with splitchar equal to 0. That would probably be ok, if the tst_search_suffix function started looking at the null character at the end of the string, and if the RouteMap_insert_reversed always made sure that the leading character of the reverse strings was 0. To test it out, I modified adt/tst.c line 99, making it say "int i = len" rather than len-1, and it does match strings against the empty pattern :) Of course, without changing RouteMap_insert_reversed it breaks the unit tests, which isn't so good, so it's not a fix yet. Is this a reasonable direction to go in, or should we just use lua patterns?