I will try to take a look at this. With new API i could not figure out 
about pre-apending request data in Recv callback, so i had to come up 
with the solution which is almost the same as before.

It is just that now i need in my driver to keep track when actual binary 
data starts and i have to force driver to parse data that nobody need 
anyway, using more memory. Empty request now is supported, the work is 
done once and server can server requests without HTTP request at all.
Is this so bad?

Stephen Deasey wrote:
> On Wed, Oct 22, 2008 at 8:36 PM, Vlad Seryakov <[EMAIL PROTECTED]> wrote:
>>> static ssize_t
>>> Recv(Ns_Sock *sock, struct iovec *bufs, int nbufs, Ns_Time
>>> *timeoutPtr, int flags)
>>> {
>>>     static const char request[] = "GET /whateva HTTP/1.0\r\n\r\n";
>>>     size_t requestLen = sizeof(request);
>>>     socklen_t sockLen = sizeof(struct sockaddr_in);
>>>
>>>     memcpy(bufs->iov_base, request, requestLen);
>>>
>>>     return recvfrom(sock->sock,
>>>                     bufs->iov_base + requestLen,
>>>                     bufs->iov_len - requestLen,
>>>                     0, (struct sockaddr*) &sock->sa, &size);
>>> }
>>>
>>> (checking for buffer lengths skipped here)
>>>
>>>
>>> The advantage of doing it this way is that everything is much simpler
>>> from the driver threads point of view. It doesn't need to know
>>> anything special about non-standard protocols, and there isn't
>>> anything in the driver callback api that isn't also useful to the HTTP
>>> server.
>>
>> Arguable this is not very clear and simple, driver will have to hack
>> buffers and every request should pretend to be HTTP just so driver
>> thread would think that it serves only HTTP requests.
> 
> 
> It's clear and simple. It's maybe not very pretty :-)
> 
> 
>> If we have special codes and already have 3, does another one breaks
>> anythings if only one code makes overall process simpler not only in
>> driver thread but for drivers itself?
> 
> 
> It's a trade off.
> 
> Either non-standard drivers prepend their first read with 20 bytes in Recv().
> (~ two lines of code)
> 
> *OR*
> 
> You need to change all parts of the sever that expect an HTTP request
> structure to be available. AND you need to account for the fact that
> sometimes it gets created in the normal fashion, but other times it
> gets created later, or not at all.
> 
> 
> You've tried to ways to do this:
> 
> 
> 1) Exposing a new Ns_DriverSetRequest routine.
> 
> Here's what it looked like in nssyslogd:
> 
> http://naviserver.cvs.sourceforge.net/viewvc/naviserver/modules/nssyslogd/nssyslogd.c?revision=1.18&view=markup
> 
> NS_EXPORT int
> Ns_ModuleInit(char *server, char *module)
> {
>     ...
>     Ns_RegisterRequest(server, "SYSLOG",  "/", SyslogRequestProc,
> NULL, srvPtr, 0);
>     ...
> }
> 
> static NS_DRIVER_ACCEPT_STATUS
> Accept(Ns_Sock *sock, SOCKET listensock, struct sockaddr *sockaddrPtr,
> int *socklenPtr)
> {
>     sock->sock = listensock;
>     Ns_DriverSetRequest(sock, "SYSLOG / HTTP/1.0");
>     return NS_DRIVER_ACCEPT_DATA;
> }
> 
> 
> How is this functionally different to what I proposed (example in Recv above)?
> 
> 
> 2) Doing away with the need for a Ns_Request all together.
> 
> Which now looks like this:
> 
> http://naviserver.cvs.sourceforge.net/viewvc/naviserver/modules/nssyslogd/nssyslogd.c?revision=1.19&view=markup
> 
> NS_EXPORT int
> Ns_ModuleInit(char *server, char *module)
> {
>     ...
>     init.requestProc = Request;
>     ...
>     init.opts = NS_DRIVER_ASYNC | NS_DRIVER_NOPARSE;
>     ...
> }
> 
> static int
> Request(void *arg, Ns_Conn *conn)
> {
>     Ns_DString *dsPtr = Ns_ConnSockContent(conn);
>     SyslogRequest *req = SyslogRequestCreate(server, sockPtr->sock,
> dsPtr->string, dsPtr->length, &sa);
>     SyslogRequestProcess(req);
>     ...
> }
> 
> 
> The strategy here seems to be to completely ignore the standard
> request structure and do your own thing. There's nothing wrong with
> this in the abstract -- you're not actually using any of the HTTP
> stuff. However, the rest of the server fully expects the HTTP request
> to be present and filled in, and this is why you've had to touch
> dozens of files in dozens of places fixing up all code that might trip
> over a null request field. (And the public API has changed...)
> 
> 
> As far as I can see, neither method 1 or 2 achieves anything than
> passing "METHOD / HTTP/1.0\r\n\r\n" does, using considerably less
> code.
> 
> For example, In the snippet above, you can see the newly added
> Ns_ConnSockContent which returns a pointer to the read buffer (which
> is otherwise private). Ordinarily the buffer would contain the HTTP
> request line, any headers, then any body. You can get at the body with
> the existing Ns_ConnContent. So if you just return "SYSLOG /
> HTTP/1.0\r\n\r\n" and then your bytes in Recv(), the request would be
> constructed and then you could parse the protocol beginning in the
> body content.
> 
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> naviserver-devel mailing list
> naviserver-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/naviserver-devel
> 


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
naviserver-devel mailing list
naviserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to