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

📄 mod_gsoap.c

📁 apache模组的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static int gsoap_header_parser(request_rec *r);static bool AddSharedLibrary(gsoapConfiguration *pConfig, const char *pszPath, const bool bIsSOAPLibrary);/*--------------------------------------------------------------------------*//*                                                                          *//* Data declarations.                                                       *//*                                                                          *//* Here are the static cells and structure declarations private to our      *//* module.                                                                  *//*                                                                          *//*--------------------------------------------------------------------------*///empty/*--------------------------------------------------------------------------*//* 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[] = {    {        "SOAPLibrary",          ///< directive name        (command_function_interface)cmd_SoapLibrary, ///< config action routine        NULL,                   ///< argument to include in call        ACCESS_CONF,            ///< where available        TAKE1,                  ///< arguments        "SOAP shared Library that will be dynamically loaded. - 1 argument (path)" ///< directive description    },    {        "SupportLibrary",       ///< directive name        (command_function_interface)cmd_SupportLibrary, ///< config action routine        NULL,                   ///< argument to include in call        ACCESS_CONF,            ///< where available        TAKE1,                  ///< arguments        "additional library that must be dynamically loaded - 1 argument (path)" ///< directive description    },    {NULL}};/*--------------------------------------------------------------------------*//*                                                                          *//* Now the list of content handlers available from this module.             *//*                                                                          *//*--------------------------------------------------------------------------*//*  * List of content handlers our module supplies.  Each handler is defined by * two parts: a name by which it can be referenced (such as by * {Add,Set}Handler), and the actual routine name.  The list is terminated by * a NULL block, since it can be of variable length. * * Note that content-handlers are invoked on a most-specific to least-specific * basis; that is, a handler that is declared for "text/plain" will be * invoked before one that was declared for "text / *".  Note also that * if a content-handler returns anything except DECLINED, no other * content-handlers will be called. */static const handler_rec gsoap_handlers[] ={    {"gsoap-handler", gsoap_handler},    {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. */module MODULE_VAR_EXPORT gsoap_module ={    STANDARD_MODULE_STUFF,    gsoap_init,               /* module initializer */    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_handlers,           /* [9] list of handlers */    gsoap_translate_handler,  /* [2] filename-to-URI translation */    gsoap_check_user_id,      /* [5] check/validate user_id */    gsoap_auth_checker,       /* [6] check user_id is valid *here* */    gsoap_access_checker,     /* [4] check access by host address */    gsoap_type_checker,       /* [7] MIME type checker/setter */    gsoap_fixer_upper,        /* [8] fixups */    gsoap_logger,             /* [10] logger */    gsoap_header_parser,      /* [3] header parser */    gsoap_child_init,         /* process initializer */    gsoap_child_exit,         /* process exit/cleanup */    gsoap_post_read_request   /* [1] post read_request handling */};/** helper to write out the headers */static int ListHeadersCallback(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 void ListHeaders(request_rec *r) {    ap_table_do(ListHeadersCallback, r, r->headers_in, NULL);}/** send the error message to the client browser */static void SendErrorMessage(request_rec *r, const char *pszError) {    gsoapConfiguration *pConfig = getConfiguration(r);    ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "mod_gsoap: %s", pszError, NULL);    r->content_type = "text/html";    ap_send_http_header(r);	    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 int send_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 int http_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")) {			ap_table_set(r->headers_out, key, value);		} else if (0 == strcasecmp(key, "Content-Type")) {			r->content_type = ap_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_t frecv(struct soap *psoap, char *pBuf, size_t len) {    request_rec *r = NULL;    int nRet = 0;    gsoapRequestConfiguration *pRqConf = getRequestConfiguration(psoap);    if (NULL != pRqConf) {		r = pRqConf->r;		if (!pRqConf->headers_received) {			ap_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 int fsend(struct soap *psoap, const char *pBuf, size_t len) {	int nWritten = 0;	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 int http_parse(struct soap *psoap) {    return SOAP_OK;}/* plugin functions */static int mod_gsoap_plugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src) {	*dst = *src;}static void mod_gsoap_delete(struct soap *soap, struct soap_plugin *p) {}static int mod_gsoap_plugin(struct soap *soap, struct soap_plugin *p, void *arg) {	p->id = GSOAP_ID;	p->data = arg;	p->fcopy = mod_gsoap_plugin_copy;	p->fdelete = mod_gsoap_delete;	return SOAP_OK;} static void set_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;    if (NULL != pIntf->fsoap_init) {		(*pIntf->fsoap_register_plugin_arg)(psoap, mod_gsoap_plugin, (void *)pRqConf);	} 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 int gsoap_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 nContentLength = 0;    int nRet = 0;    int nWritten = 0, nRead = 0;    char *pszResponse = ap_pcalloc(r->pool, nResponseBufferLen);    gsoapConfiguration *pConfig = getConfiguration(r);    gsoapRequestConfiguration *pRqConf = NULL;    assert(NULL != pConfig);    psoap = (struct soap *)ap_pcalloc(r->pool, sizeof(struct soap));    pRqConf = ap_pcalloc(r->pool, sizeof(gsoapRequestConfiguration));    pszError = SoapSharedLibraries_loadAllLibraries(pConfig->m_pLibraries, r->pool);    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, r->server, pszError);			bFirstTime = false;		}    }    if (NULL == pszError) {		if (0 != strcmp(r->method, "POST")) {			pszError = "Only POST allowed as request for SOAP!";		}    }    /* 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;		pRqConf->m_nOutBufCount = 0;		pRqConf->m_nOutBufLength = nResponseBufferLen;		pRqConf->m_pOutBuf = ap_pcalloc(r->pool, nResponseBufferLen);		pRqConf->http_parse = NULL;		pRqConf->m_pszAllHeaders = ap_pcalloc(r->pool, pRqConf->m_nHeaderLength + 1);		pRqConf->m_pszCurrentHeaderReadingPosition = pRqConf->m_pszAllHeaders;		strcpy(pRqConf->m_pszAllHeaders, r->the_request);		strcat(pRqConf->m_pszAllHeaders, "\r\n");    }     /*     * We're about to start sending content, so we need to force the HTTP     * headers to be sent at this point.  Otherwise, no headers will be sent     * at all.  We can set any we like first, of course.  **NOTE** Here's     * where you set the "Content-type" header, and you do so by putting it in     * r->content_type, *not* r->headers_out("Content-type").  If you don't     * set it, it will be filled in with the server's default type (typically     * "text/plain").  You *must* also ensure that r->content_type is lower

⌨️ 快捷键说明

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