ns_respond closes the connection, so you cannot use it, still need
ns_conn status newstatus command.



Zoran Vasiljevic wrote:
On Saturday 05 March 2005 01:33, Stephen Deasey wrote:


Does ns_respond do what you need?

ns_respond ?-status status? ?-type type? \
   { ?-string string? | ?-file filename? | ?-fileid fileid? } \
   ?-length length? ?-headers setid?



The main reason for such mechanism for me is:
I would like to prepare a http response and send it
ultimately to the client (w/o closing the connection
to the client and w/o sending any content bytes).

When the client makes a request to the server, the server
will resond with proper headers and leave the content
handling to me. For this purppose I have made the [ns_conn channel] which I can use to handle the content
myself. So it goes this way:

  server accepts a http regular connection
  server formats a proper http response
  server sends the response to client but does not close the connetion
  server gives me the connection socket [ns_conn channel]
  my custom proc takes the socket and does things
  my custom proc closes the socket when finished

So, basically, what I miss in the current implementation
is a way to create and send a proper http request
including headers and status. To set output headers,
there is a way, but to set the proper response status
there isn't.

If I do:

  ns_respond ?-status status? ?-type type? ?-headers setid?

would it do the right thing?
If I have my [ns_conn channel] command (RFE) I'd do:

  set chan [ns_conn channel]
  ns_respond -status 200 -type myown/mimetype
  dothings $chan

The client will get proper http response (ns_respond)
and I will keep the conn socket open (ns_conn channel).
My (dothings) proc will then handle the body
and ultimaltey close the channel, which will then tear
down the socket and the connection to the client.

Look at this example...

On the client-side (this can be another server instance):

  set chan [httpget /some/url/on/server]
  domyprotocol $chan

And on the server (handler for the /some/url/on/server URL)

  set chan [ns_conn channel]
  ns_respond -status 200 -type myown/mimetype
  domyprotocol $chan

The "httpget" on the client is clever. It sends
the requests and processes only up to returned headers.
For the body part, it just returns the comm socket to
the caller.
The server part accepts a valid http requests, prepares
the proper http response and passes the conn channel to
the caller.

After that, "domyprotocol" on the server and on the client
can do whatever they like on the $chan. This way we have
implemented many services in our product. We only use port
80 and http connection establishment to get a pipe between
peers. Thereafter, we use this pipe for whole lotta things
absolutely unrelated to the http protocol and page-serving at all.

Do you follow?




What is [ns_conn discardcontent] used for?


This I have made some years ago and it may not be
needed anymore today (not sure). What I ment with
that is: by processing the incoming request, I look into http headers. If I decide to drop the request because there is something in the headers
I don't like, I will handle all of the incoming
data from the client and just discard everything.
This is important for keepalive connections because
you have to be careful and read exactly the contentLength bytes from the peer. I somehow could
not do that using existing ns_ commands so I invented
my own. Question: is there another way of doing this?
Look at the implementation I have now:


static int
NsxDiscardCmd (cl, interp, objc, objv)
    ClientData      cl;
    Tcl_Interp    * interp;
    int             objc;
    Tcl_Obj       * CONST objv[];
{
    size_t buflen;
    int nb;
    char *buf;
    Ns_Conn *conn;

    /*
     * Syntax: nsx discardcontent
     */

    conn = Ns_TclGetConn(interp);
    if (conn == NULL) {
        Tcl_AppendResult(interp, "no connection", NULL);
        return TCL_ERROR;
    }

    buflen = 32*1024;
    buf = (char*)Tcl_Alloc(buflen);

    /*
     * Sink conn->contentLength bytes from connection
     */

    while(conn->contentLength > 0) {
        nb = (conn->contentLength < buflen) ? conn->contentLength : buflen;
        nb = Ns_ConnRead(conn, buf, nb);
        if (nb == NS_ERROR) {
            break;
        }
        conn->contentLength -= nb;
    }

    Tcl_Free((char*)buf);

    return TCL_OK;
}



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
naviserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

--
Vlad Seryakov
571 262-8608 office
[EMAIL PROTECTED]
http://www.crystalballinc.com/vlad/

Reply via email to