From: Zoran V. <zv...@ar...> - 2005-03-05 09:42:32
|
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; } |