Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo


#61 Support for non-HTTP drivers for AOLserver 4


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...


1 2 > >> (Page 1 of 2)
  • Stephen

    • assigned_to: nobody --> vasiljevic
  • Logged In: YES

    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

    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
    how to handle such things. I would be more than happy to
    see this happen...


  • Vlad Seryakov
    Vlad Seryakov

    Logged In: YES

    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.

  • Vlad Seryakov
    Vlad Seryakov

    Logged In: YES

    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

    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.

  • Stephen

    Logged In: YES

    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'.

  • Stephen

    Logged In: YES

    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

    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

    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

    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

    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

    Can we get some comments on the questions below?
    I would like to move on with this proposal...

  • Stephen

    Logged In: YES

    I've uploaded a new version (2) of the patch which completes
    the basic functionality.


    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


  • Stephen

    Logged In: YES

    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

    The conn flags NS_CONN_SKIPHDRS and NS_CONN_SKIPBODY are
    always set which suppresses HTTP specific headers and body

    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

    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.

  • Stephen

    Logged In: YES

    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:


    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

    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

    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

    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

    Do I see this correctly?

  • Stephen

    Logged In: YES

    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

    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.

  • Dossy Shiobara
    Dossy Shiobara

    • assigned_to: vasiljevic --> nobody
  • Stephen

    Logged In: YES

    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

    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...

  • Stephen

    Supports session local storage

  • Stephen

    Works with protocols patch V3

  • Stephen

    Logged In: YES

    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.

    • assigned_to: nobody --> vasiljevic
1 2 > >> (Page 1 of 2)