📄 mod_gsoap.c
字号:
/* * should this be a deep copy? */ 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 = 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; 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 = 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, 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, r->server, pszError); bFirstTime = false; } } if(NULL == pszError) { if(M_POST != r->method_number && M_GET != r->method_number) { pszError = "Only POST and GET 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"); pRqConf->pIntf = pIntf; } /* * 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 * case. * * We also need to start a timer so the server can know if the connection * is broken. */ ap_soft_timeout("gsoap xml response", r); /* * If we're only supposed to send header information (HEAD request), we're * already there. */ if(r->header_only) { ap_send_http_header(r); ap_kill_timeout(r); return OK; } if(NULL != pszError) { SendErrorMessage(r, pszError); ap_kill_timeout(r); return OK; } nRet = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); if(OK != nRet) { SendErrorMessage(r, "Failed to start receiving POST buffer"); ap_kill_timeout(r); return OK; } nRet = ap_should_client_block(r); if(0 == nRet) { SendErrorMessage(r, "No body received"); ap_kill_timeout(r); return OK; } if(NULL != pszError) { ap_log_error(APLOG_MARK, APLOG_ERR, r->server, pszError); SendErrorMessage(r, pszError); ap_kill_timeout(r); return OK; } if(NULL != pIntf->fsoap_init) { (*pIntf->fsoap_init) (psoap, r); psoap->namespaces = pIntf->namespaces; set_callbacks(r, pRqConf, psoap); if(NULL != pIntf->fsoap_serve) { (*pIntf->fsoap_serve) (psoap, r); } else { SendErrorMessage(r, "no soap_serve entry point"); ap_kill_timeout(r); return OK; } if(NULL != pIntf->fsoap_destroy) { pIntf->fsoap_destroy(psoap, r); // not an error in 2.1.10 any more. } if(NULL != pIntf->fsoap_end) { pIntf->fsoap_end(psoap, r); } else { SendErrorMessage(r, "no soap_end entry point"); ap_kill_timeout(r); } if(NULL != pIntf->fsoap_done) { pIntf->fsoap_done(psoap, r); } else { SendErrorMessage(r, "no soap_done entry point"); ap_kill_timeout(r); } } else { SendErrorMessage(r, "no soap_init entry point"); ap_kill_timeout(r); return OK; } /* * We did what we wanted to do, so tell the rest of the server we * succeeded. We need not delete pszResponse, because it was allocated from the request pool. */ ap_kill_timeout(r); return OK;}/* * -------------------------------------------------------------------------- * * * * Now let's declare routines for each of the callback phase in order. * * (That's the order in which they're listed in the callback list, *not * * the order in which the server calls them! See the command_rec * * declaration). Note that these may be * * called for situations that don't relate primarily to our function - in * * other words, the fixup handler shouldn't assume that the request has * * to do with "gsoap" stuff. * * * * With the exception of the content handler, all of our routines will be * * called for each request, unless an earlier handler from another module * * aborted the sequence. * * * * Handlers that are declared as "int" can return the following: * * * * OK Handler accepted the request and did its thing with it. * * DECLINED Handler took no action. * * HTTP_mumble Handler looked at request and found it wanting. * * * * What the server does after calling a module handler depends upon the * * handler's return value. In all cases, if the handler returns * * DECLINED, the server will continue to the next module with an handler * * for the current phase. However, if the handler return a non-OK, * * non-DECLINED status, the server aborts the request right there. If * * the handler returns OK, the server's next action is phase-specific; * * see the individual handler comments below for details. * * * *-------------------------------------------------------------------------- *//* * This function is called during server initialisation. Any information * that needs to be recorded must be in static cells, since there's no * configuration record. * * There is no return value. */static voidgsoap_init(server_rec * s, pool * p){ // ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_gsoap initialized", NULL);}/* * This function is called during server initialisation when an heavy-weight * process (such as a child) is being initialised. As with the * module-initialisation function, any information that needs to be recorded * must be in static cells, since there's no configuration record. * * There is no return value. */static voidgsoap_child_init(server_rec * s, pool * p){}/* * This function is called when an heavy-weight process (such as a child) is * being run down or destroyed. As with the child-initialisation function, * any information that needs to be recorded must be in static cells, since * there's no configuration record. * * There is no return value. */static voidgsoap_child_exit(server_rec * s, pool * p){ //gsoapConfiguration::getLibraries()->clear();}/* * This function gets called to create a per-directory configuration * record. This will be called for the "default" server environment, and for * each directory for which the parser finds any of our directives applicable. * If a directory doesn't have any of our directives involved (i.e., they * aren't in the .htaccess file, or a <Location>, <Directory>, or related * block), this routine will *not* be called - the configuration for the * closest ancestor is used. * * The return value is a pointer to the created module-specific * structure. */static void *gsoap_create_dir_config(pool * p, char *dirspec){ gsoapConfiguration *pConfig = gsoapConfiguration_create(p); pConfig->m_Type = ct_directory; return pConfig;}/* * This function gets called to merge two per-directory configuration * records. This is typically done to cope with things like .htaccess files * or <Location> directives for directories that are beneath one for which a * configuration record was already created. The routine has the * responsibility of creating a new record and merging the contents of the * other two into it appropriately. If the module doesn't declare a merge * routine, the record for the closest ancestor location (that has one) is * used exclusively. * * The routine MUST NOT modify any of its arguments! * * The return value is a pointer to the created module-specific structure * containing the merged values. */static void *gsoap_merge_dir_config(pool * p, void *parent_conf, void *newloc_conf){ gsoapConfiguration *pMergedConfig = gsoapConfiguration_create(p); gsoapConfiguration *pParentConfig = (gsoapConfiguration *) parent_conf; gsoapConfiguration *pNewConfig = (gsoapConfiguration *) newloc_conf; gsoapConfiguration_merge(pMergedConfig, pParentConfig, pNewConfig); return pMergedConfig;}/* * This function gets called to create a per-server configuration
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -