Vlad Seryakov's patch #726288 hasn't been accepted
(yet) into AOLserver. How about a minimally invasive
patch that allows socket driver modules to dummy up
HTTP requests from arbitrary protocols, as suggested on
the mailing list by Jim Davidson?
The main stumbling point here is that unlike HTTP, some
protocols require the server to speak first after the
client connects, to e.g. present a login banner.
I am attaching a patch that adds a new option,
NS_DRIVER_WRITE_FIRST, which socket drivers can OR into
drvPtr->opts. Drivers which do so will then have their
DriverSend function called with 0 as the tosend arg,
when a connection is first made.
With this small patch I've been able to create an
example POP3 -> HTTP protocol mangler...
Logged In: YES
user_id=43168
How about we just accept Vlad's patch instead? Dossy,
Zoran? (Caveat: I personally know nothing about the patch,
but it SOUNDS very useful, and Vlad says he's had it in
Production use for a year or so now...)
Logged In: YES
user_id=95086
As far as I'm concerned, there is no problem.
I would be happy to integrate this patch into CVS.
The real problem I see is the responsibility. As far as I can
follow, changes to AS code done from AOL are just happening
whereas changes from the community are always obstructed
by lengtly fruitless discussions on the list, yielding
mostly to a
dead-end. I think this is the point which needs to be resolved
first. We have to setup some kind of framework for this.
With the
AS core-team in place, there was at least one place one can
address such issues. Now, I do not know who is really
deciding about what/what not to do.
Maybe this particular thing should be a starting point of a
(hopefully fruitful) discussions resulting in a set of
directives
how to handle such things. I would be more than happy to
see this happen...
Zoran
Logged In: YES
user_id=184124
My patch is for version 4.0.x only, not for new 4.1. Jim
modified driver.c pretty significantly, so it cannot be
appied to CVS version.
The patch is pretty stable, it is been running for more than
8 months already in the production.
Logged In: YES
user_id=184124
Can you sen me or publish here your driver POP3 driver, just
curious how new driver.c can handle new protocols. My main
reason i had to change driver was to implement SMTP proxy with
anti-spam, anti-virus support. I will open-source it soon
and i'd like to port it to new 4.1 version as well.
Logged In: YES
user_id=95086
I'm looking into Vlad's patch and it looks very promising.
With that, you should be able to cook up just about any
custom-socket apps. I need some more time to check it, though.
Logged In: YES
user_id=87254
Thanks. This patch was created because Vlad's patch sat
unapplied for so long. I'm much happier to see a push to
provide this functionality the 'right way'.
Logged In: YES
user_id=87254
I've uploaded a patch which implements two new commands:
int Ns_RegisterParseProc(char *server, Ns_ParseProc *proc,
void *arg);
void Ns_RegisterRunProc(char *server, Ns_RunProc *proc,
void *arg);
Ns_RegisterParseProc allows module authors to register a
proc which will be called by the driver thread (or by a
reader thread if no async read ahead) to parse the data from
a connection socket.
Ns_RegisterRunProc allows module authors to register a proc
which will be called by a connection thread to run the
connection.
To write handle a new protocol you have two options:
1) Write only an Ns_ParseProc. Parse the new protocol into
the existing Ns_Request, Ns_Set (headers) structures
contained within an Ns_Conn, and let AOLserver treat it as
an HTTP connection. You get registerd procs, filters etc.
etc. for free.
2) Also write an Ns_RunProc. Do whatever you like with your
parser, handle the results here.
You can run either nssock or nsopenssl.
Note: This patch applies and the server runs, but it is
otherwise untested. It is a first cut suggestion as to how
AOLserver could handle mutiple protocols cleanly in the
core. Feedback is welcome.
Logged In: YES
user_id=95086
First question: shouldn't it be better to move the
Ns_RunProc called from within the ConnRun?
This way the connection cleanup is done by the
existing code already at the end of the ConnRun.
Second: registering Ns_ParseProc and Ns_RunProc is
done on the virtual server level, right? So to get those
two hit, one would have to configure one virtual server
per served protocol, right?
Just those two for the beginning....
Logged In: YES
user_id=95086
Third question:
"Parse the new protocol into
the existing Ns_Request, Ns_Set (headers) structures
contained within an Ns_Conn, and let AOLserver treat it as
an HTTP connection.
We should also provide some foolproof implementation on how
to do this in order not to break the code relying on the
conn structure elements, right?
At least to have those with some initial default data which
wont break the rest ot the server, plus some wrappers to set
particular elements.
Don't you think so?
Logged In: YES
user_id=95086
Fourth question:
Can you provide some example imlpementation of
Ns_ProcParse and Ns_ProcRun for a simple ncp-like
service? This would perfectly illustrate what needs to
be done and how.
Logged In: YES
user_id=95086
Stephen,
Can we get some comments on the questions below?
I would like to move on with this proposal...
Logged In: YES
user_id=87254
I've uploaded a new version (2) of the patch which completes
the basic functionality.
Changes:
Parse and Run procs are now registered per comm module
(nssock etc.) rather than per server so that only one
virtual server need be configured. Load one instance of a
comm module for each protocol you wish to serve. Comm
modules must be bound to a virtual server due to the
difficulty of getting connection pools and other scattered
bits of code to work with 'host header' virtual servers.
I've incorporated Zoran's suggestion to move the call to the
Run proc into queue.c, taking advantage of the existing
infrastructure for interp allocation, traces, cleanups etc.
Registering a Run proc now bypasses just op procs and
filters (except NS_FILTER_PRE_CLOSE, see below). We should
think about whether Run procs are really necessary...
A default Ns_Request structure is filled out if the
registered parse proc has not already done so. The HTTP
method is the module name of the comm driver, with a single
slash as the URL. This only makes a difference if your
parse proc doesn't fill out an Ns_Request and you also don't
register a run proc, which I don't think makes a lot of
sense. That's all that's need for defaults.
Ns_RegisterParseProc has sprouted a third argument
'onconnect', which if true will cause the server to generate
a request to /CONNECT (method is comm driver module name)
when a client first connects. There's no facility for
writing data to the client from within the driver or read
threads, and they don't have Tcl interps available which
would make any future Tcl interface more painful.
The Ns_Conn content, contentLength, next and roff (read
offset) fields are updated prior to running the parse proc.
conn->content usually points to just the content part (file
upload etc.) of an HTTP request, but for other protocols it
is set to the entire request. Ns_ConnRead, Ns_ConnReadLine
etc. have been updated to work in this new environment
(they're no longer used by the AOLserver core). This
provides a convenient interface for parse procs to handle
arbitrary requests.
I've added a new function Ns_ConnSetReadOffset to allow
parse procs to save state while parsing binary protocols,
XML etc.
I've added a couple of other convenience functions:
Ns_ConnSetResponseStatus sets an arbitrary response code
which will be logged by nslog; Ns_ConnAcceptTime returns
the time the client connected, which is more important than
start time to session oriented protocols.
This patch really needs some input from people who might
like to use it to handle new protocols to ensure the API is
adequate.
Thanks.
Logged In: YES
user_id=87254
I forgot to mention NS_FILTER_PRE_CLOSE...
This is a new filter type which runs after the registered
proc, but before the connection is closed, even if previous
filters or the proc errored out. This is necessary to
intercept zero length messages, such as is generated when a
Tcl error occurs, so that you can send a protocol specific
error.
The conn flags NS_CONN_SKIPHDRS and NS_CONN_SKIPBODY are
always set which suppresses HTTP specific headers and body
content.
The pre-close filters are careful about not trampling a
previous error message with a successful result. An error
in a pre-close filter is however propagated and will prevent
the running of server traces.
Logged In: YES
user_id=95086
Hey Stephen, good thing!
I will look into this, It seems like a lot
of work you did. Thank you very much for
your efforts.
After examining the changes (still need to),
I would suggest to move on to the public
and let the people see what you have done
and eventually comment on that.
Logged In: YES
user_id=87254
I've uploaded the file nspopd-0.2.tar.bz which is a simple
example of a protocol parser using the new Ns_ParseProc
interface. It transforms incoming POP3 requests into HTTP
requests of the form:
POP3 /COMMAND/ARG1/ARG2
Where COMMAND is the POP3 command such as USER, PASS etc.,
and ARG1, ARG2 are optional args.
Replies are sent using the popd_returnok, popd_returnerr Tcl
commands.
There is a default op proc to handle unknown commands and an
implmentation of the NOOP command, but other than that the
server defines no policy. You are expected to register your
own op procs, using either C or Tcl, which manage email in a
database or some other mail store.
There are the beginnings of an example implmentation
included in the distribution.
I noticed that the error handling doesn't work correctly
when a Tcl registered proc throws an error -- no message is
sent to the client. It does work from a filter. I'll look
at this later...
Logged In: YES
user_id=95086
If I understand this well, you're setting the connection to
keepalive. This defaults to 30 seconds wait time when the
next connection on the same socket should be done.
One can twek this for the nssock driver allright, but this
will of course affect all (also regular http) keepalive
handling.
If the protocol you're implemeting is user-driven, for example
an command-line-type server (nscp-like) then you can easily
run into timeouts. In your popd example, this probably won't
happen.
Do I see this correctly?
Logged In: YES
user_id=87254
You must load at least one instance of the nssock (or
nsopenssl etc.) module for each protocol you want to support.
You can load both nssock and nsopenssl, and program your new
protocol module to register the parse proc for both drivers.
The keepwait setting is specific to an instance of a comm
driver so I don't think changing it will affect web serving.
Logged In: YES
user_id=95086
Understand. Thanks for the clarification.
For people implementing nscp-like protocols, the
keepwait of the sock driver instance should be
set high-enough since the default of 30 secs is
really too low. But this is not in the scope of your
patch. I just wanted to make this point clear since
it is not so obvious on the first glance.
Logged In: YES
user_id=87254
I've uploaded version 3 of the patch.
The major new addition is in the file sls.c which implements
session/socket local storage. This is very similar to the
existing tls and cls APIs, with the exception that data is
cleaned up when the client disconnects. It also provides a
Tcl API.
Although HTTP is nominally a stateless protocol, all
interesting apps embed state in cookies or URLs, and all
modern clients support connection keepalive, so the sls.c
API is generally useful.
I've removed support for registering an Ns_RunProcs. I
don't think it has any use, but let me know if you think
otherwise...
I've aded a couple of more utility procs to set the
authenticated user and the auth user's password. The user
shows up in access logs and is used by the authentication procs.
The previously mentioned problem with error handling has
been fixed, and I've enabled preclose filters in the Tcl API.
Protocols which require pipelining are not supported because
AOLserver has no support for this. HTTP 1.1 requires
pipelining, so I think it should be a general goal to add
this. I will take a look, but if anyone has any ideas...
Supports session local storage
Works with protocols patch V3
Logged In: YES
user_id=87254
I've uploaded nspopd-0.3 which works with the latest version
of the protocols patch and includes some new features.
There's also a very simple example implementation of a POP3
server, a config file reference, and some notes in the
README file.
It should serve as enough of an example to implement most
line oriented protocols.