Logo Search packages:      
Sourcecode: gsoap version File versions

static int gsoap_handler ( request_rec *  r  )  [static]

SOAP content handler.

Returns:
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")

Definition at line 704 of file mod_gsoap.c.

References gsoapRequestConfiguration_S::headers_received, gsoapRequestConfiguration_S::headers_sent, gsoapRequestConfiguration_S::http_parse, gsoapRequestConfiguration_S::m_nHeaderLength, gsoapRequestConfiguration_S::m_nOutBufCount, gsoapRequestConfiguration_S::m_nOutBufLength, SoapSharedLibraries_S::m_pIntf, gsoapConfiguration_S::m_pLibraries, gsoapRequestConfiguration_S::m_pOutBuf, gsoapRequestConfiguration_S::m_pszAllHeaders, gsoapRequestConfiguration_S::m_pszCurrentHeaderReadingPosition, gsoapRequestConfiguration_S::r, SendErrorMessage(), and SoapSharedLibraries_loadAllLibraries().

Referenced by gsoap_hooks().

{
    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;

    /* only handle soap requests */
    if (!strstr(r->handler, "soap"))
        return DECLINED;

    /* only handle POST requests */
    if (r->method_number != M_POST)
        return DECLINED;

    pszResponse = apr_pcalloc(r->pool, nResponseBufferLen);
    gsoapConfiguration *pConfig = getConfiguration(r);
    gsoapRequestConfiguration *pRqConf = NULL;
    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);

    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;
            }
    }

    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 = apr_pcalloc(r->pool, nResponseBufferLen);
            pRqConf->http_parse = NULL;
            pRqConf->m_pszAllHeaders = apr_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
     * case.
     *
     */

    /*
     * If we're only supposed to send header information (HEAD request), we're
     * already there.
     */
    if (r->header_only) {
        return OK;
    }
    if (NULL != pszError) {
      SendErrorMessage(r, pszError);
      return OK;
    }
    nRet = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
    if (OK != nRet) {
            SendErrorMessage(r, "Failed to start receiving POST buffer");
        return OK;
    }
    nRet = ap_should_client_block(r);
    if (0 == nRet) {
            SendErrorMessage(r, "No body received");
            return OK;
    }

    if (NULL != pszError) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, pszError);
            SendErrorMessage(r, pszError);
            return OK;
    }
    if (NULL != pIntf->fsoap_init) {
            (*pIntf->fsoap_init)(psoap);
            set_callbacks(r, pRqConf, psoap);
            if (NULL != pIntf->fsoap_serve) {
                  int nRet = (*pIntf->fsoap_serve)(psoap);
            } else {
                  SendErrorMessage(r, "no soap_serve entry point");
                  return OK;
            }
            if (NULL != pIntf->fsoap_destroy) {
                  pIntf->fsoap_destroy; // not an error in 2.1.10 any more.
            }
            if (NULL != pIntf->fsoap_end) {
                  pIntf->fsoap_end(psoap);
            } else {
                  SendErrorMessage(r, "no soap_end entry point");
            }
            if (NULL != pIntf->fsoap_done) {
                  pIntf->fsoap_done(psoap);
            } else {
                  SendErrorMessage(r, "no soap_done entry point");
            }
    } else {
            SendErrorMessage(r, "no soap_init entry point");
            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.
     */
    return OK;
}


Generated by  Doxygen 1.6.0   Back to index