jk_ajp12_worker.c

来自「精通tomcat书籍原代码,希望大家共同学习」· C语言 代码 · 共 656 行 · 第 1/2 页

C
656
字号
    }
    else {
        return ajpv12_sendnbytes(p, NULL, 0);
    }
}

static int ajpv12_mark(ajp12_endpoint_t * p, unsigned char type)
{
    if (jk_sb_write(&p->sb, &type, 1)) {
        return JK_TRUE;
    }
    else {
        return JK_FALSE;
    }
}

static int ajpv12_sendint(ajp12_endpoint_t * p, int d)
{
    char buf[20];
    sprintf(buf, "%d", d);
    return ajpv12_sendstring(p, buf);
}

static int ajpv12_flush(ajp12_endpoint_t * p)
{
    return jk_sb_flush(&p->sb);
}

static int ajpv12_handle_request(ajp12_endpoint_t * p,
                                 jk_ws_service_t *s, jk_logger_t *l)
{
    int ret;

    jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_request");
    /*
     * Start the ajp 12 service sequence
     */
    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_request, sending the ajp12 start sequence");

    ret = (ajpv12_mark(p, 1) && ajpv12_sendstring(p, s->method) && ajpv12_sendstring(p, 0) &&   /* zone */
           ajpv12_sendstring(p, 0) &&   /* servlet */
           ajpv12_sendstring(p, s->server_name) && ajpv12_sendstring(p, 0) &&   /* doc root */
           ajpv12_sendstring(p, 0) &&   /* path info */
           ajpv12_sendstring(p, 0) &&   /* path translated */
#ifdef AS400
           ajpv12_sendasciistring(p, s->query_string) &&
#else
           ajpv12_sendstring(p, s->query_string) &&
#endif
           ajpv12_sendstring(p, s->remote_addr) &&
           ajpv12_sendstring(p, s->remote_host) &&
           ajpv12_sendstring(p, s->remote_user) &&
           ajpv12_sendstring(p, s->auth_type) &&
           ajpv12_sendint(p, s->server_port) &&
#ifdef AS400
           ajpv12_sendasciistring(p, s->method) &&
#else
           ajpv12_sendstring(p, s->method) &&
#endif
           ajpv12_sendstring(p, s->req_uri) && ajpv12_sendstring(p, 0) &&       /* */
           ajpv12_sendstring(p, 0) &&   /* SCRIPT_NAME */
#ifdef AS400
           ajpv12_sendasciistring(p, s->server_name) &&
#else
           ajpv12_sendstring(p, s->server_name) &&
#endif
           ajpv12_sendint(p, s->server_port) && ajpv12_sendstring(p, s->protocol) && ajpv12_sendstring(p, 0) && /* SERVER_SIGNATURE */
           ajpv12_sendstring(p, s->server_software) && ajpv12_sendstring(p, s->jvm_route) &&    /* JSERV_ROUTE */
           ajpv12_sendstring(p, "") &&  /* JSERV ajpv12 compatibility */
           ajpv12_sendstring(p, ""));   /* JSERV ajpv12 compatibility */

    if (!ret) {
        jk_log(l, JK_LOG_ERROR,
               "In ajpv12_handle_request, failed to send the ajp12 start sequence");
        return JK_FALSE;
    }

    if (s->num_attributes > 0) {
        unsigned i;
        jk_log(l, JK_LOG_DEBUG,
               "ajpv12_handle_request, sending the environment variables");

        for (i = 0; i < s->num_attributes; i++) {
            ret = (ajpv12_mark(p, 5) &&
                   ajpv12_sendstring(p, s->attributes_names[i]) &&
                   ajpv12_sendstring(p, s->attributes_values[i]));
            if (!ret) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to send environment");
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the headers");

    /* Send the request headers */
    if (s->num_headers) {
        unsigned i;
        for (i = 0; i < s->num_headers; ++i) {
            ret = (ajpv12_mark(p, 3) &&
                   ajpv12_sendstring(p, s->headers_names[i]) &&
                   ajpv12_sendstring(p, s->headers_values[i]));

            if (!ret) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to send headers");
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_request, sending the terminating mark");

    ret = (ajpv12_mark(p, 4) && ajpv12_flush(p));
    if (!ret) {
        jk_log(l, JK_LOG_ERROR,
               "In ajpv12_handle_request, failed to send the terminating mark");
        return JK_FALSE;
    }

    if (s->content_length) {
        char buf[READ_BUF_SIZE];
        unsigned so_far = 0;

        jk_log(l, JK_LOG_DEBUG,
               "ajpv12_handle_request, sending the request body");

        while (so_far < s->content_length) {
            unsigned this_time = 0;
            unsigned to_read = s->content_length - so_far;
            if (to_read > READ_BUF_SIZE) {
                to_read = READ_BUF_SIZE;
            }

            if (!s->read(s, buf, to_read, &this_time)) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to read from the web server");
                return JK_FALSE;
            }
            jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, read %d bytes",
                   this_time);
            if (this_time > 0) {
                so_far += this_time;
                if ((int)this_time != send(p->sd, buf, this_time, 0)) {
                    jk_log(l, JK_LOG_ERROR,
                           "In ajpv12_handle_request, failed to write to the container");
                    return JK_FALSE;
                }
                jk_log(l, JK_LOG_DEBUG,
                       "ajpv12_handle_request, sent %d bytes", this_time);
            }
            else if (this_time == 0) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, Error: short read. content length is %d, read %d",
                       s->content_length, so_far);
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request done");
    return JK_TRUE;
}

static int ajpv12_handle_response(ajp12_endpoint_t * p,
                                  jk_ws_service_t *s, jk_logger_t *l)
{
    int status = 200;
    char *reason = NULL;
    char **names = NULL;
    char **values = NULL;
    int headers_capacity = 0;
    int headers_len = 0;
    int write_to_ws;

    jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_response");
    /*
     * Read headers ...
     */
    while (1) {
        char *line = NULL;
        char *name = NULL;
        char *value = NULL;
#if defined(AS400) || defined(_REENTRANT)
        char *lasts;
#endif

        if (!jk_sb_gets(&p->sb, &line)) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, error reading header line");
            return JK_FALSE;
        }
#if defined(AS400) || defined(_OSD_POSIX)
        jk_xlate_from_ascii(line, strlen(line));
#endif

        jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s", line);
        if (0 == strlen(line)) {
            jk_log(l, JK_LOG_DEBUG,
                   "ajpv12_handle_response, headers are done");
            break;              /* Empty line -> end of headers */
        }

        name = line;
        while (isspace(*name) && *name) {
            name++;             /* Skip leading white chars */
        }
        if (!*name) {           /* Empty header name */
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, empty header name");
            return JK_FALSE;
        }
        if (!(value = strchr(name, ':'))) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, no value supplied");
            return JK_FALSE;    /* No value !!! */
        }
        *value = '\0';
        value++;
        while (isspace(*value) && *value) {
            value++;            /* Skip leading white chars */
        }
        if (!*value) {          /* Empty header value */
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, empty header value");
            return JK_FALSE;
        }

        jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s=%s", name,
               value);
        if (0 == strcmp("Status", name)) {
#if defined(AS400) || defined(_REENTRANT)
            char *numeric = strtok_r(value, " \t", &lasts);
#else
            char *numeric = strtok(value, " \t");
#endif

            status = atoi(numeric);
            if (status < 100 || status > 999) {
                jk_log(l, JK_LOG_ERROR,
                       "ajpv12_handle_response, invalid status code");
                return JK_FALSE;
            }
#if defined(AS400) || defined(_REENTRANT)
            reason = jk_pool_strdup(s->pool, strtok_r(NULL, " \t", &lasts));
#else
            reason = jk_pool_strdup(s->pool, strtok(NULL, " \t"));
#endif
        }
        else {
            if (headers_capacity == headers_len) {
                jk_log(l, JK_LOG_DEBUG,
                       "ajpv12_handle_response, allocating header arrays");
                names =
                    (char **)jk_pool_realloc(s->pool,
                                             sizeof(char *) *
                                             (headers_capacity + 5), names,
                                             sizeof(char *) *
                                             headers_capacity);
                values =
                    (char **)jk_pool_realloc(s->pool,
                                             sizeof(char *) *
                                             (headers_capacity + 5), values,
                                             sizeof(char *) *
                                             headers_capacity);
                if (!values || !names) {
                    jk_log(l, JK_LOG_ERROR,
                           "ajpv12_handle_response, malloc error");
                    return JK_FALSE;
                }
                headers_capacity = headers_capacity + 5;
            }
            names[headers_len] = jk_pool_strdup(s->pool, name);
            values[headers_len] = jk_pool_strdup(s->pool, value);
            headers_len++;
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, starting response");
    if (!s->start_response(s,
                           status,
                           reason,
                           (const char *const *)names,
                           (const char *const *)values, headers_len)) {
        jk_log(l, JK_LOG_ERROR,
               "ajpv12_handle_response, error starting response");
        return JK_FALSE;
    }

    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_response, reading response body");
    /*
     * Read response body
     */
    write_to_ws = JK_TRUE;
    while (1) {
        unsigned to_read = READ_BUF_SIZE;
        unsigned acc = 0;
        char *buf = NULL;

        if (!jk_sb_read(&p->sb, &buf, to_read, &acc)) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, error reading from ");
            return JK_FALSE;
        }

        if (!acc) {
            jk_log(l, JK_LOG_DEBUG,
                   "ajpv12_handle_response, response body is done");
            break;
        }

        if (write_to_ws) {
            if (!s->write(s, buf, acc)) {
                jk_log(l, JK_LOG_ERROR,
                       "ajpv12_handle_response, error writing back to server");
                write_to_ws = JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response done");
    return JK_TRUE;
}

⌨️ 快捷键说明

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