⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_ajp_common.c

📁 jboss与apache集成的中间件,详情请参看文档说明.
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {        jk_log(l, JK_LOG_INFO,               "awaited reply cpong, not received");        JK_TRACE_EXIT(l);        return JK_FALSE;    }    if ((cmd = jk_b_get_byte(msg)) != AJP13_CPONG_REPLY) {        jk_log(l, JK_LOG_INFO,               "awaited reply cpong, received %d instead",               cmd);        JK_TRACE_EXIT(l);        return JK_FALSE;    }    JK_TRACE_EXIT(l);    return JK_TRUE;}int ajp_connect_to_endpoint(ajp_endpoint_t * ae, jk_logger_t *l){    char buf[32];    int rc = JK_TRUE;    JK_TRACE_ENTER(l);    ae->sd = jk_open_socket(&ae->worker->worker_inet_addr,                            ae->worker->keepalive,                            ae->worker->socket_timeout,                            ae->worker->socket_buf, l);    if (ae->sd >= 0) {        if (JK_IS_DEBUG_LEVEL(l)) {            jk_log(l, JK_LOG_DEBUG,                   "Connected socket %d to (%s)",                   ae->sd,                   jk_dump_hinfo(&ae->worker->worker_inet_addr, buf));        }        /* set last_access only if needed */        if (ae->worker->cache_timeout > 0 || ae->worker->recycle_timeout > 0)            ae->last_access = time(NULL);        /* Check if we must execute a logon after the physical connect */        if (ae->worker->logon != NULL) {            rc = ae->worker->logon(ae, l);            JK_TRACE_EXIT(l);            return rc;        }        /* should we send a CPING to validate connection ? */        if (ae->worker->connect_timeout > 0) {            rc = ajp_handle_cping_cpong (ae,                        ae->worker->connect_timeout, l);            JK_TRACE_EXIT(l);            return rc;        }        JK_TRACE_EXIT(l);        return JK_TRUE;    }    jk_log(l, JK_LOG_INFO,           "Failed opening socket to (%s) with (errno=%d)",           jk_dump_hinfo(&ae->worker->worker_inet_addr, buf), errno);    JK_TRACE_EXIT(l);    return JK_FALSE;}/* * Send a message to endpoint, using corresponding PROTO HEADER */int ajp_connection_tcp_send_message(ajp_endpoint_t * ae,                                    jk_msg_buf_t *msg, jk_logger_t *l){    int rc;    JK_TRACE_ENTER(l);    if (ae->proto == AJP13_PROTO) {        jk_b_end(msg, AJP13_WS_HEADER);        if (JK_IS_DEBUG_LEVEL(l))            jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp13", msg);    }    else if (ae->proto == AJP14_PROTO) {        jk_b_end(msg, AJP14_WS_HEADER);        if (JK_IS_DEBUG_LEVEL(l))            jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp14", msg);    }    else {        jk_log(l, JK_LOG_ERROR,               "unknown protocol %d, supported are AJP13/AJP14", ae->proto);        JK_TRACE_EXIT(l);        return JK_FATAL_ERROR;    }    if ((rc = jk_tcp_socket_sendfull(ae->sd, msg->buf,                                     msg->len)) > 0) {        ae->endpoint.wr += msg->len;        JK_TRACE_EXIT(l);        return JK_TRUE;    }    jk_log(l, JK_LOG_ERROR,           "sendfull returned %d with errno=%d ", rc, errno);    JK_TRACE_EXIT(l);    return JK_FALSE;}/* * Receive a message from endpoint, checking PROTO HEADER */int ajp_connection_tcp_get_message(ajp_endpoint_t * ae,                                   jk_msg_buf_t *msg, jk_logger_t *l){    unsigned char head[AJP_HEADER_LEN];    int rc;    int msglen;    unsigned int header;    char buf[32];    JK_TRACE_ENTER(l);    rc = jk_tcp_socket_recvfull(ae->sd, head, AJP_HEADER_LEN);    if (rc < 0) {        if (rc == JK_SOCKET_EOF) {            jk_log(l, JK_LOG_INFO,                   "Tomcat has forced a connection close for socket %d",                   ae->sd);            JK_TRACE_EXIT(l);        }        else {            jk_log(l, JK_LOG_ERROR,                   "Can't receive the response message from tomcat, "                   "network problems or tomcat is down (%s), err=%d",                   jk_dump_hinfo(&ae->worker->worker_inet_addr, buf), rc);             JK_TRACE_EXIT(l);        }        return JK_FALSE;    }    ae->endpoint.rd += rc;    header = ((unsigned int)head[0] << 8) | head[1];    if (ae->proto == AJP13_PROTO) {        if (header != AJP13_SW_HEADER) {            if (header == AJP14_SW_HEADER) {                jk_log(l, JK_LOG_ERROR,                       "received AJP14 reply on an AJP13 connection from %s",                       jk_dump_hinfo(&ae->worker->worker_inet_addr, buf));            }            else {                jk_log(l, JK_LOG_ERROR,                       "wrong message format 0x%04x from %s",                       header, jk_dump_hinfo(&ae->worker->worker_inet_addr,                                             buf));            }            JK_TRACE_EXIT(l);            return JK_FALSE;        }    }    else if (ae->proto == AJP14_PROTO) {        if (header != AJP14_SW_HEADER) {            if (header == AJP13_SW_HEADER) {                jk_log(l, JK_LOG_ERROR,                       "received AJP13 reply on an AJP14 connection from %s",                       jk_dump_hinfo(&ae->worker->worker_inet_addr, buf));            }            else {                jk_log(l, JK_LOG_ERROR,                       "wrong message format 0x%04x from %s",                       header, jk_dump_hinfo(&ae->worker->worker_inet_addr,                                             buf));            }            JK_TRACE_EXIT(l);            return JK_FALSE;        }    }    msglen = ((head[2] & 0xff) << 8);    msglen += (head[3] & 0xFF);    if (msglen > msg->maxlen) {        jk_log(l, JK_LOG_ERROR,               "wrong message size %d %d from %s",               msglen, msg->maxlen,               jk_dump_hinfo(&ae->worker->worker_inet_addr, buf));        JK_TRACE_EXIT(l);        return JK_FALSE;    }    msg->len = msglen;    msg->pos = 0;    rc = jk_tcp_socket_recvfull(ae->sd, msg->buf, msglen);    if (rc < 0) {        jk_log(l, JK_LOG_ERROR,               "ERROR: can't receive the response message from tomcat, "               "network problems or tomcat (%s) is down %d",               jk_dump_hinfo(&ae->worker->worker_inet_addr, buf), rc);        JK_TRACE_EXIT(l);        return JK_FALSE;    }    ae->endpoint.rd += rc;    if (ae->proto == AJP13_PROTO) {        if (JK_IS_DEBUG_LEVEL(l))            jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp13", msg);    }    else if (ae->proto == AJP14_PROTO) {        if (JK_IS_DEBUG_LEVEL(l))            jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp14", msg);    }    JK_TRACE_EXIT(l);    return JK_TRUE;}/* * Read all the data from the socket. * * Socket API doesn't guaranty that all the data will be kept in a * single read, so we must loop until all awaited data is received */static int ajp_read_fully_from_server(jk_ws_service_t *s, jk_logger_t *l,                                      unsigned char *buf, unsigned int len){    unsigned int rdlen = 0;    unsigned int padded_len = len;    JK_TRACE_ENTER(l);    if (s->is_chunked && s->no_more_chunks) {        JK_TRACE_EXIT(l);        return 0;    }    if (s->is_chunked) {        /* Corner case: buf must be large enough to hold next         * chunk size (if we're on or near a chunk border).         * Pad the length to a reasonable value, otherwise the         * read fails and the remaining chunks are tossed.         */        padded_len = (len < CHUNK_BUFFER_PAD) ? len : len - CHUNK_BUFFER_PAD;    }    while (rdlen < padded_len) {        unsigned int this_time = 0;        if (!s->read(s, buf + rdlen, len - rdlen, &this_time)) {            /* Remote Client read failed. */            JK_TRACE_EXIT(l);            return JK_CLIENT_ERROR;        }        if (0 == this_time) {            if (s->is_chunked) {                s->no_more_chunks = 1;  /* read no more */            }            break;        }        rdlen += this_time;    }    return (int)rdlen;}/* * Read data from AJP13/AJP14 protocol * Returns -1 on error, else number of bytes read */static int ajp_read_into_msg_buff(ajp_endpoint_t * ae,                                  jk_ws_service_t *r,                                  jk_msg_buf_t *msg, int len, jk_logger_t *l){    unsigned char *read_buf = msg->buf;    JK_TRACE_ENTER(l);    jk_b_reset(msg);    read_buf += AJP_HEADER_LEN; /* leave some space for the buffer headers */    read_buf += AJP_HEADER_SZ_LEN;      /* leave some space for the read length */    /* Pick the max size since we don't know the content_length */    if (r->is_chunked && len == 0) {        len = AJP13_MAX_SEND_BODY_SZ;    }    if ((len = ajp_read_fully_from_server(r, l, read_buf, len)) < 0) {        jk_log(l, JK_LOG_INFO,               "Receiving data from client failed. "               "Connection aborted or network problems");        JK_TRACE_EXIT(l);        return JK_CLIENT_ERROR;    }    if (!r->is_chunked) {        ae->left_bytes_to_send -= len;    }    if (len > 0) {        /* Recipient recognizes empty packet as end of stream, not           an empty body packet */        if (0 != jk_b_append_int(msg, (unsigned short)len)) {            jk_log(l, JK_LOG_INFO,                   "Failed appending message length");            JK_TRACE_EXIT(l);            return JK_CLIENT_ERROR;        }    }    msg->len += len;    JK_TRACE_EXIT(l);    return len;}/* * send request to Tomcat via Ajp13 * - first try to find reuseable socket * - if no one available, try to connect * - send request, but send must be see as asynchronous, *   since send() call will return noerror about 95% of time *   Hopefully we'll get more information on next read. * * nb: reqmsg is the original request msg buffer *     repmsg is the reply msg buffer which could be scratched */static int ajp_send_request(jk_endpoint_t *e,                            jk_ws_service_t *s,                            jk_logger_t *l,                            ajp_endpoint_t * ae, ajp_operation_t * op){    int err = 0;    int postlen;    JK_TRACE_ENTER(l);    /* Up to now, we can recover */    op->recoverable = JK_TRUE;    /*     * First try to reuse open connections...     */    while ((ae->sd > 0)) {        int rc = 0;        err = 0;        if (ae->worker->socket_timeout) {            if (!jk_is_socket_connected(ae->sd)) {                jk_log(l, JK_LOG_INFO,                       "Socket %d is not connected any more (errno=%d)",                       ae->sd, errno);                jk_close_socket(ae->sd);                ae->sd = -1;                err++;            }        }        if (ae->worker->prepost_timeout != 0 && !err) {            /* handle cping/cpong if prepost_timeout is set             * If the socket is disconnected no need to handle             * the cping/cpong             */            if (ajp_handle_cping_cpong(ae, ae->worker->prepost_timeout, l) ==                JK_FALSE)                err++;        }        /* If we got an error or can't send data, then try to get a pooled         * connection and try again.  If we are succesful, break out of this         * loop. */        if (err ||            ((rc = ajp_connection_tcp_send_message(ae, op->request, l)) != JK_TRUE)) {            if (rc != JK_FATAL_ERROR) {                jk_log(l, JK_LOG_INFO,                       "Error sending request. Will try another pooled connection");                ajp_next_connection(ae, l);            }            else {                op->recoverable = JK_FALSE;                jk_log(l, JK_LOG_INFO,                       "Error sending request. Unrecoverable operation");                JK_TRACE_EXIT(l);                return JK_FALSE;            }        }        else            break;    }    /*     * If we failed to reuse a connection, try to reconnect.     */    if (ae->sd < 0) {        if (err) {            /* XXX: If err is set, the tomcat is either dead or disconnected */            jk_log(l, JK_LOG_INFO,                   "All endpoints are disconnected or dead");            JK_TRACE_EXIT(l);            return JK_FALSE;        }        /* no need to handle cping/cpong here since it should be at connection time */        if (ajp_connect_to_endpoint(ae, l) == JK_TRUE) {            /*             * After we are connected, each error that we are going to             * have is probably unrecoverable             */            if (ajp_connection_tcp_send_message(ae, op->request, l) != JK_TRUE) {                jk_log(l, JK_LOG_INFO,                       "Error sending request on a fresh connection");                JK_TRACE_EXIT(l);                return JK_FALSE;            }        }        else {            /* Close the socket if unable to connect */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -