On Wed, Oct 22, 2008 at 10:35 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.
>>
>
>
> I will try to take a look at this. ...
>


Did you take a look at this?  What do you think?

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