-/*
-Copyright 2002 Kevin O'Donnell
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- * Include the core server components.
- */
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "apr_compat.h"
#include "apr_strings.h"
-
-
/* our stuff */
#include "opensrf/transport_client.h"
#include "opensrf/osrf_message.h"
#ifdef RESTGATEWAY
#include "rest_xml.h"
-/*
- * This function is registered as a handler for HTTP methods and will
- * therefore be invoked for all GET requests (and others). Regardless
- * of the request type, this function simply sends a message to
- * STDERR (which httpd redirects to logs/error_log). A real module
- * would do *alot* more at this point.
- */
#define MODULE_NAME "ils_rest_gateway_module"
#else
#define MODULE_NAME "ils_gateway_module"
#endif
-/*
-struct session_list_struct {
- osrf_app_session* session;
- struct session_list_struct* next;
- int serve_count;
-};
-typedef struct session_list_struct session_list;
-
-static session_list* the_list = NULL;
-
-static void del_session( char* service ) {
- if(!service || ! the_list)
- return;
-
- debug_handler("In del_sesion for %s", service );
- session_list* prev = the_list;
- session_list* item = prev->next;
-
- if(!strcmp(prev->session->remote_service, service)) {
- info_handler("Removing gateway session for %s", service );
- the_list = item;
- osrf_app_session_destroy(prev->session);
- free(prev);
- return;
- }
-
- while(item) {
- if( !strcmp(item->session->remote_service, service)) {
- info_handler("Removing gateway session for %s", service );
- prev->next = item->next;
- osrf_app_session_destroy(item->session);
- free(item);
- return;
- }
- prev = item;
- item = item->next;
- }
-
- warning_handler("Attempt to remove gateway session "
- "that does not exist: %s", service );
-
-}
-
-// if(update) we add 1 to the serve_count
-static osrf_app_session* find_session( char* service, int update ) {
-
- session_list* item = the_list;
- while(item) {
-
- if(!strcmp(item->session->remote_service,service)) {
- if(update) {
- if( item->serve_count++ > 20 ) {
- debug_handler("Disconnected session on 20 requests => %s", service);
- osrf_app_session_disconnect(item->session);
- del_session(service);
- return NULL;
- //item->serve_count = 0;
- }
- }
- debug_handler("Found session for %s in gateway cache", service);
- return item->session;
- }
-
- item = item->next;
- }
- return NULL;
-}
-
-static void add_session( char* service, osrf_app_session* session ) {
-
- if(!session) return;
-
- if(find_session(service,0))
- return;
-
- debug_handler("Add session for %s to the cache", service );
-
- session_list* new_item = (session_list*) safe_malloc(sizeof(session_list));
- new_item->session = session;
- //new_item->service = service;
- new_item->serve_count = 0;
-
- if(the_list) {
- session_list* second = the_list->next;
- the_list = new_item;
- new_item->next = second;
- } else {
- the_list = new_item;
- }
-}
-*/
static void mod_ils_gateway_child_init(apr_pool_t *p, server_rec *s) {
- if( ! osrf_system_bootstrap_client( "/openils/conf/gateway.xml") ) {
+ if( ! osrf_system_bootstrap_client( "/openils/conf/gateway.xml") )
fatal_handler("Unable to load gateway config file...");
- }
-
- /* we don't want to waste time parsing json that we're not going to look at*/
- osrf_message_set_json_parse_result(0);
- osrf_message_set_json_parse_params(0);
fprintf(stderr, "Bootstrapping %d\n", getpid() );
fflush(stderr);
}
r->allowed |= (AP_METHOD_BIT << M_POST);
- //char* argcopy = (char*) apr_pstrdup(p, arg);
-
- //while( argcopy && (val = ap_getword(p, (const char**) &argcopy, '&'))) {
while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {
- //const char* val2 = val;
-
key = ap_getword(r->pool, (const char**) &val, '=');
if(!key || !key[0])
break;
info_handler( "param %s", string_array_get_string(sarray,k));
}
- /*
- osrf_app_session* session = find_session(service,1);
-
- if(!session) {
- debug_handler("building new session for %s", service );
- session = osrf_app_client_session_init(service);
- add_session(service, session);
- }
- */
-
osrf_app_session* session = osrf_app_client_session_init(service);
debug_handler("MOD session service: %s", session->remote_service );
-
- /* connect to the remote service */
- /*
- if(!osrf_app_session_connect(session)) {
- exception = json_object_new_object();
- json_object_object_add( exception, "is_err", json_object_new_int(1));
- json_object_object_add( exception,
- "err_msg", json_object_new_string("Unable to connect to remote service"));
-
- ap_rputs(json_object_to_json_string(exception), r );
- json_object_put(exception);
- return OK;
- }
- */
-
int req_id = osrf_app_session_make_req( session, NULL, method, 1, sarray );
string_array_destroy(sarray);
sprintf( code, "%d", omsg->status_code );
buffer_add( exc_buffer, code );
- /* build the exception object */
- /*
- exception = json_object_new_object();
- json_object_object_add( exception, "is_err", json_object_new_int(1));
- json_object_object_add( exception,
- "err_msg", json_object_new_string(exc_buffer->buf));
- */
-
exception = json_parse_string("{}");
exception->add_key(exception, "is_err", json_parse_string("1"));
exception->add_key(exception, "err_msg", new_object(exc_buffer->buf) );
/* round up our data */
if(exception) {
- //content = strdup(json_object_to_json_string(exception));
- //json_object_put(exception);
content = strdup(exception->to_json(exception));
free_object(exception);
} else {
#include "osrf_message.h"
-/* default to true */
-int parse_json_result = 1;
-int parse_json_params = 1;
-
-/* utility function for debugging a DOM doc */
-static void recurse_doc( xmlNodePtr node ) {
- if( node == NULL ) return;
- debug_handler("Recurse: %s => %s", node->name, node->content );
- xmlNodePtr t = node->children;
- while(t) {
- recurse_doc(t);
- t = t->next;
- }
-}
-
-
-
osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
osrf_message* msg = (osrf_message*) safe_malloc(sizeof(osrf_message));
msg->protocol = protocol;
msg->next = NULL;
msg->is_exception = 0;
- msg->parse_json_result = parse_json_result;
- msg->parse_json_params = parse_json_params;
- msg->parray = init_string_array(16); /* start out with a slot for 16 params. can grow */
msg->_params = NULL;
msg->_result_content = NULL;
}
-void osrf_message_set_json_parse_result( int ibool ) {
-// parse_json_result = ibool;
-}
-
-void osrf_message_set_json_parse_params( int ibool ) {
-// parse_json_params = ibool;
-}
-
void osrf_message_set_method( osrf_message* msg, char* method_name ) {
if( msg == NULL || method_name == NULL ) return;
msg->method_name = strdup( method_name );
}
-/* uses the object passed in directly, do not FREE! */
void osrf_message_add_object_param( osrf_message* msg, object* o ) {
if(!msg|| !o) return;
- if(msg->parse_json_params) {
- if(!msg->_params)
- msg->_params = json_parse_string("[]");
- msg->_params->push(msg->_params, json_parse_string(o->to_json(o)));
- }
+ if(!msg->_params)
+ msg->_params = json_parse_string("[]");
+ char* j = o->to_json(o);
+ msg->_params->push(msg->_params, json_parse_string(j));
+ free(j);
}
void osrf_message_set_params( osrf_message* msg, object* o ) {
if(!msg || !o) return;
- char* j = object_to_json(o);
- debug_handler("Setting params to\n%s", j);
- free(j);
-
- if(msg->parse_json_params) {
- if(!o->is_array) {
- warning_handler("passing non-array to osrf_message_set_params()");
- return;
- }
- if(msg->_params) free_object(msg->_params);
- char* j = o->to_json(o);
- msg->_params = json_parse_string(j);
- free(j);
+ if(!o->is_array) {
+ warning_handler("passing non-array to osrf_message_set_params()");
+ return;
}
+
+ if(msg->_params) free_object(msg->_params);
+
+ char* j = o->to_json(o);
+ msg->_params = json_parse_string(j);
+ free(j);
}
if(msg == NULL || param_string == NULL) return;
if(!msg->_params) msg->_params = new_object(NULL);
msg->_params->push(msg->_params, json_parse_string(param_string));
-
- /*
- if(!msg->parse_json_params)
- string_array_add(msg->parray, param_string);
- */
}
warning_handler( "Bad params to osrf_message_set_result_content()" );
msg->result_string = strdup(json_string);
- debug_handler( "Message Parse JSON result is set to: %d", msg->parse_json_result );
-
- if(msg->parse_json_result)
- msg->_result_content = json_parse_string(msg->result_string);
+ if(json_string) msg->_result_content = json_parse_string(json_string);
}
if( msg->_params != NULL )
free_object(msg->_params);
- string_array_destroy(msg->parray);
-
free(msg);
}
msgs[numparsed++] = new_msg;
}
}
+ free_object(json);
return numparsed;
}
-
-/* here's where things get interesting */
-char* osrf_message_to_xml( osrf_message* msg ) {
-
- if( msg == NULL ) return NULL;
-
- xmlKeepBlanksDefault(0);
-
- xmlNodePtr message_node;
- xmlNodePtr type_node;
- xmlNodePtr thread_trace_node;
- xmlNodePtr protocol_node;
- xmlNodePtr status_node;
- xmlNodePtr status_text_node;
- xmlNodePtr status_code_node;
- xmlNodePtr method_node = NULL;
- xmlNodePtr method_name_node;
- xmlNodePtr params_node = NULL;
- xmlNodePtr result_node;
- xmlNodePtr content_node;
-
-
- xmlDocPtr doc = xmlReadDoc(
- BAD_CAST "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
- "<oils:domainObject name='oilsMessage'/></oils:root>",
- NULL, NULL, XML_PARSE_NSCLEAN );
-
- message_node = xmlDocGetRootElement(doc)->children; /* since it's the only child */
- type_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- thread_trace_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- protocol_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
-
- char tt[64];
- memset(tt,0,64);
- sprintf(tt,"%d",msg->thread_trace);
- xmlSetProp( thread_trace_node, BAD_CAST "name", BAD_CAST "threadTrace" );
- xmlSetProp( thread_trace_node, BAD_CAST "value", BAD_CAST tt );
-
- char prot[64];
- memset(prot,0,64);
- sprintf(prot,"%d",msg->protocol);
- xmlSetProp( protocol_node, BAD_CAST "name", BAD_CAST "protocol" );
- xmlSetProp( protocol_node, BAD_CAST "value", BAD_CAST prot );
-
- switch(msg->m_type) {
-
- case CONNECT:
- xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
- xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
- break;
-
- case DISCONNECT:
- xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
- xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
- break;
-
- case STATUS:
-
- xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
- xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "STATUS" );
- status_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
- xmlSetProp( status_node, BAD_CAST "name", BAD_CAST msg->status_name );
-
- status_text_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
- xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
-
- status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
-
- char sc[64];
- memset(sc,0,64);
- sprintf(sc,"%d",msg->status_code);
- xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
-
- break;
-
- case REQUEST:
-
- xmlSetProp( type_node, BAD_CAST "name", "type" );
- xmlSetProp( type_node, BAD_CAST "value", "REQUEST" );
- method_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
- xmlSetProp( method_node, BAD_CAST "name", BAD_CAST "oilsMethod" );
-
- if( msg->method_name != NULL ) {
-
- method_name_node = xmlNewChild( method_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- xmlSetProp( method_name_node, BAD_CAST "name", BAD_CAST "method" );
- xmlSetProp( method_name_node, BAD_CAST "value", BAD_CAST msg->method_name );
-
- if( msg->parse_json_params ) {
- if( msg->_params != NULL ) {
-
- //char* jj = json_object_to_json_string( msg->params );
- char* jj = msg->_params->to_json(msg->_params);
- params_node = xmlNewChild( method_node, NULL, BAD_CAST "params", NULL );
- xmlNodePtr tt = xmlNewDocTextLen( doc, BAD_CAST jj, strlen(jj) );
- xmlAddChild(params_node, tt);
- }
-
- } else {
- if( msg->parray != NULL ) {
-
- /* construct the json array for the params */
- growing_buffer* buf = buffer_init(128);
- buffer_add( buf, "[");
- int k;
- for( k=0; k!= msg->parray->size; k++) {
- buffer_add( buf, string_array_get_string(msg->parray, k) );
- if(string_array_get_string(msg->parray, k+1))
- buffer_add( buf, "," );
- }
-
- buffer_add( buf, "]");
-
- char* tmp = safe_malloc( (buf->n_used + 1) * sizeof(char));
- memcpy(tmp, buf->buf, buf->n_used);
-
- params_node = xmlNewChild( method_node, NULL,
- BAD_CAST "params", NULL );
-
- xmlNodePtr tt = xmlNewDocTextLen( doc, BAD_CAST tmp, strlen(tmp) );
- xmlAddChild(params_node, tt);
-
- buffer_free(buf);
- }
- }
- }
-
- break;
-
- case RESULT:
-
- xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
- xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "RESULT" );
- result_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
- xmlSetProp( result_node, BAD_CAST "name", BAD_CAST "oilsResult" );
-
- status_text_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
- xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
-
- status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
- xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
-
- char stc[64];
- memset(stc,0,64);
- sprintf(stc,"%d",msg->status_code);
- xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
-
- content_node = xmlNewChild( result_node, NULL,
- BAD_CAST "domainObject", BAD_CAST msg->result_string );
- xmlSetProp( content_node, BAD_CAST "name", BAD_CAST "oilsScalar" );
-
- break;
-
- default:
- warning_handler( "Recieved bogus message type" );
- return NULL;
- }
-
-
- // -----------------------------------------------------
- // Dump the XML doc to a string and remove the
- // xml declaration
- // -----------------------------------------------------
-
- /* passing in a '1' means we want to retain the formatting */
-
- //xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
- //xmlDocDumpMemoryEnc( doc, &xmlbuf, &bufsize, "UTF-8" );
-
-
-
- /*
- xmlDocDumpMemoryEnc( doc, &xmlbuf, &bufsize, "UTF-8" );
-
- encoded_msg = strdup( (char*) xmlbuf );
-
-
- if( encoded_msg == NULL )
- fatal_handler("message_to_xml(): Out of Memory");
-
- xmlFree(xmlbuf);
- xmlFreeDoc( doc );
- xmlCleanupParser();
- */
-
-
- /***/
- xmlBufferPtr xmlbuf = xmlBufferCreate();
- xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
-
- char* xml = strdup( (char*) (xmlBufferContent(xmlbuf)));
- xmlBufferFree(xmlbuf);
-
- int l = strlen(xml)-1;
- if( xml[l] == 10 || xml[l] == 13 )
- xml[l] = '\0';
-
- return xml;
- /***/
-
-
-
- /*
- int len = strlen(encoded_msg);
- char tmp[len];
- memset( tmp, 0, len );
- int i;
- int found_at = 0;
-
- for( i = 0; i!= len; i++ ) {
- if( encoded_msg[i] == 62) {
-
- found_at = i + 1;
- break;
- }
- }
-
- if( found_at ) {
- strncpy( tmp, encoded_msg + found_at, len - found_at );
- memset( encoded_msg, 0, len );
- strcpy( encoded_msg, tmp );
- }
-
- return encoded_msg;
- */
-
-}
-
-
-
-
-int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
-
- if(!xml) return 0;
-
- xmlKeepBlanksDefault(0);
-
- xmlNodePtr message_node;
- xmlDocPtr doc = xmlReadDoc(
- BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
-
- xmlNodePtr root =xmlDocGetRootElement(doc);
- if(!root) {
- warning_handler( "Attempt to build message from incomplete xml %s", xml );
- return 0;
- }
-
- int msg_index = 0;
- message_node = root->children; /* since it's the only child */
-
- if(!message_node) {
- warning_handler( "Attempt to build message from incomplete xml %s", xml );
- return 0;
- }
-
- while( message_node != NULL ) {
-
- xmlNodePtr cur_node = message_node->children;
- osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
- new_msg->parse_json_result = parse_json_result;
-
-
- while( cur_node ) {
-
- xmlChar* name = NULL;
- xmlChar* value = NULL;
-
- /* we're a domainObjectAttr */
- if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
- name = xmlGetProp( cur_node, BAD_CAST "name");
-
- if(name) {
-
- value = xmlGetProp( cur_node, BAD_CAST "value" );
- if(value) {
-
- if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
-
- if(!strcmp((char*)value, "CONNECT"))
- new_msg->m_type = CONNECT;
-
- if(!strcmp((char*)value, "DISCONNECT"))
- new_msg->m_type = DISCONNECT;
-
- if(!strcmp((char*)value, "STATUS"))
- new_msg->m_type = STATUS;
-
- if(!strcmp((char*)value, "REQUEST"))
- new_msg->m_type = REQUEST;
-
- if(!strcmp((char*)value, "RESULT"))
- new_msg->m_type = RESULT;
-
- } else if((!strcmp((char*)name, "threadTrace"))) {
- new_msg->thread_trace = atoi( (char*) value );
-
- } else if((!strcmp((char*)name, "protocol"))) {
- new_msg->protocol = atoi( (char*) value );
- }
-
- xmlFree(value);
- }
- xmlFree(name);
- }
- }
-
- /* we're a domainObject */
- if( !strcmp((char*)cur_node->name,"domainObject" )) {
-
- name = xmlGetProp( cur_node, BAD_CAST "name");
-
- if(name) {
-
- if( !strcmp(name,"oilsMethod") ) {
-
- xmlNodePtr meth_node = cur_node->children;
-
- while( meth_node != NULL ) {
-
- if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
- char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
- if(meth_name) {
- new_msg->method_name = strdup(meth_name);
- xmlFree(meth_name);
- }
- }
-
- if( !strcmp((char*)meth_node->name,"params" ) && meth_node->children->content ) {
- //new_msg->params = json_object_new_string( meth_node->children->content );
- if( new_msg->parse_json_params) {
- //new_msg->params = json_tokener_parse(meth_node->children->content);
- new_msg->_params = json_parse_string(meth_node->children->content);
- } else {
- /* XXX this will have to parse the JSON to
- grab the strings for full support! This should only be
- necessary for server support of
- non-json-param-parsing, though. Ugh. */
- //new_msg->params = json_tokener_parse(meth_node->children->content);
- new_msg->_params = json_parse_string(meth_node->children->content);
- }
- }
-
- meth_node = meth_node->next;
- }
- } //oilsMethod
-
- if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
-
- xmlNodePtr result_nodes = cur_node->children;
-
- while( result_nodes ) {
-
- if(!strcmp(result_nodes->name,"domainObjectAttr")) {
-
- xmlChar* result_attr_name = xmlGetProp( result_nodes, BAD_CAST "name");
- if(result_attr_name) {
- xmlChar* result_attr_value = xmlGetProp( result_nodes, BAD_CAST "value" );
-
- if( result_attr_value ) {
- if((!strcmp((char*)result_attr_name, "status")))
- new_msg->status_text = strdup((char*) result_attr_value );
-
- else if((!strcmp((char*)result_attr_name, "statusCode")))
- new_msg->status_code = atoi((char*) result_attr_value );
- xmlFree(result_attr_value);
- }
-
- xmlFree(result_attr_name);
- }
-
- }
-
-
- if(!strcmp(result_nodes->name,"domainObject")) {
- xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
- if(r_name) {
- if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content ) {
- osrf_message_set_result_content( new_msg, result_nodes->children->content);
- }
- xmlFree(r_name);
- }
- }
- result_nodes = result_nodes->next;
- }
- }
-
- if( new_msg->m_type == STATUS )
- new_msg->status_name = strdup(name);
-
- xmlFree(name);
- }
- }
-
- /* we're a params node */
- if( !strcmp((char*)cur_node->name,"params" )) {
-
- }
-
- cur_node = cur_node->next;
- }
-
- msgs[msg_index] = new_msg;
- msg_index++;
- message_node = message_node->next;
-
- } // while message_node != null
-
- xmlCleanupCharEncodingHandlers();
- xmlFreeDoc( doc );
- xmlCleanupParser();
-
- return msg_index;
-
-}
-