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);*/