use of single instance of axis2_http_client_t and axis2_env_t in the transport
module hangs at CLIENT_RECIEVE_HEADER call after 50 message transfers in win32
and about 102 transfers in linux
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: AXIS2C-522
URL: https://issues.apache.org/jira/browse/AXIS2C-522
Project: Axis2-C
Issue Type: Bug
Components: build system (Unix/Linux), build system (Windows)
Affects Versions: 0.95
Environment: Tried in both windows (xp pro) and linux (Suse)
Reporter: Prabhakar Raju
We are using axis2/c within a c++ class. We created static variables for
axis2_http_client_t and axis2_env_t in the class and trying to reuse the
instances for transmitting multiple messages. please note that respose also
reusing the same instance. This code was developed by my colleague and I'm only
modifying (denoted by pbkar in comments) it to use single client instance that
uses the same socket stream for multiple messages.
The files are APSAPISoap.cpp / .h
1) APSAPISoap.cpp
---------------------------------------------
///
///
/// @author lkrankur
///
///
#ifdef WIN32
#include "stdafx.h"
#endif
#include "APSAPISoap.h"
#include "APSConfigData.h"
#include "ClientLog.h"
#include <vector>
extern
string trim(string* s);
axis2_env* APSAPISoap::m_env = NULL; // instances defined here pbkar
axis2_http_client_t *APSAPISoap::m_http_client = NULL;
int APSAPISoap::m_count = 0;
//#ifdef MYDBG
//extern std::ofstream outt;
//#endif
typedef struct axis2_http_simple_response_impl
{
axis2_http_simple_response_t simple_response;
axis2_http_status_line_t *status_line;
axis2_array_list_t *header_group;
axis2_stream_t *stream;
}
axis2_http_simple_response_impl_t;
#define AXIS2_INTF_TO_IMPL2(simple_response) \
((axis2_http_simple_response_impl_t *)(simple_response))
axis2_ssize_t AXIS2_CALL
axis2_http_simple_response_get_body_bytes1
(
axis2_http_simple_response_t* simple_response,
const axis2_env_t* env,
axis2_char_t **buffer,
long bsize
)
{
if ( 1 > bsize )
return 0;
axis2_http_simple_response_impl_t* response_impl = NULL;
long return_size = 0;
try
{
response_impl = AXIS2_INTF_TO_IMPL2(simple_response);
if ( NULL == response_impl->stream )
return return_size;
*buffer =
(char *)AXIS2_MALLOC
(
env->allocator,
sizeof(char) * (bsize + 1)
);
#ifdef MYDBG
int k = 1;
#endif
for ( int ret = 1 ; bsize != return_size && 0 < ret; )
{
return_size +=
ret =
AXIS2_STREAM_READ
(
response_impl->stream,
env,
*buffer + return_size,
bsize - return_size
);
if ( bsize == return_size || 0 == ret )
{
char* p = *buffer + bsize;
p[0] = 0;
break;
}
else
{
#ifdef MYDBG
// cout << Log::getCurrentDateTime() <<
"\tprocessID = " << getpid() << "\ttry in receive = " << k << ", read bytes = "
<< return_size2 << endl;
// outt << Log::getCurrentDateTime() <<
"\tprocessID = " << getpid() << "\ttry in receive = " << k << ", read bytes =
" << return_size2 << endl;
// ++k;
#endif
;
}
}
}
catch ( ... )
{
return_size = 0;
if ( NULL != *buffer )
{
AXIS2_FREE(env->allocator, *buffer);
*buffer = NULL;
}
}
return return_size;
}
///
/// AXIS2_HTTP_CLIENT_SEND Axis2c 0.94. 095 has memory leak
/// method replaces axis2_http_client_send method (in http_client.c) modified
to fix
///
axis2_status_t AXIS2_CALL
axis2_http_client_send1
(
axis2_http_client_t* client,
const axis2_env_t* env,
axis2_http_simple_request_t* request
)
{
static axis2_http_client_impl_t* client_impl = NULL;
char* wire_format = NULL;
axis2_array_list_t* headers = NULL;
char* str_body = NULL;
char* str_request_line = NULL;
int body_size = 0;
int written = 0;
axis2_status_t status = AXIS2_FAILURE;
axis2_bool_t chunking_enabled = AXIS2_FALSE;
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
// this code is an attempt to reset the client_impl since it was hanging after
50 calls pbkar
++APSAPISoap::m_count;
if (APSAPISoap::m_count >= 49){
client_impl->request_sent = AXIS2_TRUE;
APSAPISoap::m_count=0;
if ( NULL != client_impl->data_stream )
{
try
{
AXIS2_STREAM_FREE(client_impl->data_stream, env);
}
catch ( ... )
{
}
client_impl->data_stream = NULL;
}
axis2_network_handler_close_socket(env, client_impl->sockfd);
AXIS2_HTTP_SIMPLE_RESPONSE_FREE(client_impl->response, env);
//AXIS2_HTTP_CLIENT_FREE( &(client_impl->http_client), env);
//client_impl->http_client.ops->free(
&(client_impl->http_client), env);
//AXIS2_URL_FREE(client_impl->url, env);
client_impl = NULL;
}
// end reset client_impl
if(client_impl == NULL) { // code to bypass socket creation once client
instance created created, pbkar
client_impl = AXIS2_INTF_TO_IMPL(client);
if ( NULL == client_impl->url )
{
if ( NULL != env->error )
AXIS2_ERROR_SET
(
env->error,
AXIS2_ERROR_NULL_URL,
(axis2_status_codes_t)AXIS2_FAILURE
);
return AXIS2_FAILURE;
}
if ( AXIS2_TRUE == client_impl->proxy_enabled )
{
if ( NULL == client_impl->proxy_host || 0 >= client_impl->proxy_port )
{
return AXIS2_FAILURE;
}
client_impl->sockfd =
axis2_network_handler_open_socket
(
env,
client_impl->proxy_host,
client_impl->proxy_port
);
}
else
{
client_impl->sockfd =
axis2_network_handler_open_socket
(
env,
AXIS2_URL_GET_SERVER(client_impl->url, env),
AXIS2_URL_GET_PORT(client_impl->url, env)
);
}
if ( 0 > client_impl->sockfd )
{
if ( NULL != env->error )
AXIS2_ERROR_SET
(
env->error,
AXIS2_ERROR_SOCKET_ERROR,
(axis2_status_codes_t)AXIS2_FAILURE
);
return AXIS2_FAILURE;
}
/* ONLY FOR TESTING
* client_impl->data_stream = axis2_stream_create_file(env,
* stdout);
*/
if ( 0 < client_impl->timeout )
{
axis2_network_handler_set_sock_option
(
env,
client_impl->sockfd,
SO_RCVTIMEO,
client_impl->timeout
);
axis2_network_handler_set_sock_option
(
env,
client_impl->sockfd,
SO_SNDTIMEO,
client_impl->timeout
);
}
if ( 0 == AXIS2_STRCASECMP
(
AXIS2_URL_GET_PROTOCOL(client_impl->url, env),
"HTTPS"
)
)
{
#ifdef AXIS2_SSL_ENABLED
if ( AXIS2_TRUE == client_impl->proxy_enabled )
{
if ( AXIS2_SUCCESS != axis2_http_client_connect_ssl_host(client,
env,
AXIS2_URL_GET_SERVER(client_impl->url, env),
AXIS2_URL_GET_PORT(client_impl->url, env))
)
{
return AXIS2_FAILURE;
}
}
client_impl->data_stream =
axis2_stream_create_ssl
(
env,
client_impl->sockfd
);
#else
if ( NULL != env->error )
AXIS2_ERROR_SET
(
env->error,
AXIS2_ERROR_INVALID_TRANSPORT_PROTOCOL,
(axis2_status_codes_t)AXIS2_FAILURE
);
return AXIS2_FAILURE;
#endif
}
else
{
client_impl->data_stream =
axis2_stream_create_socket
( env,
client_impl->sockfd
);
}
if ( NULL == client_impl->data_stream )
{
axis2_network_handler_close_socket(env, client_impl->sockfd);
return AXIS2_FAILURE;
}
} // end code to bypass pbkar
headers = AXIS2_HTTP_SIMPLE_REQUEST_GET_HEADERS(request, env);
string s;
if ( headers )
{
int header_count = AXIS2_ARRAY_LIST_SIZE(headers, env);
char ee[2048] = {0};
for ( int i = 0; i < header_count; ++i )
{
axis2_char_t* header_ext_form = NULL;
axis2_http_header_t*
tmp_header =
(axis2_http_header_t
*)AXIS2_ARRAY_LIST_GET(headers, env, i);
if ( NULL == tmp_header )
{
continue;
}
/* check whether we have transfer encoding and then see whether the
* value is "chunked" */
if ( 0 == AXIS2_STRCMP(AXIS2_HTTP_HEADER_GET_NAME(tmp_header, env),
AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && 0 ==
AXIS2_STRCMP(AXIS2_HTTP_HEADER_GET_VALUE(tmp_header, env),
AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)
)
{
chunking_enabled = AXIS2_TRUE;
}
sprintf
(
ee,
"%s: %s%s",
tmp_header->ops->get_name(tmp_header, env),
tmp_header->ops->get_value(tmp_header, env),
AXIS2_HTTP_CRLF
);
s += ee;
}
}
if ( AXIS2_FALSE == client_impl->proxy_enabled )
{
str_request_line =
AXIS2_HTTP_REQUEST_LINE_TO_STRING
(
AXIS2_HTTP_SIMPLE_REQUEST_GET_REQUEST_LINE(request, env),
env
);
}
else
{
/* we need the request line in the format
* POST http://host:port/path HTTP/1.x if we have enabled proxies
*/
axis2_char_t* host_port_str = NULL;
axis2_char_t* server = AXIS2_URL_GET_SERVER(client_impl->url,
env);
axis2_http_request_line_t* request_line =
AXIS2_HTTP_SIMPLE_REQUEST_GET_REQUEST_LINE(request, env);
axis2_char_t* path =
AXIS2_HTTP_REQUEST_LINE_GET_URI(request_line, env);
/* length = len(server) + len(:port) + len("http://") + len(path) + 1*/
host_port_str =
(axis2_char_t*)AXIS2_MALLOC
(
env->allocator,
AXIS2_STRLEN(server) +
AXIS2_STRLEN(path) +
20 *
sizeof(axis2_char_t)
);
if ( NULL == host_port_str )
{
if ( NULL != env->error )
AXIS2_ERROR_SET
(
env->error,
AXIS2_ERROR_NO_MEMORY,
(axis2_status_codes_t)AXIS2_FAILURE
);
return AXIS2_FAILURE;
}
sprintf
(
host_port_str,
"http://%s:%d%s",
server,
AXIS2_URL_GET_PORT(client_impl->url, env),
path
);
str_request_line =
(char*)AXIS2_MALLOC
(
env->allocator,
AXIS2_STRLEN(host_port_str) +
20 * sizeof(axis2_char_t)
);
sprintf
(
str_request_line, "%s %s %s\r\n",
AXIS2_HTTP_REQUEST_LINE_GET_METHOD(request_line, env),
host_port_str,
AXIS2_HTTP_REQUEST_LINE_GET_HTTP_VERSION(request_line,
env)
);
AXIS2_FREE(env->allocator, host_port_str);
host_port_str = NULL;
}
s = string(str_request_line) + s;
AXIS2_FREE(env->allocator, str_request_line);
str_request_line = NULL;
written = AXIS2_STREAM_WRITE(client_impl->data_stream, env, s.c_str(),
s.size());
cout << "after write" << endl;
AXIS2_FREE(env->allocator, wire_format);
wire_format = NULL;
written = AXIS2_STREAM_WRITE(client_impl->data_stream, env,
AXIS2_HTTP_CRLF, 2);
cout << "after write crlf" << endl;
body_size = AXIS2_HTTP_SIMPLE_REQUEST_GET_BODY_BYTES(request, env,
&str_body);
if ( 0 < body_size && str_body )
{
if (AXIS2_FALSE == chunking_enabled)
{
status = AXIS2_SUCCESS;
while ( written < body_size )
{
written =
AXIS2_STREAM_WRITE
(
client_impl->data_stream,
env,
str_body,
body_size
);
if ( -1 == written )
{
status = AXIS2_FAILURE;
break;
}
}
}
else
{
axis2_http_chunked_stream_t* chunked_stream = NULL;
chunked_stream =
axis2_http_chunked_stream_create(env,
client_impl->data_stream);
status = AXIS2_SUCCESS;
if ( NULL == chunked_stream )
{
if ( NULL != env->log )
AXIS2_LOG_ERROR
(
env->log,
AXIS2_LOG_SI,
"Creation of chunked stream
failed"
);
return AXIS2_FAILURE;
}
while ( written < body_size )
{
written =
AXIS2_HTTP_CHUNKED_STREAM_WRITE
(
chunked_stream,
env,
str_body,
body_size
);
if ( -1 == written )
{
status = AXIS2_FAILURE;
break;
}
}
if ( AXIS2_SUCCESS == status )
{
AXIS2_HTTP_CHUNKED_STREAM_WRITE_LAST_CHUNK(chunked_stream, env);
}
AXIS2_HTTP_CHUNKED_STREAM_FREE(chunked_stream, env);
}
}
client_impl->request_sent = AXIS2_TRUE;
if ( NULL != str_body )
{
AXIS2_FREE(env->allocator, str_body);
str_body = NULL;
}
cout << "after send1" << endl;
return status;
}
/// <summary>
/// constructor
/// <param name="logSoap">, [in], type = char*, path to the axis2 log
file</param>
/// </summary>
APSAPISoap::APSAPISoap()
:m_buffer(NULL), m_buffer2(NULL), m_body(NULL)
{
m_allocator = axis2_allocator_init (NULL);
//m_env = axis2_env_create(m_allocator);
axis2_allocator_t* allocator = axis2_allocator_init (NULL);
axis2_error_t* error = axis2_error_create(allocator);
m_env = axis2_env_create_with_error(allocator, error);
}
/// <summary>
/// method creates unsigned envelope
/// <param name="localName">, [in], type = axis2_char_t*, local name for
the request element</param>
/// <param name="localNamespace">, [in], type = axis2_char_t*, namespace
for the request element, could be NULL</param>
/// <param name="pRequest">, [in], type = RequestTO*, XACML request, could
be NULL</param>
/// <param name="applicationName">, [in], type = axis2_char_t*, application
name, could be NULL</param>
/// </summary>
bool APSAPISoap::getSoapEnvelope
(
axis2_char_t* localName,
axis2_char_t* localNamespace,
RequestTO* pRequest,
axis2_char_t* applicationName
)
{
bool fOk = false;
m_buffer = m_buffer2 = NULL;
axiom_soap_body* body = NULL;
axiom_soap_envelope* envelope = NULL;
axiom_node_t* request_om_node = NULL;
axiom_node_t* envelope_om_node = NULL;
try
{
axiom_namespace_t* ns[] = {
axiom_namespace_create (m_env,
APS::XML_NAMESPACE::SOAP_ENCODING,
"soapenc"),
axiom_namespace_create (m_env,
APS::XML_NAMESPACE::SCHEMA,
"xsd"),
axiom_namespace_create (m_env,
APS::XML_NAMESPACE::SCHEMA_INSTANCE,
"xsi"),
};
envelope =
axiom_soap_envelope_create_with_soap_version_prefix(m_env, 1, "");
envelope_om_node = AXIOM_SOAP_ENVELOPE_GET_BASE_NODE(envelope,
m_env);
axiom_element_t* envelope_om_ele =
(axiom_element_t*)AXIOM_NODE_GET_DATA_ELEMENT(envelope_om_node, m_env);
for ( int i = 0; i < 3; ++i )
AXIOM_ELEMENT_DECLARE_NAMESPACE(envelope_om_ele, m_env,
envelope_om_node, ns[i]);
body = axiom_soap_body_create_with_parent(m_env, envelope);
request_om_node =
(
( applicationName ) ?
createRequest2(localName,
applicationName)
:
createRequest(localName,
localNamespace, pRequest)
);
m_buffer2 = AXIOM_NODE_TO_STRING(request_om_node, m_env);
axis2_status_t status =
AXIOM_SOAP_BODY_ADD_CHILD
(
body,
m_env,
request_om_node
);
m_buffer = AXIOM_NODE_TO_STRING(envelope_om_node, m_env);
fOk = true;
AXIOM_SOAP_ENVELOPE_FREE(envelope, m_env);
envelope = NULL;
}
catch ( ... )
{
// to do logging?
try
{
if ( !fOk )
freeBuffers();
//if ( NULL != body )
// AXIOM_SOAP_BODY_FREE(body, m_env);
//if ( NULL != request_om_node )
// AXIOM_SOAP_BODY_FREE(request_om_node, m_env);
//if ( NULL != envelope_om_node )
// AXIOM_NODE_FREE_TREE(envelope_om_node, m_env);
if ( NULL != envelope )
AXIOM_SOAP_ENVELOPE_FREE(envelope, m_env);
}
catch ( ... )
{
// to do logging?
}
}
return fOk;
}
/// <summary>
/// method creates XACML Request element (evaluation policy) as OM node
/// <param name="localName">, [in], type = axis2_char_t*, localName of
Request element</param>
/// <param name="localNamespace">, [in], type = axis2_char_t*, namespace of
localName of Request element</param>
/// <param name="pRequest">, [in], type = RequestTO*, pointer to RequestTO
object </param>
/// </summary>
axiom_node_t* APSAPISoap::createRequest
(
axis2_char_t* localName,
axis2_char_t* localNamespace,
RequestTO* pRequest
)
{
axiom_node_t* request_om_node = NULL;
axiom_node_t* resource_om_node = NULL;
axiom_element_t* resource_om_ele = NULL;
axiom_node_t* action_om_node = NULL;
axiom_element_t* action_om_ele = NULL;
axiom_element_t* request_om_ele =
axiom_element_create
(
m_env,
NULL,
localName,
// to comfort signature validation have to create request without namespace
/* axiom_namespace_create
(
m_env,
localNamespace,
""
)*/
NULL
,
&request_om_node
);
SubjectTO tmpSTO = pRequest->getSubject();
createSubject
(
request_om_node,
&tmpSTO
);
createResource
(
request_om_node,
(axis2_char_t*)pRequest->getResource().c_str(),
(axis2_char_t*)pRequest->getScope().c_str()
);
createAction
(
request_om_node,
(axis2_char_t*)pRequest->getAction().c_str()
);
return request_om_node;
}
/// <summary>
/// method creates XACML Request element (RoleRequest, ResourceRequest,
DCRequest) as OM node
/// <param name="localName">, [in], type = aps_arribute_t*, localName of
Request element</param>
/// <param name="appname">, [in], type = axis2_char_t*, name of
application</param>
/// </summary>
axiom_node_t* APSAPISoap::createRequest2
(
axis2_char_t* localName,
axis2_char_t* appname
)
{
axiom_node_t* request_om_node = NULL;
axiom_node_t* add0_om_node = NULL;
axiom_element_t* request_om_ele =
axiom_element_create
(
m_env,
NULL,
localName,
NULL,
&request_om_node
);
axiom_element_t* add0_om_ele =
axiom_element_create
(
m_env,
request_om_node,
"Application",
NULL,
&add0_om_node
);
axiom_attribute_t* attr0 = axiom_attribute_create(m_env, "Name",
appname, NULL);
AXIOM_ELEMENT_SET_NAMESPACE(add0_om_ele, m_env, NULL, add0_om_node);
AXIOM_ELEMENT_ADD_ATTRIBUTE(add0_om_ele, m_env, attr0, add0_om_node);
return request_om_node;
}
/// <summary>
/// method creates OM node for Subject element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="pSubject">, [in], type = SubjectTO*, pointer to SubjectTO
object</param>
/// </summary>
void APSAPISoap::createSubject(axiom_node_t* parent, SubjectTO* pSubject)
{
axiom_node_t* om_node = NULL;
axiom_element_t* om_ele =
axiom_element_create
(
m_env,
parent,
"Subject",
NULL,
&om_node
);
AXIOM_ELEMENT_ADD_ATTRIBUTE
(
om_ele,
m_env,
axiom_attribute_create
(
m_env,
"SubjectCategory",
APS::XACML::SUBJECT_CATEGORY,
NULL
),
om_node
);
vector<aps_arribute_t*> attributes;
vector<AttributeTO> subjectAtts = pSubject->getAttributes();
vector<AttributeTO>::iterator attributeTO;
for
(
attributeTO = subjectAtts.begin();
attributeTO != subjectAtts.end();
attributeTO++
)
{
aps_arribute_t* t = new aps_arribute_t
(
(axis2_char_t*)attributeTO->getID().c_str(),
(axis2_char_t*)attributeTO->getType().c_str(),
(axis2_char_t*)attributeTO->getValue().c_str(),
m_env
);
attributes.push_back(t);
}
addAttributes(attributes, om_node);
clearAttributes(attributes);
}
/// <summary>
/// method creates OM node for Resource element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="resource">, [in], type = axis2_char_t*, resource
name</param>
/// <param name="scope">, [in], type = axis2_char_t*, scope of
resource</param>
/// </summary>
void APSAPISoap::createResource
(
axiom_node_t* parent,
axis2_char_t* resource,
axis2_char_t* scope)
{
axiom_node_t* om_node = NULL;
axiom_element_t* resource_om_ele =
axiom_element_create
(
m_env,
parent,
"Resource",
NULL,
&om_node
);
vector<aps_arribute_t*> attributes;
aps_arribute_t* t = new
aps_arribute_t((axis2_char_t*)APS::XACML::RESOURCE_ID,
(axis2_char_t*)APS::XACML::RESOURCE_DEFAULT_TYPE, resource, m_env);
attributes.push_back(t);
t = new aps_arribute_t((axis2_char_t*)APS::XACML::RESOURCE_SCOPE_ID,
scope, m_env);
attributes.push_back(t);
addAttributes(attributes, om_node);
clearAttributes(attributes);
}
/// <summary>
/// method creates OM node for Action element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="action">, [in], type = axis2_char_t*, action name</param>
/// </summary>
void APSAPISoap::createAction(axiom_node_t* parent, axis2_char_t* action)
{
axiom_node_t* om_node = NULL;
axiom_element_t* om_ele =
axiom_element_create
(
m_env,
parent,
"Action",
NULL,
&om_node
);
vector<aps_arribute_t*> attributes;
aps_arribute_t* t = new
aps_arribute_t((axis2_char_t*)APS::XACML::ACTION_ID, action, m_env);
attributes.push_back(t);
addAttributes(attributes, om_node);
clearAttributes(attributes);
}
/// <summary>
/// method adds XACML attribute as OM element to a parent OM node
/// <param name="attribute">, [in], type = aps_arribute_t*, attribute info
</param>
/// <param name="parent">, [in], type = axiom_node_t*, parent OM node
</param>
/// </summary>
void APSAPISoap::addAttribute
(
aps_arribute_t* attribute,
axiom_node_t* parent
)
{
axiom_node_t* add0_om_node = NULL;
axiom_node_t* add1_om_node = NULL;
axiom_element_t* add0_om_ele =
axiom_element_create(m_env, parent, "Attribute", NULL,
&add0_om_node);
axiom_element_t*
add1_om_ele = axiom_element_create(m_env, add0_om_node,
"AttributeValue", NULL, &add1_om_node);
axiom_attribute_t* attr0 = axiom_attribute_create(m_env, "AttributeId",
attribute->attributeId, NULL);
axiom_attribute_t* attr1 = axiom_attribute_create(m_env, "DataType",
attribute->dataType, NULL);
AXIOM_ELEMENT_SET_NAMESPACE(add0_om_ele, m_env, NULL, add0_om_node);
AXIOM_ELEMENT_ADD_ATTRIBUTE(add0_om_ele, m_env, attr0, add0_om_node);
AXIOM_ELEMENT_ADD_ATTRIBUTE(add0_om_ele, m_env, attr1, add0_om_node);
AXIOM_ELEMENT_SET_TEXT(add1_om_ele, m_env, attribute->dataValue,
add1_om_node);
}
/// <summary>
/// method adds XACML attributes as OM elements to parent node
/// <param name="attributes">, [in], type = vector<aps_arribute_t*>,
collection of attribute info </param>
/// <param name="parent">, [in], type = axiom_node_t*, parent OM node
</param>
/// </summary>
void APSAPISoap::addAttributes
(
vector<aps_arribute_t*> attributes,
axiom_node_t* parent
)
{
vector<aps_arribute_t*>::iterator iter;
for ( iter = attributes.begin(); iter != attributes.end(); iter++ )
{
addAttribute(*iter, parent);
}
}
/// <summary>
/// method clears collections of aps_arribute_t*
/// <param name="attributes">, [in], type = vector<aps_arribute_t*>&
</param>
/// </summary>
void APSAPISoap::clearAttributes(vector<aps_arribute_t*>& attributes)
{
try
{
while ( 0 < attributes.size() )
{
aps_arribute_t* t = attributes[attributes.size()-1];
attributes.pop_back();
m_allocator->free_fn(m_allocator, t->attributeId);
m_allocator->free_fn(m_allocator, t->dataType);
m_allocator->free_fn(m_allocator, t->dataValue);
delete t;
}
}
catch ( ... )
{
// to do logging?
}
attributes.clear();
}
/// <summary>
/// method logs send/receive SOAP over HTTP
/// <param name="attempt">, [in], type = integer, attempt tried</param>
/// <param name=buffer>, [in], type = integer, number of attempts
configured</param>
/// <param name="method">, [in], type = char*, message that sent</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <param name="status">, [in], type = integer, HTTP code returned (if
any)</param>
/// </summary>
void APSAPISoap::logSoap
(
int attempt,
int retry,
char* buffer,
SOAPResponseMessage* pResponseMsg,
int status
)
{
int level = APSConfigData::getInstance().getLogLevel();
bool fOk = (200 == status || 500 == status);
if ( APS::LOG_ERROR <= level )
{
char msg[512] = {0};
char* f[] = {"st", "nd", "rd", "th"};
string warning;
sprintf
(
msg,
"%d%s attempt (from %d) to retry sending SOAP message
%s. ",
attempt+1, f[( attempt < 3 ) ? attempt : 3],
retry,
fOk ? "succeed" : "failed"
);
warning += msg;
if ( ( 200 != status ) &&
(pResponseMsg->getStatusTransportDescription().size()
|| pResponseMsg->getStatusHTTPDescription().size() )
)
{
warning += string( fOk ? " Warning" : " Error") +
string(" description: ") +
pResponseMsg->getStatusTransportDescription() +
string(
pResponseMsg->getStatusTransportDescription().size() ? ". " : "" ) +
pResponseMsg->getStatusHTTPDescription();
warning = trim(&warning);
for ( int i = 1; i < 3; ++i )
if ( 10 == warning.c_str()[warning.size()-1] ||
13 == warning.c_str()[warning.size()-1] )
warning.erase(warning.size()-1, 1);
warning = trim(&warning);
if ( '.' != warning.c_str()[warning.size()-1] && '.' !=
warning.c_str()[warning.size()-2] )
warning += ". ";
}
else
warning += "\n";
if ( APS::LOG_INFO <= level && NULL != buffer && 500 == status )
{
warning += "SOAP fault:\r";
warning += buffer;
warning += "\n";
}
if ( warning.size() )
{
int msgtype = fOk ? ( 200 == status ? APS::LOG_INFO :
APS::LOG_WARNING )
: APS::LOG_ERROR;
if ( msgtype <= level )
ClientLog::getInstance().saveMsg(warning,
msgtype);
}
}
}
/// <summary>
/// sends Request SOAP message over HTTP
/// <param name="envlopebuffer">, [in], type = char*, buffer - keeps signed
SOAP envelope</param>
/// <param name="url">, [in], type = axis2_char_t*, path to the service
fotmat (pdp location)/(service)</param>
/// <param name="method">, [in], type = axis2_char_t*, service method -
soap action</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <param name="int">, [in], type = int, number of attempts when
failure</param>
/// <param name="int">, [in], type = int, interval in min? between attempts
when failure</param>
/// </summary>
bool APSAPISoap::sendSoapEnvelope
(
char* envlopebuffer,
axis2_char_t* url_str,
axis2_char_t* method,
SOAPResponseMessage* pResponseMsg,
int retry,
// default = 1
int timeout
// default = 10
)
{
int tt = strlen(url_str) + strlen(method);
if ( 0 > retry && 3 < retry )
retry = 1;
if ( 0 > timeout && 10 < timeout )
timeout = 10;
bool fOk = false;
axis2_url_t* url = NULL;
//axis2_http_client_t* http_client = NULL;
axis2_http_simple_request_t* simple_request = NULL;
m_body = NULL;
int status = AXIS2_FAILURE; // AXIS2_SUCCESS;
if ( NULL != envlopebuffer && strlen(envlopebuffer) )
{
#ifdef MYDBG
// FILE *fp = fopen("C:\\Myfiles\\temp\\mysigned.xml","w");
// fprintf(fp,"%s", envlopebuffer);
// fclose(fp);
// cout << "SOAP envelope with signed request sent to
C:\\Myfiles\\temp\\mysigned.xml" << endl;
//getchar();
#endif
char content_lenght[17] = {0};
sprintf((char*)&content_lenght, "%d", strlen(envlopebuffer));
axis2_http_header_t* header_host = NULL;
axis2_http_header_t* header_soap_action = NULL;
axis2_http_header_t* header_content_type = NULL;
axis2_http_header_t* header_content_lenght = NULL;
axis2_http_request_line_t* request_line = NULL;
for ( int i = 0; i < retry; ++i )
{
url = axis2_url_parse_string(m_env, url_str);
request_line =
axis2_http_request_line_create
(
m_env,
AXIS2_HTTP_HEADER_POST,
AXIS2_URL_GET_PATH(url, m_env),
AXIS2_HTTP_HEADER_PROTOCOL_11
);
simple_request =
axis2_http_simple_request_create
(
m_env,
request_line,
NULL,
0,
NULL
);
// create HTTP headers
header_host =
axis2_http_header_create
(
m_env,
AXIS2_HTTP_HEADER_HOST,
AXIS2_URL_GET_SERVER(url, m_env)
);
header_soap_action =
axis2_http_header_create
(
m_env,
AXIS2_HTTP_HEADER_SOAP_ACTION,
method
);
header_content_type =
axis2_http_header_create
(
m_env,
AXIS2_HTTP_HEADER_CONTENT_TYPE,
AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML
);
header_content_lenght =
axis2_http_header_create
(
m_env,
AXIS2_HTTP_HEADER_CONTENT_LENGTH,
(const axis2_char_t *)&content_lenght
);
// add HTTP headers
AXIS2_HTTP_SIMPLE_REQUEST_ADD_HEADER
(
simple_request,
m_env,
header_host
);
AXIS2_HTTP_SIMPLE_REQUEST_ADD_HEADER
(
simple_request,
m_env,
header_soap_action
);
AXIS2_HTTP_SIMPLE_REQUEST_ADD_HEADER
(
simple_request,
m_env,
header_content_type
);
AXIS2_HTTP_SIMPLE_REQUEST_ADD_HEADER
(
simple_request,
m_env,
header_content_lenght
);
AXIS2_HTTP_SIMPLE_REQUEST_SET_BODY_STRING
(
simple_request,
m_env,
envlopebuffer
);
if(m_http_client == NULL) {
m_http_client = axis2_http_client_create(m_env, url);
}
AXIS2_HTTP_CLIENT_SET_TIMEOUT(m_http_client, m_env, TIMEOUT);
// send request to server
try
{
status =
//AXIS2_HTTP_CLIENT_SEND
temporarely commented, Axis2c 0.94. 095 has memory leak
//(
// http_client,
// m_env,
// simple_request
//)
axis2_http_client_send1(m_http_client,
m_env, simple_request);
;
}
catch ( ... )
{
}
int statCode = getHTTPResponse(status, m_http_client,
pResponseMsg);
logSoap(i, retry, m_body, pResponseMsg, statCode);
if ( 1 < retry && mustRetry(statCode) )
{
#ifdef WIN32
Sleep(timeout*1000);
#else
// sleep(timeout);
#endif
#ifdef MYDBG
//cout << Log::getCurrentDateTime() << "\tsend
try = " << i+1 << ", statcode = " << statCode << endl;
//outt << Log::getCurrentDateTime() << "\tsend
try = " << i+1 << ", statcode = " << statCode << endl;
#endif
}
else
break;
freeBuffer(&m_body);
freeSimpleRequest(&simple_request);
//freeClient(&http_client);
}
if ( NULL != m_body )
fOk = isResponseValid(pResponseMsg);
}
else
{
pResponseMsg->setStatusTransport(status);
pResponseMsg->setStatusTransportDescription(string("SEND
failure .......... nothing to send!"));
}
freeBuffer(&m_body);
freeSimpleRequest(&simple_request);
//freeClient(&m_http_client);
return (fOk);
}
/// <summary>
/// method gets HTTP response (axis2_simple_response)
/// <param name="status">, [in], type = integer, status</param>
/// <param name="http_client">, [in], type = axis2_http_client_t*, axis2
http_client</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <returns> type = int, status</returns>
/// </summary>
int APSAPISoap::getHTTPResponse
(
int status0,
axis2_http_client_t* http_client,
SOAPResponseMessage* pResponseMsg
)
{
int status = status0;
char cStatus[256] = {0};
freeBuffer(&m_body);
pResponseMsg->setStatusTransport(status);
if ( status < 0 )
{
sprintf((char*)cStatus, "SEND Failed .........Can't send the
request. Status :%d", status);
pResponseMsg->setStatusTransportDescription(string(cStatus));
#ifdef MYDBG
// debug
printf("%s\n", cStatus);
// degug
#endif
return (status);
}
cout << "before recv header" << endl;
//cout << AXIS2_ERROR_GET_MESSAGE(m_env->error) <<
endl;
status = AXIS2_HTTP_CLIENT_RECIEVE_HEADER(http_client, m_env);
cout << "after recv header" << endl;
if ( status < 0 )
{
cout << AXIS2_ERROR_GET_MESSAGE(m_env->error) << endl;
sprintf((char*)cStatus, "SEND Failed ......... Can't recieve.
Status :%d", status);
pResponseMsg->setStatusTransportDescription(string(cStatus));
#ifdef MYDBG
// debug
printf("%s\n", cStatus);
//debug
#endif
return (status);
}
cout << "before get response" << endl;
axis2_http_simple_response_t*
simple_response = AXIS2_HTTP_CLIENT_GET_RESPONSE(http_client,
m_env);
cout << "after get response" << endl;
if ( NULL == simple_response )
{
pResponseMsg->setStatusTransportDescription("SEND Failed : NULL
response");
#ifdef MYDBG
// debug
printf("SEND Failed : NULL response");
// debug
#endif
return (-1);
}
sprintf((char*)&cStatus, "%d",
AXIS2_HTTP_SIMPLE_RESPONSE_GET_STATUS_CODE(simple_response, m_env));
pResponseMsg->setStatusHTTP(string(cStatus));
pResponseMsg->setStatusHTTPDescription
(
string(AXIS2_HTTP_SIMPLE_RESPONSE_GET_STATUS_LINE(simple_response, m_env))
);
#ifdef MYDBG
// debug
printf("Content Type :%s\n",
AXIS2_HTTP_SIMPLE_RESPONSE_GET_CONTENT_TYPE(
simple_response, m_env));
printf("Content Length :%d\n",
AXIS2_HTTP_SIMPLE_RESPONSE_GET_CONTENT_LENGTH(
simple_response, m_env));
printf("Status code :%d\n", status);
// debug
#endif
if ( 200 == status || 500 == status )
{
bool fOk = false;
try
{
char msg[512] = {0};
int len2 = 0;
for ( int i = 0; 3 > i; ++i )
if ( 0 < (len2 =
AXIS2_HTTP_SIMPLE_RESPONSE_GET_CONTENT_LENGTH(simple_response, m_env) ) )
break;
if ( fOk = ( 0 < len2 ) )
{
fOk = false;
try
{
// int len =
AXIS2_HTTP_SIMPLE_RESPONSE_GET_BODY_BYTES(simple_response, m_env, &m_body);
int len =
axis2_http_simple_response_get_body_bytes1(simple_response, m_env, &m_body,
len2);
cout << "after get body
bytes1" << endl;
if ( len != len2 )
{
#ifdef MYDBG
// cout <<
Log::getCurrentDateTime() << "\tprocessID = " << getpid() << "\tlen get body =
" << len << ", len2 get content = " << len2 << endl;
// outt <<
Log::getCurrentDateTime() << "\tprocessID = " << getpid() << "\tlen get body =
" << len << ", len2 get content = " << len2 << endl;
#endif
pResponseMsg->setStatusHTTP("-1");
sprintf(msg, "Response body
length = %d is less than stated in content length header = (%d)", len2, len);
pResponseMsg->setStatusHTTPDescription(msg);
freeBuffer(&m_body);
return (-1);
}
pResponseMsg->setEnvelope(string(m_body));
fOk = true;
}
catch ( ... )
{
}
}
else
{
pResponseMsg->setStatusHTTP("-1");
pResponseMsg->setStatusHTTPDescription("Content
length is 0");
return (-1);
}
}
catch ( ... )
{
}
#ifdef MYDBG
// debug
// printf("body :%s\n", ( fOk && (NULL != m_body ) ) ? m_body : "
response content is empty");
//debug
#endif
if ( !fOk )
{
pResponseMsg->setStatusHTTPDescription("Response
content is empty");
pResponseMsg->setStatusHTTP(string("500"));
status = 500;
}
}
return (status);
}
/// <summary>
/// method validates response
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <returns> type = bool, validaty of response, no faults - response HTTP code
= 200 (OK)</returns>
/// </summary>
bool APSAPISoap::isResponseValid
(
SOAPResponseMessage* pResponseMsg
)
{
bool fOk = false;
axiom_soap_envelope_t* soap_envelope = NULL;
axiom_soap_builder_t* soap_builder = NULL;
axiom_stax_builder_t* om_builder = NULL;
axiom_xml_reader_t* xml_reader = NULL;
axiom_soap_body* body = NULL;
axiom_soap_fault_t* fault = NULL;
try
{
xml_reader =
axiom_xml_reader_create_for_memory
(
m_env,
(void*)m_body,
strlen(m_body),
AXIS2_UTF_8,
AXIS2_XML_PARSER_TYPE_BUFFER
);
om_builder =
axiom_stax_builder_create(m_env, xml_reader);
soap_builder =
axiom_soap_builder_create
(
m_env,
om_builder,
AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI
);
soap_envelope =
AXIOM_SOAP_BUILDER_GET_SOAP_ENVELOPE(soap_builder,
m_env);
body =
AXIOM_SOAP_ENVELOPE_GET_BODY(soap_envelope, m_env);
if ( AXIOM_SOAP_BODY_HAS_FAULT(body, m_env) )
{
// SOAP fault, HTTP code = 500, and NULL != m_body
pResponseMsg->setBodyHasFault(true);
parseFault
(
fault = AXIOM_SOAP_BODY_GET_FAULT(body, m_env),
pResponseMsg
);
#ifdef MYDBG
// debug
printf("BODY HAS A FAULT");
// debug
#endif
}
else
{
// OK, HTTP code = 200
fOk = true;
axis2_char_t* t = AXIOM_NODE_TO_STRING
(
AXIOM_NODE_GET_FIRST_CHILD
(
AXIOM_SOAP_BODY_GET_BASE_NODE(body,
m_env),
m_env
),
m_env
);
string response = t;
AXIS2_FREE(m_env->allocator, t);
// to comfort signature validation
int pos = string::npos;
while ( string::npos != (pos = response.find("
xmlns=\"\"") ) )
response.erase(pos, 9);
pResponseMsg->setResponse(response);
}
// cleanup
try
{
freeBuffer(&m_body);
if ( NULL != soap_envelope )
AXIOM_SOAP_ENVELOPE_FREE(soap_envelope, m_env);
#ifdef SOLARIS
// axis95 (build on solaris CC) does not release om_stax_builder!
// freeing om_stax_builder on WIN32 and Linux is crashing!
if ( NULL != om_builder )
AXIOM_STAX_BUILDER_FREE(om_builder, m_env);
#endif
}
catch ( ... )
{
}
}
catch ( ... )
{
freeBuffer(&m_body);
}
#ifdef MYDBG
//debug
printf("\nFinished http_client send ..........\n\n");
// debug
#endif
return (fOk);
}
/// <summary>
/// method parses SOAP fault element
/// <param name="fault">, [in], type = axiom_soap_fault_t*, soap
fault</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// </summary>
void APSAPISoap::parseFault
(
axiom_soap_fault_t* fault,
SOAPResponseMessage* pResponseMsg
)
{
axiom_soap_fault_code*
code = AXIOM_SOAP_FAULT_GET_CODE(fault, m_env);
if ( NULL != code )
{
axiom_soap_fault_value_t*
value = AXIOM_SOAP_FAULT_CODE_GET_VALUE(code, m_env);
if ( NULL != value )
pResponseMsg->setFaultCode((char*)AXIOM_SOAP_FAULT_VALUE_GET_TEXT(value,
m_env));
}
axiom_soap_fault_reason*
reason = AXIOM_SOAP_FAULT_GET_REASON(fault, m_env);
if ( NULL != reason )
{
try
{
axiom_soap_fault_text*
reason_text =
AXIOM_SOAP_FAULT_REASON_GET_FIRST_SOAP_FAULT_TEXT(reason, m_env); //
faultstring
if ( NULL != reason_text )
pResponseMsg->setFaultReason(AXIOM_SOAP_FAULT_TEXT_GET_TEXT(reason_text,
m_env)); // faultstring CDATA
}
catch ( ... )
{
}
}
}
/// <summary>
/// destructor
/// cleanup
/// </summary>
APSAPISoap::~APSAPISoap(void)
{
//freeClient(&m_http_client); //commented this as the instance is no
longer recreated for every request pbkar
freeBuffers();
axis2_env_free(m_env);
}
------------------------------------------------------------
2) APSAPISoap.h
///
///
/// @author lkrankur
///
///
//#pragma once
#ifndef APSAPISOAP_H
#define APSAPISOAP_H
#include "Extern.h"
#include "APSAPISoapUtil.h"
#include "RequestTO.h"
#include "SOAPResponseMessage.h"
#include "APSConfigData.h"
#include <vector>
using namespace std;
const int TIMEOUT = 60000;
/// <summary>
///Info of XACML attribute
/// </summary>
struct aps_arribute_t
{
///
axis2_char_t* attributeId;
///
axis2_char_t* dataType;
///
axis2_char_t* dataValue;
/// constructor
aps_arribute_t(axis2_env_t* env)
{
dataType =
(axis2_char_t*)AXIS2_STRDUP(APS::XACML::ATTRIBUTE_DEFAULT_TYPE, env);
//"http://www.w3.org/2001/XMLSchema#string";
};
/// <summary>
/// constructor
/// <param name="id">, [in], type = axis2_char_t*, AttributeID of attribute
element </param>
/// <param name="value">, [in], type = axis2_char_t*, DataValue of
attribute element </param>
/// </summary>
aps_arribute_t(axis2_char_t* id, axis2_char_t* value, axis2_env_t* env)
{
attributeId = (axis2_char_t*)AXIS2_STRDUP(id, env);
dataType =
(axis2_char_t*)AXIS2_STRDUP(APS::XACML::ATTRIBUTE_DEFAULT_TYPE, env);
dataValue = (axis2_char_t*)AXIS2_STRDUP(value, env);
};
/// <summary>
/// constructor
/// <param name="id">, [in], type = axis2_char_t*, AttributeID of attribute
element </param>
/// <param name="id">, [in], type = axis2_char_t*, DataType of attribute
element </param>
/// <param name="value">, [in], type = axis2_char_t*, DataValue of
attribute element </param>
/// </summary>
aps_arribute_t(axis2_char_t* id, axis2_char_t* type, axis2_char_t*
value, axis2_env_t* env)
{
attributeId = (axis2_char_t*)AXIS2_STRDUP(id, env);
dataType = (axis2_char_t*)AXIS2_STRDUP(type, env);
dataValue = (axis2_char_t*)AXIS2_STRDUP(value, env);
};
};
///
/// struct to use in fixing Axis2c 0.94. 095 memory leak
/// axis2_http_client implementation
///
typedef struct axis2_http_client_impl
{
axis2_http_client_t http_client;
int sockfd;
axis2_stream_t *data_stream;
axis2_url_t *url;
axis2_http_simple_response_t *response;
axis2_bool_t request_sent;
int timeout;
axis2_bool_t proxy_enabled;
axis2_char_t *proxy_host;
int proxy_port;
axis2_char_t *proxy_host_port;
}
axis2_http_client_impl_t;
#define AXIS2_INTF_TO_IMPL(http_client) ((axis2_http_client_impl_t
*)(http_client))
/// <summary>
/// ASP SOAP processing
/// </summary>
class APSAPISoap
{
/// axis2 environment
public:
static axis2_env_t* m_env; // made static for single instance
pbkar
static axis2_http_client_t* m_http_client;
static int m_count;
/// axis2 memory allocation
axis2_allocator_t* m_allocator;
///
axis2_char_t* m_buffer;
axis2_char_t* m_buffer2;
axis2_char_t* m_body; // http body
void freeOMElement(axiom_element_t* om_element);
void freeOMNode(axiom_node_t* om_node);
/// <summary>
/// method adds XACML attributes as OM elements to parent node
/// <param name="attributes">, [in], type = vector<aps_arribute_t*>,
collection of attribute info </param>
/// <param name="parent">, [in], type = axiom_node_t*, parent OM node
</param>
/// </summary>
void addAttributes
(
vector<aps_arribute_t*> attributes,
axiom_node_t* parent
);
/// <summary>
/// method adds XACML attribute as OM element to a parent OM node
/// <param name="attribute">, [in], type = aps_arribute_t*, attribute info
</param>
/// <param name="parent">, [in], type = axiom_node_t*, parent OM node
</param>
/// </summary>
void addAttribute
(
aps_arribute_t* attribute,
axiom_node_t* parent
);
/// <summary>
/// method clears collections of aps_arribute_t*
/// <param name="attributes">, [in], type = vector<aps_arribute_t*>&
</param>
/// </summary>
void clearAttributes(vector<aps_arribute_t*>& attributes);
/// <summary>
/// method creates XACML Request element (evaluation policy) as OM node
/// <param name="localName">, [in], type = axis2_char_t*, localName of
Request element</param>
/// <param name="localNamespace">, [in], type = axis2_char_t*, namespace of
localName of Request element</param>
/// <param name="pRequest">, [in], type = RequestTO*, pointer to RequestTO
object </param>
/// </summary>
axiom_node_t* createRequest
(
axis2_char_t* localName,
axis2_char_t* localNamespace,
RequestTO* pRequest
);
/// <summary>
/// method creates XACML Request element (RoleRequest, ResourceRequest,
DCRequest) as OM node
/// <param name="localName">, [in], type = axis2_char_t*, localName of
Request element</param>
/// <param name="appname">, [in], type = axis2_char_t*, name of
application</param>
/// </summary>
axiom_node_t* createRequest2
(
axis2_char_t* localName,
axis2_char_t* appname
);
/// <summary>
/// method creates OM node for Subject element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="pSubject">, [in], type = SubjectTO*, pointer to SubjectTO
object</param>
/// </summary>
void createSubject
(
axiom_node_t* request,
SubjectTO* subject
);
/// <summary>
/// method creates OM node for Resource element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="resource">, [in], type = axis2_char_t*, resource
name</param>
/// <param name="scope">, [in], type = axis2_char_t*, scope of
resource</param>
/// </summary>
void createResource
(
axiom_node_t* request,
axis2_char_t* resource,
axis2_char_t* scope
);
/// <summary>
/// method creates OM node for Action element and adds to Request node
/// <param name="request">, [in], type = axiom_node_t*, request node</param>
/// <param name="action">, [in], type = axis2_char_t*, action name</param>
/// </summary>
void createAction
(
axiom_node_t* request,
axis2_char_t* action
);
/// <summary>
/// method logs send/receive SOAP over HTTP
/// <param name="attempt">, [in], type = integer, attempt tried</param>
/// <param name=buffer>, [in], type = integer, number of attempts
configured</param>
/// <param name="method">, [in], type = char*, message that sent</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <param name="status">, [in], type = integer, HTTP code returned (if
any)</param>
/// </summary>
void logSoap
(
int attempt,
int retry,
char* buffer,
SOAPResponseMessage* pResponseMsg,
int status
);
void freeClient(axis2_http_client_t** http_client)
{
if ( NULL != *http_client )
{
axis2_http_client_impl_t* client_impl =
AXIS2_INTF_TO_IMPL(*http_client);
if ( NULL != client_impl->data_stream )
{
try
{
AXIS2_STREAM_FREE(client_impl->data_stream, m_env);
}
catch ( ... )
{
}
client_impl->data_stream = NULL;
}
try
{
AXIS2_HTTP_CLIENT_FREE(*http_client, m_env);
}
catch ( ... )
{
}
}
*http_client = NULL;
}
void freeSimpleRequest(axis2_http_simple_request_t** simple_request)
{
if ( NULL != *simple_request)
{
try
{
AXIS2_HTTP_SIMPLE_REQUEST_FREE(*simple_request,
m_env);
}
catch ( ... )
{
}
*simple_request = NULL;
}
}
public:
/// <summary>
/// constructor
/// </summary>
APSAPISoap();
/// <summary>
/// method creates unsigned envelope
/// <param name="localName">, [in], type = axis2_char_t*, local name for
the request element</param>
/// <param name="localNamespace">, [in], type = axis2_char_t*, namespace
for the request element, could be NULL</param>
/// <param name="pRequest">, [in], type = RequestTO*, XACML request, could
be NULL</param>
/// <param name="applicationName">, [in], type = axis2_char_t*, application
name, could be NULL</param>
/// </summary>
bool getSoapEnvelope
(
axis2_char_t* localName,
axis2_char_t* localNamespace,
RequestTO* pRequest,
axis2_char_t* applicationName
);
/// <summary>
/// method sends Request SOAP message over HTTP
/// <param name="envlopebuffer">, [in], type = char*, buffer - keeps signed
SOAP envelope</param>
/// <param name="url">, [in], type = axis2_char_t*, path to the service
fotmat (pdp location)/(service)</param>
/// <param name="method">, [in], type = axis2_char_t*, service method -
soap action</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <param name="int">, [in], type = int, number of attempts when
failure</param>
/// <param name="int">, [in], type = int, interval in sec between attempts
when connection failure</param>
/// <returns> type = bool, success in sending HTTP</returns>
/// </summary>
bool sendSoapEnvelope
(
char* envelope,
axis2_char_t* url,
axis2_char_t* method,
SOAPResponseMessage* pResponseMsg,
int retry = 1,
int timeout = 10
);
/// <summary>
/// method gets HTTP response (axis2_simple_response)
/// <param name="status">, [in], type = integer, status</param>
/// <param name="http_client">, [in], type = axis2_http_client_t*, axis2
http_client</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <returns> type = int, status</returns>
/// </summary>
int getHTTPResponse
(
int status,
axis2_http_client_t* http_client,
SOAPResponseMessage* pResponseMsg
);
/// <summary>
/// method validates response
/// <param name="status">, [in], type = integer, status</param>
/// <returns> type = bool, sending request needs retry</returns>
/// </summary>
bool mustRetry(int status)
{
return
APSConfigData::getInstance().getPdpLocation().StatusCodeForceRetry(status);
};
/// <summary>
/// method validates response
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// <returns> type = bool, validaty of response, no faults - response HTTP code
= 200 (OK)</returns>
/// </summary>
bool isResponseValid
(
SOAPResponseMessage* pResponseMsg
);
/// <summary>
/// method parses SOAP fault element
/// <param name="fault">, [in], type = axiom_soap_fault_t*, soap
fault</param>
/// <param name="pResponseMsg">, [in], type = SOAPResponseMessage*, pointer
to SOAPResponseMessage object</param>
/// </summary>
void parseFault
(
axiom_soap_fault_t* fault,
SOAPResponseMessage* pResponseMsg
);
/// <summary>
/// accessor get buffer, keeps SOAP envelope
/// <returns> type = axis2_char_t*, buffer, keeps SOAP envelope
/// </summary>
axis2_char_t* getBuffer()
{
return m_buffer;
}
/// <summary>
/// accessor get buffer, keeps first child of SOAP body
/// <returns> type = axis2_char_t*, buffer, keeps first child of SOAP bod
/// </summary>
axis2_char_t* getBuffer2()
{
return m_buffer2;
}
void freeBuffer(axis2_char_t** buffer)
{
if ( NULL != *buffer )
{
try
{
AXIS2_FREE(m_env->allocator, *buffer);
}
catch ( ... )
{
}
*buffer = NULL;
}
}
/// <summary>
/// method frees m_buffer, m_buffer2
/// </summary>
void freeBuffers()
{
freeBuffer(&m_buffer);
freeBuffer(&m_buffer2);
freeBuffer(&m_body);
}
/// destructor
virtual ~APSAPISoap(void);
};
#endif /* APSAPISOAP_H */
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]