On Sat, Nov 8, 2008 at 5:00 AM, Vlad Seryakov <[EMAIL PROTECTED]> wrote:
> Yes, keep-alive is the key, nshttp_test closes connection so it cannot
> test this

/*
 * php_ns_sapi_send_headers() flushes the headers to the client.
 * Called before real content is sent by PHP.
 */

static int php_ns_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
    ns_context *ctx = SG(server_context);

    if (ctx->conn != NULL) {
        Ns_ConnSetResponseStatus(ctx->conn,
SG(sapi_headers).http_response_code);
    }

    Ns_ConnWriteData(ctx->conn, NULL, 0, NS_CONN_STREAM);

    return SAPI_HEADER_SENT_SUCCESSFULLY;
}


Does this actually need to flush?

It depends when php calls it. In the case where there's no body, eg. a
302 redirect, then maybe this signals 'all done' and you're to write
the headers. In the case where there is a body it's not needed because
naviserver will construct and dump the headers when you try to write
the first data, and it will send both with a single syscall (and
packet, if it fits), which is more efficient.

So you should try not to flush. You might try to do nothing in this
call, and detect when you've finished sending in the case of a
zero-length body some other way. When php returns control to your
Ns_Op function you could check to see if any bytes were sent and if
not, flush the headers.

But anyway, you're checking for ctx->conn != NULL before setting the
response code, then using it unconditionally when you write the data.

Ns_ConnWriteData can fail but you're ignoring the return code and
returning success.




/*
 * php_ns_sapi_header_handler() sets a HTTP reply header to be sent to
the client.
 */


Does php try to set a length header? You may need to check for it in
here and call Ns_ConnSetLengthHeader.



/*
 * php_ns_sapi_ub_write() writes data to the client connection.
 */

static int php_ns_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
    ns_context *ctx = SG(server_context);

    if (!ctx->conn) {
        int size = ctx->buffer ? strlen(ctx->buffer) : 0;
        ctx->buffer = ns_realloc(ctx->buffer, size + str_length + 1);
        strncpy(&(ctx->buffer[size]), str, str_length);
        ctx->buffer[size + str_length] = 0;
        return str_length;
    }

    if (Ns_ConnWriteData(ctx->conn, (void *) str, str_length,
NS_CONN_STREAM) != NS_OK) {
        php_handle_aborted_connection();
    }

    return str_length;
}


Whether the write succeeds or fails, you're returning the original
buffer length, which I guess signals success to php. It might be hard
to figure out exactly how much did get sent, because
conn->nContentSent includes the headers bytes. But maybe php doesn't
care? You'll have to check if you can return -1 or 0 or something.

You might also want to check if php exposes it's buffering. If you can
figure out that your ub_write call is being called with all the data
that's going to be sent (the script has finished executing) or the
last piece of data, you shouldn't pass the flag NS_CONN_STREAM.
Otherwise, you should.



> I tried that but could not get it to work, it generates configure but
> when i run it i never could make it finish, there are always some errors.



Do you need to buy into the full build process? Maybe you can just
pull in the header and link against the library..?

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