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

📄 mod_gsoap.c

📁 linux下简单对象应用协议的开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
{    assert(NULL != This);    SoapSharedLibraries_merge3(This->m_pLibraries, pParentConfig->m_pLibraries,                               pNewConfig->m_pLibraries);    This->m_Type = ct_both;}static voidgsoapConfiguration_init(gsoapConfiguration * This, apr_pool_t * p){    This->m_pLibraries =        (SoapSharedLibraries *) apr_pcalloc(p, sizeof(SoapSharedLibraries));    SoapSharedLibraries_init(This->m_pLibraries, p);    This->m_Type = ct_directory;}static gsoapConfiguration *gsoapConfiguration_create(apr_pool_t * p){    gsoapConfiguration *pConfig =        (gsoapConfiguration *) apr_pcalloc(p, sizeof(gsoapConfiguration));    gsoapConfiguration_init(pConfig, p);    return pConfig;}/* * forward declarations                                                      */static int gsoap_handler(request_rec * r);static int gsoap_init(apr_pool_t * p, apr_pool_t * ptemp, apr_pool_t * plog,                      server_rec * psrec);static void *gsoap_create_dir_config(apr_pool_t * p, char *dirspec);static void *gsoap_merge_dir_config(apr_pool_t * p, void *parent_conf,                                    void *newloc_conf);static void *gsoap_create_server_config(apr_pool_t * p, server_rec * s);static void *gsoap_merge_server_config(apr_pool_t * p, void *server1_conf,                                       void *server2_conf);static bool AddSharedLibrary(gsoapConfiguration * pConfig, const char *pszPath,                             const bool bIsSOAPLibrary);/* * * * * We prototyped the various syntax for command handlers (routines that      * * are called when the configuration parser detects a directive declared     * * by our module) earlier.  Now we actually declare a "real" routine that    * * will be invoked by the parser when our "real" directive is                * * encountered.                                                              *  * * If a command handler encounters a problem processing the directive, it    * * signals this fact by returning a non-NULL pointer to a string             * * describing the problem.                                                   *  * * The magic return value DECLINE_CMD is used to deal with directives        * * that might be declared by multiple modules.  If the command handler       * * returns NULL, the directive was processed; if it returns DECLINE_CMD,     * * the next module (if any) that declares the directive is given a chance    * * at it.  If it returns any other value, it's treated as the text of an     * * error message.                                                            *//** Command handler for the TAKE1 "SOAPLibrary" directive. * We remember the load path for the shared library that contains the SOAP server. */static const char *cmd_SoapLibrary(cmd_parms * cmd, void *mconfig, const char *pszPath){    gsoapConfiguration *pConfig = (gsoapConfiguration *) mconfig;    AddSharedLibrary(pConfig, pszPath, true);    return NULL;}/** Command handler for the TAKE1 "SOAPSupportLibrary" directive. * We remember the load path for a shared library that must additionally loaded. * This is a mechanism to load libraries that the SOAPLibrary depends on. * This type of libraries do not contain our soap server. */static const char *cmd_SupportLibrary(cmd_parms * cmd, void *mconfig, const char *pszPath){    gsoapConfiguration *pConfig = (gsoapConfiguration *) mconfig;    AddSharedLibrary(pConfig, pszPath, false);    return NULL;}typedef const char *(*command_function_interface) ();/** List of directives specific to our module. */static const command_rec gsoap_cmds[] = {    AP_INIT_TAKE1("SOAPLibrary",    ///< directive name                  (command_function_interface) cmd_SoapLibrary, ///< config action routine                  NULL,         ///< argument to include in call                  ACCESS_CONF,  ///< where available                  "SOAP shared Library that will be dynamically loaded. - 1 argument (path)"    ///< directive description        ),    AP_INIT_TAKE1("SupportLibrary", ///< directive name                  (command_function_interface) cmd_SupportLibrary,  ///< config action routine                  NULL,         ///< argument to include in call                  ACCESS_CONF,  ///< where available                  "additional library that must be dynamically loaded - 1 argument (path)"  ///< directive description        ),    {NULL}};/* * All of the routines have been declared now.  Here's the list of           * directives specific to our module, and information about where they       * may appear and how the command parser should pass them to us for          * processing.  Note that care must be taken to ensure that there are NO     * collisions of directive names between modules.                            *//* * Module definition for configuration.  If a particular callback is not * needed, replace its routine name below with the word NULL. * * The number in brackets indicates the order in which the routine is called * during request processing.  Note that not all routines are necessarily * called (such as if a resource doesn't have access restrictions). *//** List of callback routines and data structures that provide the hooks into our module. */static voidgsoap_hooks(apr_pool_t * p){    // I think this is the call to make to register a handler for method calls (GET PUT et. al.).    // We will ask to be last so that the comment has a higher tendency to    // go at the end.    ap_hook_handler(gsoap_handler, NULL, NULL, APR_HOOK_LAST);    //Register a handler for post config processing     ap_hook_post_config(gsoap_init, NULL, NULL, APR_HOOK_MIDDLE);}module AP_MODULE_DECLARE_DATA gsoap_module = {    STANDARD20_MODULE_STUFF,    gsoap_create_dir_config,    /* per-directory config creator */    gsoap_merge_dir_config,     /* dir config merger */    gsoap_create_server_config, /* server config creator */    gsoap_merge_server_config,  /* server config merger */    gsoap_cmds,                 /* command table */    gsoap_hooks,                /*hooks */};/** helper to write out the headers */static intListHeadersCallback(void *rec, const char *key, const char *value){    request_rec *r = (request_rec *) rec;    ap_rprintf(r, "%s: %s<br>", key, value);    return 1;}/** write out the headers of the request. */static voidListHeaders(request_rec * r){    apr_table_do(ListHeadersCallback, r, r->headers_in, NULL);}/** send the error message to the client browser */static voidSendErrorMessage(request_rec * r, const char *pszError){    ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "mod_gsoap: %s",                 pszError);    r->content_type = "text/html";    ap_rputs(DOCTYPE_HTML_3_2, r);    ap_rputs("<HTML>\n", r);    ap_rputs(" <HEAD>\n", r);    ap_rputs("  <TITLE>Apache Soap Handler\n", r);    ap_rputs("  </TITLE>\n", r);    ap_rputs(" </HEAD>\n", r);    ap_rputs(" <BODY>\n", r);    ap_rputs("  <H1>mod_gsoap Apache SOAP Server Error</H1>\n", r);    ap_rprintf(r,               "<p><strong>%s</strong><br>Please see the documentation at <a href=\"http://www.webware.at/SOAP\">WebWare</a> for details.</p>",               pszError);    ap_rputs("  <H2>Content headers of the request</H2>\n", r);    ListHeaders(r);    ap_rputs("</BODY></HTML>\n", r);}static intsend_header_to_gsoap(void *pvoid, const char *key, const char *value){    gsoapRequestConfiguration *pRqConf = NULL;    struct soap *psoap = (struct soap *)pvoid;    if(NULL != psoap)    {        pRqConf = getRequestConfiguration(psoap);    }    if(NULL == pRqConf)    {        return 0;    }    if(0 == strcasecmp(key, "SOAPAction") ||       0 == strcasecmp(key, "Content-Type") ||       0 == strcasecmp(key, "Status") || 0 == strcasecmp(key, "Content-Length"))    {        psoap->fparsehdr(psoap, key, value);    }    return 1;}/* * Callback functions for gsoap. We must parse the headers ourselves and  *  we must handle send/receive properly.   */static inthttp_post_header(struct soap *soap, const char *key, const char *value){    gsoapRequestConfiguration *pRqConf = getRequestConfiguration(soap);    request_rec *r = NULL == pRqConf ? NULL : pRqConf->r;    if(NULL != value)    {        if(0 == strcasecmp(key, "SOAPAction"))        {            apr_table_set(r->headers_out, key, value);        }        else if(0 == strcasecmp(key, "Content-Type"))        {            r->content_type = apr_pstrdup(r->pool, value);        }        else if(0 == strcasecmp(key, "Content-Length"))        {            ap_set_content_length(r, atoi(value));        }    }    return SOAP_OK;}/** gsoap function that requests the next piece of data from us */static size_tfrecv(struct soap *psoap, char *pBuf, apr_size_t len){    request_rec *r = NULL;    apr_size_t nRet = 0;    gsoapRequestConfiguration *pRqConf = getRequestConfiguration(psoap);    if(NULL != pRqConf)    {        r = pRqConf->r;        if(!pRqConf->headers_received)        {            apr_table_do(send_header_to_gsoap, psoap, r->headers_in, NULL);            pRqConf->headers_received = true;        }        if(r->remaining > 0)        {            nRet =                ap_get_client_block(r, pBuf,                                    len > r->remaining ? r->remaining : len);        }    }    return nRet;}static intfsend(struct soap *psoap, const char *pBuf, apr_size_t len){    int nRet = SOAP_OK;    gsoapRequestConfiguration *pRqConf = getRequestConfiguration(psoap);    if(NULL != pRqConf)    {        request_rec *r = pRqConf->r;        if(!pRqConf->headers_sent)        {            //          ap_send_http_header(r);            pRqConf->headers_sent = true;        }        nRet = ap_rwrite(pBuf, len, r) == len ? SOAP_OK : SOAP_FAULT;    }    else    {        nRet = SOAP_FAULT;    }    return nRet;}/** instead of real header parsing we skip that. */static inthttp_parse(struct soap *psoap){    return SOAP_OK;}/** make sure we go through soap_send_fault(), which calls fpoll */static intfpoll(struct soap *psoap){    return SOAP_OK;}/* * plugin functions  */static intmod_gsoap_plugin_copy(struct soap *soap, struct soap_plugin *dst,                      struct soap_plugin *src){    /*     * should this be a deep copy?      */    *dst = *src;    return SOAP_OK;}static voidmod_gsoap_delete(struct soap *soap, struct soap_plugin *p){}static intmod_gsoap_plugin(struct soap *soap, struct soap_plugin *p, void *arg){    p->id = mod_gsoap_id;    p->data = arg;    p->fcopy = mod_gsoap_plugin_copy;    p->fdelete = mod_gsoap_delete;    return SOAP_OK;}static voidset_callbacks(request_rec * r, gsoapRequestConfiguration * pRqConf,              struct soap *psoap){    gsoapConfiguration *pConfig = getConfiguration(r);    struct apache_soap_interface *pIntf = pConfig->m_pLibraries->m_pIntf;    pRqConf->r = r;    pRqConf->http_parse = psoap->fparse;    psoap->user = pRqConf;    psoap->frecv = frecv;    psoap->fsend = fsend;    psoap->fparse = http_parse;    psoap->fposthdr = http_post_header;    psoap->fpoll = fpoll;    if(NULL != pIntf->fsoap_init)    {        (*pIntf->fsoap_register_plugin_arg) (psoap, mod_gsoap_plugin,                                             (void *)pRqConf, r);    }    else    {        psoap->user = pRqConf;    }}/* *  * * Now we declare our content handlers, which are invoked when the server    * * encounters a document which our module is supposed to have a chance to    * * see.  (See mod_mime's SetHandler and AddHandler directives, and the       * * mod_info and mod_status examples, for more details.)                      *  * * Since content handlers are dumping data directly into the connexion       * * (using the r*() routines, such as rputs() and rprintf()) without          * * intervention by other parts of the server, they need to make              * * sure any accumulated HTTP headers are sent first.  This is done by        * * calling send_http_header().  Otherwise, no header will be sent at all,    * * and the output sent to the client will actually be HTTP-uncompliant.      *//** * SOAP content handler. * * @return the value that instructs the caller concerning what happened and what to do next. *  OK ("we did our thing") *  DECLINED ("this isn't something with which we want to get involved") *  HTTP_mumble ("an error status should be reported") */static intgsoap_handler(request_rec * r){    static const int nResponseBufferLen = IOBUF_CHUNK_SIZE;    const char *pszError = NULL;    struct soap *psoap = NULL;    struct apache_soap_interface *pIntf = NULL;    int nRet = 0;    char *pszResponse = NULL;    gsoapConfiguration *pConfig = getConfiguration(r);    gsoapRequestConfiguration *pRqConf = NULL;    /*     * only handle soap requests      */    if(!strstr(r->handler, "soap"))        return DECLINED;    /*     * only handle POST requests      */    if(r->method_number != M_POST && r->method_number != M_GET)        return DECLINED;    pszResponse = apr_pcalloc(r->pool, nResponseBufferLen);    assert(NULL != pConfig);    psoap = (struct soap *)apr_pcalloc(r->pool, sizeof(struct soap));    pRqConf = apr_pcalloc(r->pool, sizeof(gsoapRequestConfiguration));    pszError =        SoapSharedLibraries_loadAllLibraries(pConfig->m_pLibraries, r->pool, r);    pIntf = pConfig->m_pLibraries->m_pIntf;    ap_update_mtime(r, r->request_time);    ap_set_last_modified(r);    if(NULL != pszError)    {        static bool bFirstTime = true;        if(bFirstTime)        {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, pszError);            bFirstTime = false;        }    }    /*     * as a next step, we prepare a buffer that sends the request as first line to gsoap.      * Then the remaining data.      * We start returning bytes on frecv from this buffer, until it is empty.      * then it is not necessary to fiddle around with gsoap's request line parsing.     */    if(NULL == pszError)    {        pRqConf->r = r;        pRqConf->headers_sent = false;        pRqConf->headers_received = false;        pRqConf->m_pszAllHeaders = NULL;        pRqConf->m_nHeaderLength = strlen(r->the_request) + 2;        pRqConf->m_pszCurrentHeaderReadingPosition = NULL;

⌨️ 快捷键说明

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