📄 mod_gsoap.c
字号:
SoapSharedLibrary_create(This->m_pPool); SoapSharedLibrary_init(pNewLib, This->m_pPool, pLib); SoapSharedLibraries_addLibrary(This, pNewLib); } }}static voidSoapSharedLibraries_merge3(SoapSharedLibraries * This, SoapSharedLibraries * libraries1, SoapSharedLibraries * libraries2){ SoapSharedLibraries_merge(This, libraries1); SoapSharedLibraries_merge(This, libraries2);}static voidgsoapConfiguration_merge(gsoapConfiguration * This, gsoapConfiguration * pParentConfig, gsoapConfiguration * pNewConfig){ assert(NULL != This); SoapSharedLibraries_merge3(This->m_pLibraries, pParentConfig->m_pLibraries, pNewConfig->m_pLibraries); This->m_Type = ct_both;}static voidgsoapConfiguration_init(gsoapConfiguration * This, pool * p){ This->m_pLibraries = (SoapSharedLibraries *) ap_pcalloc(p, sizeof(SoapSharedLibraries)); SoapSharedLibraries_init(This->m_pLibraries, p); This->m_Type = ct_directory;}static gsoapConfiguration *gsoapConfiguration_create(pool * p){ gsoapConfiguration *pConfig = (gsoapConfiguration *) ap_pcalloc(p, sizeof(gsoapConfiguration)); gsoapConfiguration_init(pConfig, p); return pConfig;}/* * forward declarations */static int gsoap_handler(request_rec * r);static void gsoap_init(server_rec * s, pool * p);static void gsoap_child_init(server_rec * s, pool * p);static void gsoap_child_exit(server_rec * s, pool * p);static void *gsoap_create_dir_config(pool * p, char *dirspec);static void *gsoap_merge_dir_config(pool * p, void *parent_conf, void *newloc_conf);static void *gsoap_create_server_config(pool * p, server_rec * s);static void *gsoap_merge_server_config(pool * p, void *server1_conf, void *server2_conf);static int gsoap_post_read_request(request_rec * r);static int gsoap_translate_handler(request_rec * r);static int gsoap_check_user_id(request_rec * r);static int gsoap_auth_checker(request_rec * r);static int gsoap_access_checker(request_rec * r);static int gsoap_type_checker(request_rec * r);static int gsoap_fixer_upper(request_rec * r);static int gsoap_logger(request_rec * r);static int gsoap_header_parser(request_rec * r);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[] = { { "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 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){ ap_table_do(ListHeadersCallback, r, r->headers_in, NULL);}/** send the error message to the client browser */static voidSendErrorMessage(request_rec * r, const char *pszError){ /* * gsoapConfiguration *pConfig = getConfiguration(r); */ ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "mod_gsoap: %s", pszError); 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 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")) { 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_tfrecv(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 intfsend(struct soap *psoap, const char *pBuf, 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;}/* * plugin functions */static intmod_gsoap_plugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src){ *dst = *src;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -