MOO-cows Mailing List Archive


Re: bf_connect_player(CONN, PLAYER) --> *FTP!!*

On Sun, 4 Aug 1996, Richard Connamacher wrote:

> First to say that I think a connect_player() / bind_connection() builtin 
> function would be a good idea and a nice step in making the database more 
> independant of specific server nuances.  I do, though, have to disagree 
> with both of the reasons posted.  First, HTTP is by definition supposed 
> to be _stateless_, which means that logging someone into a MOO through a 
> web connection is actually against the HTTP specifications.

Jay Carlson makes some good comments about this, but let me just say that
the entire point of what we're doing is to figure out _how_ to make HTTP
maintain state.  We're aware that's not in the spec now, but we think it
would be a useful tool to maintain data on a user from request to request. 
MOO seems like a great launching point for this -- make each user a
character and store data on that player object. 

> You must be confusing the unix ftp client, where it prompts you for a 
> password and you type it in, and the actual interface to the FTP server, 
> where "PASS" _is_ a command, of the form PASS <password>, which is 
> supposed to follow a USER <username> command.  In MOO, if you really 
> wanted to make the main interface via FTP, then you'd log someone in 
> simply by returning the player's object number after the PASS command 
> gets executed.  Running a read() after the USER command gets executed is 
> not only unneccessary, but probably also against the FTP protocol specs 
> whre PASS is a command and only a command.

Yes, some confusion, though I think my point is still valid.  I'm not sure
what you mean by "after the PASS command gets executed."  As it is now,
each *line* of input from an unlogged-in connection gets passed to
:do_login_command().  So in theory, if you _do_ want to log in FTP
connections (and again, I am having second thoughts about this) you would
have :do_login_command() receive the first *line* of an FTP request, hold
input on that connection, read() the rest of the lines (or at least up to
the line beginning with PASS) unhold input and return either a player
object number or zero.  As we've discussed before, if that read() is
blocking, the return value of :do_login_command() is ignored by the
server: no login is possible.  If it is a non-blocking read inside a loop,
it lags the entire MOO. So this is why I don't understand the "after the
PASS command gets executed" part. 

One certainly can buffer each line as it comes in (at the cost of calling
:do_login_command() once for each line) and only have the call to
:do_login_command() that gets the PASS line return a valid player object
number.  But as you pointed out: 

> [...] you can create your own input 
> buffer in-database via $do_login_command() and create your own, say, 
> $login:read() verb that way.  But, it would be nicer and cleaner if we 
> could simply call a builtin function to do the connection binding.

... and I think nicer and cleaner is worth it: we'd end up needing only
one call to :do_login_command() (because it could use blocking read()s and
use "connect_player()"/"bind_connection()" to log in the connection) and
we could dispense with an input buffer property, the necessity of clearing
out this buffer for connections that dropped partway through, and other
messy bits and pieces. 

> > If you change the read(player) to read(player, 1) (the "non-blocking" 
> > option of read(), NOT the default) then you will be logged in.  However,
> > *nothing* else will happen on the MOO until that while loop exits (or runs
> > out of ticks.) So if someone takes a long time to type in "LOG ME IN" (or
> > their password, for instance) the MOO lags like Eeyore on valium. 
> Wouldn't it run out of seconds if the user took over four or five seconds 
> to respond?  (Yes, I agree that a nonsuspending read loop is a bad idea)

Yes, true.  But four or five seconds of lag annoys me, at least! :)
> (You'd have connections logging 
> in, then out, then in, then out, constantly.  Remember, HTTP connections 
> are very brief and many.)

True, except that we already wrote the hack to allow for a "grace period" 
of X seconds (defined in-DB) between when a client disconnects (i.e. an
HTTP connection closes from the client side due to someone hitting the
stop or reload button) and when a player is in fact logged out.  During
this grace period all output to the player is simply buffered via the
normal server network buffering, and when (if) the player reconnects with
a second HTTP request, that buffer is sent to them and it simply looks
like they've redirected their connection.  If they don't reconnect within
the grace period, they are logged out and all buffer data is cleared
normally.  I'd be happy to show you this hack;  it's very easy.

> MOO HTTP servers are great (Believe me, I 
> know), but be sure that you do follow the HTTP specifications and 
> guidelines, including keeping web connections stateless, nomatter how 
> much you might be tempted not to.

MOO HTTP servers are indeed great, and that's why we think they're the 
way to go when _intentionally_ trying to make a state-maintaining HTTP 
server.  We're not alone in trying to create such a thing: check out, which is running a state-maintaining server, 
though not related to MOO.  


Tripod, Inc.

Follow-Ups: References:

Home | Subject Index | Thread Index