Kevin Convy (Contractor) wrote:
I am having an issue posting a large request (that also requires
authentication) through a Sun One/IPlanet 6.0sp5 webserver to Tomcat 5.5
using the 1.2.8 nsapi_redirector. The client that is doing the posting
gets a server write error if the request body is over a certain size
(~150K). The issue occurs on both the Windows XP and Solaris
versions.The issue does NOT occur using an Apache-mod_jk configuration.
If I use the attached version of the ajp_process_callback method in
jk_ajp_common.c (changes from the 1.2.8 version of the code are marked
with KCADD comments) it resolves the problem.

A diff -u would help to see your changes.

It seems to resolve it by
making sure the entire request body is read off the netbuf before
turning around and starting the response (which occurs in this case
because an authentication challenge is sent before the entire request is
read by tomcat). I don't mean to offer this as a fix, but I was
wondering if this is a known issue and if there is a better fix
somewhere. I sent a slightly different version of this email to the tomcat-user
list a couple of weeks ago and apologize for the cross-post.
Thanks, Kevin Convy
Icebox LLC
static int ajp_process_callback(jk_msg_buf_t *msg,
                                jk_msg_buf_t *pmsg,
                                ajp_endpoint_t * ae,
                                jk_ws_service_t *r, jk_logger_t *l)
{
    int code = (int)jk_b_get_byte(msg);
    // KCADD
    int bytesread = 0;
    unsigned char buf1[AJP13_MAX_SEND_BODY_SZ];
JK_TRACE_ENTER(l);
    switch (code) {
    case JK_AJP13_SEND_HEADERS:
        {
            jk_res_data_t res;
            if (!ajp_unmarshal_response(msg, &res, ae, l)) {
                jk_log(l, JK_LOG_ERROR,
                       "ajp_unmarshal_response failed\n");
                JK_TRACE_EXIT(l);
                return JK_AJP13_ERROR;
            }
//KCADD
            // make sure the entire request body has been read.
            jk_log(l, JK_LOG_INFO, "KCDEBUG: this many bytes left: %d",
ae->left_bytes_to_send);
            while(ae->left_bytes_to_send > 0) {
                r->read(r, buf1, AJP13_MAX_SEND_BODY_SZ, &bytesread);
                ae->left_bytes_to_send -= bytesread;
            }
r->start_response(r, res.status, res.msg,
                              (const char *const *)res.header_names,
                              (const char *const *)res.header_values,
                              res.num_headers);
        }
        return JK_AJP13_SEND_HEADERS;
case JK_AJP13_SEND_BODY_CHUNK:
        {
            unsigned len = (unsigned)jk_b_get_int(msg);
            if (!r->write(r, jk_b_get_buff(msg) + jk_b_get_pos(msg),
len)) {
                jk_log(l, JK_LOG_INFO,
                       "Connection aborted or network problems\n");
                JK_TRACE_EXIT(l);
                return JK_CLIENT_ERROR;
            }
        }
        break;
case JK_AJP13_GET_BODY_CHUNK:
        {
            int len = (int)jk_b_get_int(msg);
if (len < 0) {
                len = 0;
            }
            if (len > AJP13_MAX_SEND_BODY_SZ) {
                len = AJP13_MAX_SEND_BODY_SZ;
            }
            if ((unsigned int)len > ae->left_bytes_to_send) {
                len = ae->left_bytes_to_send;
            }
/* the right place to add file storage for upload */
            if ((len = ajp_read_into_msg_buff(ae, r, pmsg, len, l)) >=
0) {
                r->content_read += len;
                JK_TRACE_EXIT(l);
                return JK_AJP13_HAS_RESPONSE;
            }
jk_log(l, JK_LOG_INFO,
                   "Connection aborted or network problems\n");
JK_TRACE_EXIT(l);
            return JK_CLIENT_ERROR;
        }
        break;
case JK_AJP13_END_RESPONSE:
        {
            ae->reuse = (int)jk_b_get_byte(msg);
if (!ae->reuse) {
                /*
                 * Strange protocol error.
                 */
                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG, "Reuse: %d\n", ae->reuse);
                ae->reuse = JK_FALSE;
            }
            /* Reuse in all cases */
            ae->reuse = JK_TRUE;
        }
        JK_TRACE_EXIT(l);
        return JK_AJP13_END_RESPONSE;
        break;
default:
        jk_log(l, JK_LOG_ERROR,
               "Invalid code: %d\n", code);
        JK_TRACE_EXIT(l);
        return JK_AJP13_ERROR;
    }
JK_TRACE_EXIT(l);
    return JK_AJP13_NO_RESPONSE;
}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to