updated to new json api
[working/Evergreen.git] / Open-ILS / src / apachemods / mod_rest_gateway.c
1 #include "mod_rest_gateway.h"
2
3 char* ils_rest_gateway_config_file;
4
5 static const char* ils_gateway_set_config(cmd_parms *parms, void *config, const char *arg) {
6         ils_gateway_config  *cfg;
7
8         cfg = ap_get_module_config(parms->server->module_config, &ils_rest_gateway_module);
9
10         cfg->configfile = (char*) arg;
11         ils_rest_gateway_config_file = (char*) arg;
12
13         return NULL;
14 }
15
16 /* tell apache about our commands */
17 static const command_rec ils_gateway_cmds[] = {
18         AP_INIT_TAKE1( GATEWAY_CONFIG, ils_gateway_set_config, NULL, RSRC_CONF, "gateway config file"),
19         {NULL}
20 };
21
22 /* build the config object */
23 static void* ils_gateway_create_config( apr_pool_t* p, server_rec* s) {
24         ils_gateway_config* cfg = (ils_gateway_config*) apr_palloc(p, sizeof(ils_gateway_config));
25         cfg->configfile = GATEWAY_DEFAULT_CONFIG;
26         return (void*) cfg;
27 }
28
29
30 static void mod_ils_gateway_child_init(apr_pool_t *p, server_rec *s) {
31
32         char* cfg = ils_rest_gateway_config_file;
33
34         if( ! osrf_system_bootstrap_client( cfg, CONFIG_CONTEXT) ) 
35                 fatal_handler("Unable to load gateway config file...");
36         fprintf(stderr, "Bootstrapping %d\n", getpid() );
37         fflush(stderr);
38 }
39
40 static int mod_ils_gateway_method_handler (request_rec *r) {
41
42         /* make sure we're needed first thing*/
43         if (strcmp(r->handler, MODULE_NAME )) 
44                 return DECLINED;
45
46         apr_pool_t *p = r->pool;        /* memory pool */
47         char* arg = r->args;                    /* url query string */
48
49         char* service                                   = NULL; /* service to connect to */
50         char* method                                    = NULL; /* method to perform */
51
52         //json* exception                               = NULL; /* returned in error conditions */
53         jsonObject* exception                           = NULL; /* returned in error conditions */
54         string_array* sarray                    = init_string_array(12); /* method parameters */
55
56         growing_buffer* buffer          = NULL; /* POST data */
57         growing_buffer* tmp_buf         = NULL; /* temp buffer */
58
59         char* key                                               = NULL; /* query item name */
60         char* val                                               = NULL; /* query item value */
61
62
63
64         /* verify we are connected */
65         if(!osrf_system_get_transport_client()) {
66                 fatal_handler("Bootstrap Failed, no transport client");
67                 return HTTP_INTERNAL_SERVER_ERROR;
68         }
69
70
71
72         /* gather the post args and append them to the url query string */
73         if( !strcmp(r->method,"POST") ) {
74
75                 ap_setup_client_block(r,REQUEST_CHUNKED_DECHUNK);
76
77                 if(! ap_should_client_block(r)) {
78                         warning_handler("No Post Body");
79                 }
80
81                 char body[1025];
82                 memset(body,0,1025);
83                 buffer = buffer_init(1025);
84
85                 while(ap_get_client_block(r, body, 1024)) {
86                         debug_handler("Apache read POST block data: %s\n", body);
87                         buffer_add( buffer, body );
88                         memset(body,0,1025);
89                 }
90
91                 if(arg && arg[0]) {
92                         tmp_buf = buffer_init(1024);
93                         buffer_add(tmp_buf,arg);
94                         buffer_add(tmp_buf,buffer->buf);
95                         arg = (char*) apr_pstrdup(p, tmp_buf->buf);
96                         buffer_free(tmp_buf);
97                 } else {
98                         arg = (char*) apr_pstrdup(p, buffer->buf);
99                 }
100                 buffer_free(buffer);
101
102         } 
103
104         debug_handler("params args are %s", arg);
105
106
107         if( ! arg || !arg[0] ) { /* we received no request */
108                 warning_handler("No Args");
109                 return OK;
110         }
111
112         r->allowed |= (AP_METHOD_BIT << M_GET);
113         r->allowed |= (AP_METHOD_BIT << M_POST);
114
115         
116         while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {
117
118                 key = ap_getword(r->pool, (const char**) &val, '=');
119                 if(!key || !key[0])
120                         break;
121
122                 ap_unescape_url((char*)key);
123                 ap_unescape_url((char*)val);
124
125                 if(!strcmp(key,"service")) 
126                         service = val;
127
128                 if(!strcmp(key,"method"))
129                         method = val;
130
131                 if(!strcmp(key,"param"))
132                         string_array_add(sarray, val);
133
134         }
135
136         info_handler("Performing(%d):  service %s | method %s | \n",
137                         getpid(), service, method );
138
139         int k;
140         for( k = 0; k!= sarray->size; k++ ) {
141                 info_handler( "param %s", string_array_get_string(sarray,k));
142         }
143
144         osrf_app_session* session = osrf_app_client_session_init(service);
145
146         debug_handler("MOD session service: %s", session->remote_service );
147
148         int req_id = osrf_app_session_make_req( session, NULL, method, 1, sarray );
149         string_array_destroy(sarray);
150
151         osrf_message* omsg = NULL;
152
153         growing_buffer* result_data = buffer_init(256);
154         buffer_add(result_data, "[");
155
156         /* gather result data */
157         while((omsg = osrf_app_session_request_recv( session, req_id, 60 ))) {
158
159                 if( omsg->_result_content ) {
160                         char* content = jsonObjectToJSON(omsg->_result_content);
161                         buffer_add(result_data, content);
162                         buffer_add( result_data, ",");
163                         free(content);
164
165                 } else {
166
167
168                         /* build the exception information */
169                         growing_buffer* exc_buffer = buffer_init(256);
170                         buffer_add( exc_buffer, "\nReceived Exception:\nName: " );
171                         buffer_add( exc_buffer, omsg->status_name );
172                         buffer_add( exc_buffer, "\nStatus: " );
173                         buffer_add( exc_buffer, omsg->status_text );
174                         buffer_add( exc_buffer, "\nStatus: " );
175
176                         char code[16];
177                         memset(code, 0, 16);
178                         sprintf( code, "%d", omsg->status_code );
179                         buffer_add( exc_buffer, code );
180
181                         exception = json_parse_string("{}");
182                         jsonObjectSetKey(exception, "is_err", json_parse_string("1"));
183                         jsonObjectSetKey(exception, "err_msg", jsonNewObject(exc_buffer->buf) );
184
185                         warning_handler("*** Looks like we got a "
186                                         "server exception\n%s", exc_buffer->buf );
187
188                         buffer_free(exc_buffer);
189                         osrf_message_free(omsg);
190                         break;
191                 }
192
193                 osrf_message_free(omsg);
194                 omsg = NULL;
195         }
196
197         /* remove trailing comma */
198         if( result_data->buf[strlen(result_data->buf)-1] == ',') {
199                 result_data->buf[strlen(result_data->buf)-1] = '\0';
200                 result_data->n_used--;
201         }
202
203         buffer_add(result_data,"]");
204
205         char* content = NULL;
206
207         if(exception) {
208                 content = jsonObjectToJSON(exception);
209                 jsonObjectFree(exception);
210         } 
211
212         /* set content type to text/xml for passing around XML objects */
213         ap_set_content_type(r, "text/xml");
214         if(content) { /* exception... */
215                 char* tmp = content;
216                 content = json_string_to_xml( tmp );
217                 free(tmp);
218         } else {
219                 content = json_string_to_xml( result_data->buf );
220         }
221
222         buffer_free(result_data);
223
224         if(content) {
225                 debug_handler( "APACHE writing data to web client: %s", content );
226                 ap_rputs(content,r);
227                 free(content);
228         } 
229
230         osrf_app_session_request_finish( session, req_id );
231         debug_handler("gateway process message successfully");
232
233
234         osrf_app_session_destroy(session);
235         return OK;
236
237 }
238
239 static void mod_ils_gateway_register_hooks (apr_pool_t *p) {
240         ap_hook_handler(mod_ils_gateway_method_handler, NULL, NULL, APR_HOOK_MIDDLE);
241         ap_hook_child_init(mod_ils_gateway_child_init,NULL,NULL,APR_HOOK_MIDDLE);
242 }
243
244
245 module AP_MODULE_DECLARE_DATA ils_rest_gateway_module = {
246         STANDARD20_MODULE_STUFF,
247         NULL,
248         NULL,
249         ils_gateway_create_config,
250         NULL,
251         ils_gateway_cmds,
252         mod_ils_gateway_register_hooks,
253 };
254