`
cywhoyi
  • 浏览: 421033 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Apache扩展对于webservice指定机器请求

 
阅读更多

Mod_jk是apache module模块中鼎鼎大名的

static int jk_handler(request_rec * r)
{
    const char *worker_name;
    jk_server_conf_t *xconf;
    jk_request_conf_t *rconf;
    int rc, dmt = 1;
    int worker_name_extension = JK_FALSE;

    /* We do DIR_MAGIC_TYPE here to make sure TC gets all requests, even
     * if they are directory requests, in case there are no static files
     * visible to Apache and/or DirectoryIndex was not used. This is only
     * used when JkOptions has ForwardDirectories set. */
    /* Not for me, try next handler */
    if (strcmp(r->handler, JK_HANDLER)
        && (dmt = strcmp(r->handler, DIR_MAGIC_TYPE)))
        return DECLINED;

    xconf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config,
                                                      &jk_module);
    JK_TRACE_ENTER(xconf->log);
    if (apr_table_get(r->subprocess_env, "no-jk")) {
        if (JK_IS_DEBUG_LEVEL(xconf->log))
            jk_log(xconf->log, JK_LOG_DEBUG,
                   "Into handler no-jk env var detected for uri=%s, declined",
                   r->uri);

        JK_TRACE_EXIT(xconf->log);
        return DECLINED;
    }

    /* Was the option to forward directories to Tomcat set? */
    if (!dmt && !(xconf->options & JK_OPT_FWDDIRS)) {
        JK_TRACE_EXIT(xconf->log);
        return DECLINED;
    }

    worker_name = apr_table_get(r->notes, JK_NOTE_WORKER_NAME);

    if (worker_name == NULL) {
        /* we may be here because of a manual directive ( that overrides
           translate and
           sets the handler directly ). We still need to know the worker.
         */
        worker_name = apr_table_get(r->subprocess_env, xconf->worker_indicator);
        if (worker_name) {
          /* The JkWorkerIndicator environment variable has
           * been used to explicitely set the worker without JkMount.
           * This is useful in combination with LocationMatch or mod_rewrite.
           */
            if (JK_IS_DEBUG_LEVEL(xconf->log))
                jk_log(xconf->log, JK_LOG_DEBUG,
                       "Retrieved worker (%s) from env %s for %s",
                       worker_name, xconf->worker_indicator, r->uri);
            if (ap_strchr_c(worker_name, ';')) {
                rule_extension_t *e = apr_palloc(r->pool, sizeof(rule_extension_t));
                char *w = apr_pstrdup(r->pool, worker_name);
                worker_name_extension = JK_TRUE;
                parse_rule_extensions(w, e, xconf->log);
                worker_name = w;
                rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config,
                                                                  &jk_module);
                rconf->rule_extensions = e;
            }
        }
        else if (worker_env.num_of_workers == 1) {
          /** We have a single worker ( the common case ).
              ( lb is a bit special, it should count as a single worker but
              I'm not sure how ). We also have a manual config directive that
              explicitely give control to us. */
            worker_name = worker_env.worker_list[0];
            if (JK_IS_DEBUG_LEVEL(xconf->log))
                jk_log(xconf->log, JK_LOG_DEBUG,
                       "Single worker (%s) configuration for %s",
                       worker_name, r->uri);
        }
        else {
            if (!xconf->uw_map) {
                if (JK_IS_DEBUG_LEVEL(xconf->log))
                    jk_log(xconf->log, JK_LOG_DEBUG,
                           "missing uri map for %s:%s",
                           xconf->s->server_hostname ? xconf->s->server_hostname : "_default_",
                           r->uri);
            }
            else {
                rule_extension_t *e;
                worker_name = map_uri_to_worker_ext(xconf->uw_map, r->uri,
                                                    NULL, &e, NULL, xconf->log);
                rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config,
                                                                  &jk_module);
                rconf->rule_extensions = e;
            }

            if (worker_name == NULL && worker_env.num_of_workers) {
                worker_name = worker_env.worker_list[0];
                if (JK_IS_DEBUG_LEVEL(xconf->log))
                    jk_log(xconf->log, JK_LOG_DEBUG,
                           "Using first worker (%s) from %d workers for %s",
                           worker_name, worker_env.num_of_workers, r->uri);
            }
        }
        if (worker_name)
            apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker_name);
    }

    if (JK_IS_DEBUG_LEVEL(xconf->log))
       jk_log(xconf->log, JK_LOG_DEBUG, "Into handler %s worker=%s"
              " r->proxyreq=%d",
              r->handler, STRNULL_FOR_NULL(worker_name), r->proxyreq);

    rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config,
                                                      &jk_module);
    rconf->jk_handled = JK_TRUE;

    /* If this is a proxy request, we'll notify an error */
    if (r->proxyreq) {
        jk_log(xconf->log, JK_LOG_INFO, "Proxy request for worker=%s"
              " is not allowed",
              STRNULL_FOR_NULL(worker_name));
        JK_TRACE_EXIT(xconf->log);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Set up r->read_chunked flags for chunked encoding, if present */
    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != APR_SUCCESS) {
        JK_TRACE_EXIT(xconf->log);
        return rc;
    }

    if (worker_name) {
        jk_worker_t *worker = wc_get_worker_for_name(worker_name, xconf->log);

        /* If the remote client has aborted, just ignore the request */
        if (r->connection->aborted) {
            jk_log(xconf->log, JK_LOG_INFO, "Client connection aborted for"
                   " worker=%s",
                   worker_name);
            JK_TRACE_EXIT(xconf->log);
            return OK;
        }

        if (worker) {
            long micro, seconds;
            char *duration = NULL;
            apr_time_t rd;
            apr_time_t request_begin = 0;
            int is_error = HTTP_INTERNAL_SERVER_ERROR;
            int rc = JK_FALSE;
            apache_private_data_t private_data;
            jk_ws_service_t s;
            jk_pool_atom_t buf[SMALL_POOL_SIZE];
            jk_open_pool(&private_data.p, buf, sizeof(buf));

            private_data.read_body_started = JK_FALSE;
            private_data.r = r;

            if (worker_name_extension == JK_TRUE) {
                extension_fix(&private_data.p, worker_name,
                              rconf->rule_extensions, xconf->log);
            }

            /* Maintain will be done by watchdog thread */
            if (!jk_watchdog_interval)
                wc_maintain(xconf->log);
            jk_init_ws_service(&s);
            s.ws_private = &private_data;
            s.pool = &private_data.p;
            apr_table_setn(r->notes, JK_NOTE_WORKER_TYPE,
                           wc_get_name_for_type(worker->type, xconf->log));

            request_begin = apr_time_now();

            if (init_ws_service(&private_data, &s, xconf)) {
                jk_endpoint_t *end = NULL;

                /* Use per/thread pool ( or "context" ) to reuse the
                   endpoint. It's a bit faster, but I don't know
                   how to deal with load balancing - but it's usefull for JNI
                 */

                /* worker->get_endpoint might fail if we are out of memory so check */
                /* and handle it */
                if (worker->get_endpoint(worker, &end, xconf->log)) {
                    rc = end->service(end, &s, xconf->log,
                                      &is_error);
                    end->done(&end, xconf->log);
                    if (s.content_read < s.content_length ||
                        (s.is_chunked && !s.no_more_chunks)) {
                        /*
                         * If the servlet engine didn't consume all of the
                         * request data, consume and discard all further
                         * characters left to read from client
                         */
                        char *buff = apr_palloc(r->pool, 2048);
                        int consumed = 0;
                        if (buff != NULL) {
                            int rd;
                            while ((rd =
                                    ap_get_client_block(r, buff, 2048)) > 0) {
                                s.content_read += rd;
                                consumed += rd;
                            }
                        }
                        if (JK_IS_DEBUG_LEVEL(xconf->log)) {
                           jk_log(xconf->log, JK_LOG_DEBUG,
                                  "Consumed %d bytes of remaining request data for worker=%s",
                                  consumed, STRNULL_FOR_NULL(worker_name));
                        }
                    }
                }
                else {            /* this means we couldn't get an endpoint */
                    jk_log(xconf->log, JK_LOG_ERROR, "Could not get endpoint"
                           " for worker=%s",
                           worker_name);
                    rc = 0;       /* just to make sure that we know we've failed */
                }
            }
            else {
                jk_log(xconf->log, JK_LOG_ERROR, "Could not init service"
                       " for worker=%s",
                       worker_name);
                jk_close_pool(&private_data.p);
                JK_TRACE_EXIT(xconf->log);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            rd = apr_time_now() - request_begin;
            seconds = (long)apr_time_sec(rd);
            micro = (long)(rd - apr_time_from_sec(seconds));

            duration = apr_psprintf(r->pool, "%.1ld.%.6ld", seconds, micro);
            apr_table_setn(r->notes, JK_NOTE_REQUEST_DURATION, duration);
            if (s.route && *s.route)
                apr_table_setn(r->notes, JK_NOTE_WORKER_ROUTE, s.route);

            jk_close_pool(&private_data.p);

            if (rc > 0) {
                if (s.extension.use_server_error_pages &&
                    s.http_response_status >= s.extension.use_server_error_pages) {
                    if (JK_IS_DEBUG_LEVEL(xconf->log))
                        jk_log(xconf->log, JK_LOG_DEBUG, "Forwarding status=%d"
                               " for worker=%s",
                               s.http_response_status, worker_name);
                    JK_TRACE_EXIT(xconf->log);
                    return s.http_response_status;
                }
                /* If tomcat returned no body and the status is not OK,
                   let apache handle the error code */

                if (!r->sent_bodyct && r->status >= HTTP_BAD_REQUEST) {
                    jk_log(xconf->log, JK_LOG_INFO, "No body with status=%d"
                           " for worker=%s",
                           r->status, worker_name);
                    JK_TRACE_EXIT(xconf->log);
                    return r->status;
                }
                if (JK_IS_DEBUG_LEVEL(xconf->log))
                    jk_log(xconf->log, JK_LOG_DEBUG, "Service finished"
                           " with status=%d for worker=%s",
                           r->status, worker_name);
                JK_TRACE_EXIT(xconf->log);
                return OK;      /* NOT r->status, even if it has changed. */
            }
            else if (rc == JK_CLIENT_ERROR) {
                if (is_error != HTTP_REQUEST_ENTITY_TOO_LARGE)
                    r->connection->aborted = 1;
                jk_log(xconf->log, JK_LOG_INFO, "Aborting connection"
                       " for worker=%s",
                       worker_name);
                JK_TRACE_EXIT(xconf->log);
                return is_error;
            }
            else {
                jk_log(xconf->log, JK_LOG_INFO, "Service error=%d"
                       " for worker=%s",
                       rc, worker_name);
                JK_TRACE_EXIT(xconf->log);
                return is_error;
            }
        }
        else {
            jk_log(xconf->log, JK_LOG_INFO, "Could not find a worker"
                   " for worker name=%s",
                   worker_name);
            JK_TRACE_EXIT(xconf->log);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    rconf->jk_handled = JK_FALSE;
    JK_TRACE_EXIT(xconf->log);
    return DECLINED;
}

 

分享到:
评论

相关推荐

    05-ApacheCamel-CXF-WebService

    本项目"05-ApacheCamel-CXF-WebService"主要探讨了如何将Apache Camel与Apache CXF整合,以实现高效的服务消费和提供。 在项目中,"05-ApacheCamel-CXF-WebService-Client"这部分内容可能是客户端的应用,用于调用...

    Apache CXF2+Spring2.5轻松实现WebService

    在上述配置中,我们定义了一个CXF的ServerFactoryBean,它会创建一个处理Web服务请求的Servlet,并指定了服务类和服务地址。同时,我们还定义了服务实现类,可以通过Spring的依赖注入来管理其依赖。 接下来,我们...

    httpClient调用webservice接口

    此外,HttpClient还具有很高的灵活性和可扩展性,能够满足各种复杂的网络请求需求。 #### 三、调用WebService的基本步骤 1. **构建SOAP消息**:WebService通常使用SOAP协议进行通信。因此,首先需要构造一个符合...

    彻底了解|利用Apache CXF框架开发WebService

    Apache CXF是一个强大的开源Web服务框架,专门用于简化和加速基于Java的Web服务开发。它不仅支持SOAP(简单对象访问协议)和RESTful(表述性状态转移)服务,还提供了丰富的特性和工具集,如拦截器,使得开发者可以...

    超简单的webservice调用

    【标题】"超简单的webservice调用"涉及的是在Java环境下使用Hutool库进行Web ...最后,如果想要扩展或优化这个示例,可以深入研究Hutool的其他功能,或者考虑使用其他的Web Service客户端库,比如Apache CXF或JAX-WS。

    apache-cxf_WebService

    Apache CXF是一个开源的Java框架,它主要用于构建和开发Web服务。这个项目的名字"CXF"代表了"CXF融合一切"(CXF = See Everything Fusion)。Apache CXF允许开发者以多种方式创建Web服务,包括使用Java API for Web ...

    WebService Axis初学者

    总结:了解和掌握WebService Axis,对于Java开发者来说至关重要,因为它能帮助你在项目中快速实现服务化,提高代码复用性和系统扩展性。通过学习和实践,你将能够自如地创建、部署和调用SOAP Web服务,进一步提升你...

    CXF打印SOAP报文,记录WebService日志

    在实际开发过程中,对于WebService的请求和响应信息进行日志记录是非常必要的。这有助于我们在出现问题时能够快速定位问题原因,并且对服务的整体性能监控也有很大帮助。CXF提供了丰富的API来实现这一功能。 #### ...

    axis2实现webservice请求

    当我们谈论 Axis2 时,我们指的是一个高效、灵活且强大的Web服务框架,它是Apache软件基金会开发的。Axis2 是用于构建和部署Web服务的第二代产品,它基于 Axis1 提供了许多改进和新特性。 **Axis2 概述** Axis2 是...

    WebService依赖jar以及xml.zip

    这些jar文件很可能包含了用于处理WebService请求和响应的库,如Apache CXF、 Axis2 或者 Metro等,它们提供了实现SOAP协议和解析WSDL文件的工具。 例如,Apache CXF是一个流行的开源框架,它提供了开发和部署SOAP和...

    Java调用WebService接口的方法

    6. **设置SOAPAction**:`setSOAPActionURI()`方法用于设置SOAP请求头的SOAPAction属性,这对于正确路由请求至关重要。 7. **调用方法**:最后,通过`call.invoke()`方法执行实际的WebService调用。此方法接收一个...

    webservice

    - **单机应用程序**:对于不需要网络通信的单机应用,使用WebService没有必要。 - **局域网上的同构应用程序**:如果应用都在同一局域网内,并且使用相同的编程语言和平台,使用更简单的通信方式可能更合适。 #### ...

    JBOSS与APACHE的整合

    第三步:配置JBOSS服务器的配置文件,指定JBOSS服务器的主机名和端口号,用于APACHE服务器的连接。 在JBOSS与APACHE的整合中,APACHE服务器充当反向代理服务器的角色,将静态网页的请求交给APACHE服务器处理,而将...

    Java写WebService客户端

    WebService客户端则用于发起请求并处理来自服务端的响应。 ##### 2. SOAP与XML SOAP(Simple Object Access Protocol)是一种轻量级的协议,用于交换结构化的和自描述的信息。它使用XML作为消息格式的规范,并使用...

    WebService调用天气预报小例子

    在天气预报的例子中,我们将通过SOAP调用来向特定的Weather WebService发送请求,获取指定地点的天气信息。 要实现这个功能,我们需要以下步骤: 1. **了解WebService接口**:首先,我们需要找到一个提供天气预报...

    Android开发之WebService介绍

    2. 发送请求:使用HttpURLConnection或Apache HttpClient库发送SOAP请求到WebService的URL。 3. 处理响应:接收并解析SOAP响应,通常是XML格式,然后转换为相应的Java对象。 4. 显示结果:将解析后的数据展示在...

    webservice-service-demo.rar

    【标题】"webservice-service-demo.rar" 是一个包含SpringBoot...通过深入研究这个示例项目,开发者将能够具备独立创建和部署基于SpringBoot的Webservice服务的能力,并且能够灵活地调整和扩展服务功能以满足实际需求。

    webservice 第一个小项目

    Java提供了多种库和框架来支持WebService的开发,如JAX-WS(Java API for XML Web Services)和Apache CXF。本项目可能侧重于JAX-WS,因为它更简单且易于上手。 1. **创建WebService**: - 定义服务接口:在Java中...

    WebService服务端和客户端

    此项目对于学习和理解WebService的生命周期、服务端和客户端之间的交互,以及如何在Java环境中实现和使用WebService具有很高的价值。通过实际操作,开发者可以更深入地了解SOAP通信的细节,提升跨平台应用集成的能力...

Global site tag (gtag.js) - Google Analytics