Exemplo n.º 1
0
int
Ns_ConnFlush(Ns_Conn *conn, char *buf, int len, int stream)
{
    Conn *connPtr = (Conn *) conn;
    NsServer *servPtr = connPtr->servPtr;
    Tcl_Encoding encoding;
    Tcl_DString  enc, gzip;
    char *ahdr;
    int status;

    connPtr->sbuf=buf;
    if (NsRunFilters((Ns_Conn *) connPtr, NS_FILTER_PRE_WRITE) != NS_OK) {
        return NS_ERROR;
    } 
    if (connPtr->rbuf != NULL) {
        /* the content was set by pre-write filters */
        buf=Tcl_DStringValue(connPtr->rbuf);
        len=Tcl_DStringLength(connPtr->rbuf);
    }

    Tcl_DStringInit(&enc);
    Tcl_DStringInit(&gzip);
    if (len < 0) {
	len = strlen(buf);
    }

    /*
     * Encode content to the expected charset.
     */

    encoding = Ns_ConnGetEncoding(conn);
    if (encoding != NULL) {
	Tcl_UtfToExternalDString(encoding, buf, len, &enc);
	buf = enc.string;
	len = enc.length;
    }

    /*
     * GZIP the content when not streaming if enabled and the content
     * length is above the minimum.
     */

    if (!stream
	    && (conn->flags & NS_CONN_GZIP)
	    && (servPtr->opts.flags & SERV_GZIP)
	    && (len > (int) servPtr->opts.gzipmin)
	    && (ahdr = Ns_SetIGet(conn->headers, "Accept-Encoding")) != NULL
	    && strstr(ahdr, "gzip") != NULL
	    && Ns_Gzip(buf, len, servPtr->opts.gziplevel, &gzip) == NS_OK) {
	buf = gzip.string;
	len = gzip.length;
	Ns_ConnCondSetHeaders(conn, "Content-Encoding", "gzip");
    }

    /*
     * Flush content.
     */

    status = Ns_ConnFlushDirect(conn, buf, len, stream);
    Tcl_DStringFree(&enc);
    Tcl_DStringFree(&gzip);
    return status;
}
Exemplo n.º 2
0
int
Ns_ConnSend(Ns_Conn *conn, struct iovec *bufs, int nbufs)
{
    Conn	   *connPtr = (Conn *) conn;
    int         nwrote, towrite, i, n;
    struct iovec    sbufs[16];

    /*
     * Send up to 16 buffers, including the queued output
     * buffer if necessary.
     */

    towrite = 0;
    n = 0;
    if (connPtr->obuf.length > 0) {
	sbufs[n].iov_base = connPtr->obuf.string;
	sbufs[n].iov_len = connPtr->obuf.length;
	towrite += sbufs[n].iov_len;
	++n;
    }
    for (i = 0; i < nbufs && n < 16; ++i) {
	if (bufs[i].iov_len > 0 && bufs[i].iov_base != NULL) {
	    sbufs[n].iov_base = bufs[i].iov_base;
	    sbufs[n].iov_len = bufs[i].iov_len;
	    towrite += bufs[i].iov_len;
	    ++n;
	}
    }
    nbufs = n;
    bufs = sbufs;
    n = nwrote = 0;
    while (towrite > 0) {
	n = NsConnSend(conn, bufs, nbufs);
	if (n < 0) {
	    break;
	}
	towrite -= n;
	nwrote  += n;
	if (towrite > 0) {
	    for (i = 0; i < nbufs && n > 0; ++i) {
		if (n > (int) bufs[i].iov_len) {
		    n -= bufs[i].iov_len;
		    bufs[i].iov_base = NULL;
		    bufs[i].iov_len = 0;
		} else {
		    bufs[i].iov_base = (char *) bufs[i].iov_base + n;
		    bufs[i].iov_len -= n;
		    n = 0;
		}
	    }
	}
    }
    if (nwrote > 0) {
        connPtr->nContentSent += nwrote;
	if (connPtr->obuf.length > 0) {
	    n = connPtr->obuf.length - nwrote;
	    if (n <= 0) {
		nwrote -= connPtr->obuf.length;
		Tcl_DStringTrunc(&connPtr->obuf, 0);
	    } else {
		memmove(connPtr->obuf.string,
		    connPtr->obuf.string + nwrote, (size_t)n);
		Tcl_DStringTrunc(&connPtr->obuf, n);
		nwrote = 0;
	    }
	}
    } else {
        /*
         * Return error on first send, if any, from NsSockSend above.
         */

        nwrote = n;
    }
    if (nwrote >= 0
	&& NsRunFilters((Ns_Conn *) connPtr, NS_FILTER_WRITE) != NS_OK) {
	nwrote = -1;
    }
    return nwrote;
}
Exemplo n.º 3
0
static void
ConnRun(Conn *connPtr)
{
    Tcl_Encoding    encoding = NULL;
    Ns_Conn 	  *conn = (Ns_Conn *) connPtr;
    NsServer	  *servPtr = connPtr->servPtr;
    int		   i, status;
	
    /*
     * Initialize the connection encodings. 
     */
    
    encoding = NsGetInputEncoding(connPtr);
    if (encoding == NULL) {
    	encoding = NsGetOutputEncoding(connPtr);
	if (encoding == NULL) {
	    encoding = connPtr->servPtr->urlEncoding;
	}
    }
    Ns_ConnSetUrlEncoding((Ns_Conn *) connPtr, encoding);
    if (connPtr->servPtr->opts.hdrcase != Preserve) {
	for (i = 0; i < Ns_SetSize(connPtr->headers); ++i) {
    	    if (connPtr->servPtr->opts.hdrcase == ToLower) {
		Ns_StrToLower(Ns_SetKey(connPtr->headers, i));
	    } else {
		Ns_StrToUpper(Ns_SetKey(connPtr->headers, i));
	    }
	}
    }

    /*
     * Run the request.
     */

    if (connPtr->request->protocol != NULL && connPtr->request->host != NULL) {
	status = NsConnRunProxyRequest((Ns_Conn *) connPtr);
    } else {
	status = NsRunFilters(conn, NS_FILTER_PRE_AUTH);
	if (status == NS_OK) {
	    status = Ns_AuthorizeRequest(servPtr->server,
			connPtr->request->method, connPtr->request->url, 
			connPtr->authUser, connPtr->authPasswd, connPtr->peer);
	    switch (status) {
	    case NS_OK:
		status = NsRunFilters(conn, NS_FILTER_POST_AUTH);
		if (status == NS_OK) {
		    status = Ns_ConnRunRequest(conn);
		}
		break;

	    case NS_FORBIDDEN:
		Ns_ConnReturnForbidden(conn);
		break;

	    case NS_UNAUTHORIZED:
		Ns_ConnReturnUnauthorized(conn);
		break;

	    case NS_ERROR:
	    default:
		Ns_ConnReturnInternalError(conn);
		break;
	    }
        } else if (status != NS_FILTER_RETURN) {
            /* if not ok or filter_return, then the pre-auth filter coughed
             * an error.  We are not going to proceed, but also we
             * can't count on the filter to have sent a response
             * back to the client.  So, send an error response.
             */
            Ns_ConnReturnInternalError(conn);
            status = NS_FILTER_RETURN; /* to allow tracing to happen */
        }
    }
    Ns_ConnClose(conn);
    if (status == NS_OK || status == NS_FILTER_RETURN) {
	status = NsRunFilters(conn, NS_FILTER_TRACE);
	if (status == NS_OK) {
	    (void) NsRunFilters(conn, NS_FILTER_VOID_TRACE);
	    NsRunTraces(conn);
	}
    }

    /*
     * Cleanup the connections, calling any registered cleanup traces
     * followed by free the connection interp if it was used.
     */

    NsRunCleanups(conn);
    NsFreeConnInterp(connPtr);
}