You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sa...@apache.org on 2004/01/29 07:10:09 UTC
cvs commit: ws-axis/c/src/server/apache2 mod_axis2.c
sanjaya 2004/01/28 22:10:09
Modified: c/src/server/apache2 mod_axis2.c
Log:
changed mod_axis2.c to comply with changes to mod_axis.c
Revision Changes Path
1.4 +184 -26 ws-axis/c/src/server/apache2/mod_axis2.c
Index: mod_axis2.c
===================================================================
RCS file: /home/cvs/ws-axis/c/src/server/apache2/mod_axis2.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- mod_axis2.c 12 Jan 2004 12:20:53 -0000 1.3
+++ mod_axis2.c 29 Jan 2004 06:10:09 -0000 1.4
@@ -57,7 +57,7 @@
*
*
*
- * @author Sanjaya Singharage (sanjayas@jkcsworld.com)
+ * @author Sanjaya Singharage (sanjayas@opensource.lk, sanjayas@jkcsworld.com)
*
*/
#ifdef WIN32
@@ -75,25 +75,53 @@
#include <axis/common/Packet.h>
#include <malloc.h>
-#define AXIS_URI_EXTENSION "/axis/"
+#define AXIS_URI_EXTENSION "/axis"
/*
The apache 2.0 module for Axis. THIS IS NOT COMPLETED
*/
+/* Following is the character that should be used to separate the method name in the
+ * SOAPAction header value. Ex: "http://localhost:80/axis/Calculator#Add"
+ */
+#define SOAPACTION_METHODNAME_SEPARATOR "#"
+
extern int process_request(Ax_soapstream* str);
/*extern int process(soapstream *);*/
extern unsigned char chEBuf[1024];
-#define SIZEOFMODULEBUFFER 100
+#define SIZEOFMODULEBUFFER 4096
char g_buffer[SIZEOFMODULEBUFFER];
-/*Should dispatch the headers from within this method*/
-int send_transport_information(Ax_soapstream* hdr)
+/**
+ * This method adds the http header to the Ax_soapstream. These headers will be dispatched later
+ * before sending the http body
+ */
+static void AXISCALL set_transport_information(AXIS_TRANSPORT_INFORMATION_TYPE type, const char* value, Ax_soapstream* stream)
{
- ap_send_http_header((request_rec*)hdr->str.op_stream);
- return 0;
+ const char* key = NULL;
+ switch(type)
+ {
+ case SOAPACTION_HEADER: /* needed only in the client side ? */
+ break;
+ case SERVICE_URI: /* need to set ? */
+ break;
+ case OPERATION_NAME: /* need to set ? */
+ break;
+ case SOAP_MESSAGE_LENGTH:
+ key = "Content-Length"; /*this is apache module and transport is http so the key*/
+ break;
+ default:;
+ }
+ if (key)
+ {
+ ap_table_set(((request_rec*)stream->str.op_stream)->headers_out, key, value);
+ }
+#ifdef CHUNCKED_DATA_SUPPORTED
+ ap_send_http_header((request_rec*)hdr->str.op_stream);
+ /*should we remove the sent headers ? Sanjaya ?*/
+#endif
}
/*Call initialize_module() [of Packet.h] from within this method*/
@@ -102,10 +130,43 @@
initialize_module(1);
}
-int send_response_bytes(char* res, void* opstream)
+/**
+ * If this module is not handling chunked data transfer, it accumulates all buffers
+ * before sending them so that the http header "Content-Length" can be sent before
+ * sending the http body
+ */
+static AXIS_TRANSPORT_STATUS AXISCALL send_response_bytes(const char* buffer, const void* bufferid, const void* pStream)
{
- ap_rputs(res, (request_rec*)opstream);
- return 0;
+ const Ax_soapstream* stream = (Ax_soapstream*) pStream;
+#ifndef CHUNCKED_DATA_SUPPORTED
+ int index;
+ sendbuffers* pbuffers;
+#endif
+
+ if (!bufferid) /* temporary buffers should always sent immediately */
+ {
+ ap_rputs(buffer, (request_rec*)(stream->str.op_stream));
+ return TRANSPORT_FINISHED;
+ }
+
+#ifdef CHUNCKED_DATA_SUPPORTED
+ //Do we need to send any headers and length of this chunk ? Sanjaya ?
+ ap_rputs(buffer, (request_rec*)(stream->str.op_stream));
+ //Do we need to send any indication to mark the end of this chunk ? Sanjaya ?
+ return TRANSPORT_FINISHED;
+#else
+ pbuffers = (sendbuffers*)stream->reserved1;
+ for (index=0;index < NO_OF_SERIALIZE_BUFFERS; index++)
+ {
+ if(!pbuffers[index].buffer)
+ {
+ pbuffers[index].buffer = buffer;
+ pbuffers[index].bufferid = bufferid;
+ break;
+ }
+ }
+ return TRANSPORT_IN_PROGRESS;
+#endif
}
/*Call initialize_process() [of Packet.h] from within this method*/
@@ -119,15 +180,66 @@
* This function is called by the Axis Engine whenever it needs to get bytes from the
* transport layer.
*/
-int get_request_bytes(const char** req, int* retsize, const void* ipstream)
+static AXIS_TRANSPORT_STATUS AXISCALL get_request_bytes(const char** req, int* retsize, const Ax_soapstream* stream)
{
+ /*How can I detect an error when reading stream ? Sanjaya ?
+ In case of an error set buffer to null, size 0 and return TRANSPORT_FAILED*/
int len_read;
-// ap_hard_timeout("util_read", (request_rec*)ipstream);
- len_read = ap_get_client_block((request_rec*)ipstream, g_buffer, SIZEOFMODULEBUFFER);
-// ap_reset_timeout((request_rec*)ipstream);
+ /* ap_hard_timeout("util_read", (request_rec*)stream->str.ip_stream);*/
+ len_read = ap_get_client_block((request_rec*)stream->str.ip_stream, g_buffer, SIZEOFMODULEBUFFER);
+ /*ap_reset_timeout((request_rec*)stream->str.ip_stream);*/
*req = g_buffer;
*retsize = len_read;
- return 0;
+ if (len_read < SIZEOFMODULEBUFFER)
+ {
+ g_buffer[len_read] = '\0';
+ return TRANSPORT_FINISHED;
+ }
+ else
+ return TRANSPORT_IN_PROGRESS;
+}
+
+static void AXISCALL release_receive_buffer(const char* buffer, const Ax_soapstream* stream)
+{
+
+}
+
+static const char* AXISCALL get_transport_information(AXIS_TRANSPORT_INFORMATION_TYPE type, Ax_soapstream* stream)
+{
+ const char* ptemp;
+ switch(type)
+ {
+ case SOAPACTION_HEADER:
+ return get_property(stream, "SOAPAction");
+ case SERVICE_URI:
+ if (strstr(stream->so.http->uri_path, AXIS_URI_EXTENSION))
+ {
+ return strstr(stream->so.http->uri_path, AXIS_URI_EXTENSION) +
+ strlen(AXIS_URI_EXTENSION) + 1;
+ }
+ else
+ {
+ return stream->so.http->uri_path;
+ }
+ case OPERATION_NAME:
+ ptemp = get_property(stream, "SOAPAction");
+ if (ptemp)
+ {
+ if (strstr(ptemp, SOAPACTION_METHODNAME_SEPARATOR))
+ {
+ return strstr(ptemp, SOAPACTION_METHODNAME_SEPARATOR) +
+ strlen(SOAPACTION_METHODNAME_SEPARATOR);
+ }
+ else
+ {
+ return ptemp;
+ }
+ }
+ case SOAP_MESSAGE_LENGTH:
+ return get_property(stream, "Content-Length"); /*this is apache module and transport is http so the key*/
+ default:;
+ }
+ return NULL;
}
static int mod_axis_method_handler (request_rec *req_rec)
@@ -139,6 +251,13 @@
apr_table_entry_t* pHeaderTable;
Ax_header* pAx_Headers;
+#ifndef CHUNCKED_DATA_SUPPORTED
+ int contentLength=0;
+ int index;
+ sendbuffers* pbuffers;
+ char strtonum[8];
+#endif
+
if ((!req_rec->handler) || strcmp(req_rec->handler, "axis") != 0)
{
return DECLINED;
@@ -148,16 +267,25 @@
sstr->transport.pSendFunct = send_response_bytes;
sstr->transport.pGetFunct = get_request_bytes;
- sstr->transport.pSendTrtFunct = send_transport_information;
- sstr->transport.pGetTrtFunct = send_transport_information; /*isn't there a get transport information function for apache module ?*/
+ sstr->transport.pSetTrtFunct = set_transport_information;
+ sstr->transport.pGetTrtFunct = get_transport_information;
+ sstr->transport.pRelBufFunct = release_receive_buffer;
sstr->trtype = APTHTTP;
+ sstr->so.http = malloc(sizeof(Ax_stream_http));
/*req_rec is used as both input and output streams*/
sstr->str.ip_stream = req_rec;
sstr->str.op_stream = req_rec;
/*just add some sessionid*/
sstr->sessionid = "this is temporary session id";
+#ifdef CHUNCKED_DATA_SUPPORTED
+ sstr->reserved1 = NULL;
+ sstr->reserved2 = NULL;
+#else
+ sstr->reserved1 = calloc(NO_OF_SERIALIZE_BUFFERS, sizeof(sendbuffers));
+ sstr->reserved2 = NULL;
+#endif
/*set up the read policy from the client.*/
if ((rc = ap_setup_client_block(req_rec, REQUEST_CHUNKED_ERROR)) != OK)
@@ -167,21 +295,21 @@
/*the member, "path" of "parsed_uri" contains the uri of the*/
/*request (i.e "/abc/xyz" part of http://somehost/abc/xyz)*/
- sstr->so.http.uri_path = req_rec->parsed_uri.path;
+ sstr->so.http->uri_path = req_rec->parsed_uri.path;
/*ap_table_elts returns an array_header struct. The nelts element of that struct contains the number of*/
/*input header elements. Finally assigns that to the axis soap data structure. */
- sstr->so.http.ip_headercount = ap_table_elts(req_rec->headers_in)->nelts;
+ sstr->so.http->ip_headercount = ap_table_elts(req_rec->headers_in)->nelts;
- if (sstr->so.http.ip_headercount > 0)
+ if (sstr->so.http->ip_headercount > 0)
{
/*obtain the array_header from the headers_in table and assign it to the axis soap structure*/
arr = ap_table_elts(req_rec->headers_in);
pHeaderTable = arr->elts;
- sstr->so.http.ip_headers = malloc(sizeof(Ax_header)*sstr->so.http.ip_headercount);
- pAx_Headers = sstr->so.http.ip_headers;
- for (ix = 0; ix < sstr->so.http.ip_headercount; ix++)
+ sstr->so.http->ip_headers = malloc(sizeof(Ax_header)*sstr->so.http->ip_headercount);
+ pAx_Headers = sstr->so.http->ip_headers;
+ for (ix = 0; ix < sstr->so.http->ip_headercount; ix++)
{
(pAx_Headers+ix)->headername = (pHeaderTable+ix)->key;
(pAx_Headers+ix)->headervalue = (pHeaderTable+ix)->val;
@@ -191,17 +319,17 @@
switch (req_rec->method_number)
{
case M_GET:
- sstr->so.http.ip_method = AXIS_HTTP_GET;
+ sstr->so.http->ip_method = AXIS_HTTP_GET;
req_rec->content_type = "text/html";
break;
case M_POST:
- sstr->so.http.ip_method = AXIS_HTTP_POST;
+ sstr->so.http->ip_method = AXIS_HTTP_POST;
req_rec->content_type = "text/xml";
/*for SOAP 1.2 this this should be "application/soap+xml" */
/*but keep this for the moment*/
break;
default:
- sstr->so.http.ip_method = AXIS_HTTP_UNSUPPORTED;
+ sstr->so.http->ip_method = AXIS_HTTP_UNSUPPORTED;
}
/*tell the client that we are ready to receive content and check whether client will send content*/
@@ -214,6 +342,36 @@
return OK;
}
+#ifdef CHUNCKED_DATA_SUPPORTED
+ /*headers have already been sent. see set_transport_information
+ http body too have been sent
+ Do we need to send any indication to mark end of chuncked data ? Sanjaya ?*/
+#else
+ /*Calculate Content-Length and set header*/
+ pbuffers = (sendbuffers*)sstr->reserved1;
+ for (index=0;index < NO_OF_SERIALIZE_BUFFERS; index++)
+ {
+ if(!pbuffers[index].buffer) break;
+ contentLength += strlen(pbuffers[index].buffer);
+ }
+ if (contentLength != 0) /* do only if the http body is not empty.*/
+ {
+ sprintf(strtonum, "%d", contentLength);
+ set_transport_information(SOAP_MESSAGE_LENGTH, strtonum, sstr);
+ ap_send_http_header(req_rec);
+ /*Send all buffers*/
+ pbuffers = (sendbuffers*)sstr->reserved1;
+ for (index=0;index < NO_OF_SERIALIZE_BUFFERS; index++)
+ {
+ if(!pbuffers[index].buffer) break;
+ ap_rputs(pbuffers[index].buffer, req_rec);
+ /*Let Axis know that the buffer is no longer in use*/
+ axis_buffer_release(pbuffers[index].buffer, pbuffers[index].bufferid , sstr);
+ }
+ }
+ /*Free the array */
+ if (sstr->reserved1) free(sstr->reserved1);
+#endif
free(sstr);
/*free(arr);*/