Broad patch from Dan Scott to move towards better memory management:
[OpenSRF.git] / src / gateway / apachetools.c
1 #include "apachetools.h"
2
3 string_array* apacheParseParms(request_rec* r) {
4
5         if( r == NULL ) return NULL;
6
7         char* arg = r->args;                    /* url query string */
8         apr_pool_t *p = r->pool;        /* memory pool */
9         string_array* sarray                    = init_string_array(12); /* method parameters */
10
11         growing_buffer* buffer          = NULL; /* POST data */
12         growing_buffer* tmp_buf         = NULL; /* temp buffer */
13
14         char* key                                               = NULL; /* query item name */
15         char* val                                               = NULL; /* query item value */
16
17         /* gather the post args and append them to the url query string */
18         if( !strcmp(r->method,"POST") ) {
19
20                 ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
21                 
22                 osrfLogDebug(OSRF_LOG_MARK, "gateway reading post data..");
23
24                 if(ap_should_client_block(r)) {
25
26                         char body[1025];
27                         memset(body,0,sizeof(body));
28                         buffer = buffer_init(1025);
29
30
31                         osrfLogDebug(OSRF_LOG_MARK, "gateway client has post data, reading...");
32         
33                         long bread;
34                         while( (bread = ap_get_client_block(r, body, 1024)) ) {
35
36                                 if(bread < 0) {
37                                         osrfLogInfo(OSRF_LOG_MARK, 
38                                                 "ap_get_client_block(): returned error, exiting POST reader");
39                                         break;
40                                 }
41
42                                 buffer_add( buffer, body );
43                                 memset(body,0,sizeof(body));
44
45                                 osrfLogDebug(OSRF_LOG_MARK, 
46                                         "gateway read %d bytes: %d bytes of data so far", bread, buffer->n_used);
47
48                                 if(buffer->n_used == 0) break;
49
50                                 if(buffer->n_used > APACHE_TOOLS_MAX_POST_SIZE) {
51                                         osrfLogError(OSRF_LOG_MARK, "gateway received POST larger "
52                                                 "than %d bytes. dropping request", APACHE_TOOLS_MAX_POST_SIZE);
53                                         buffer_free(buffer);
54                                         return NULL;
55                                 }
56                         }
57
58                         osrfLogDebug(OSRF_LOG_MARK, "gateway done reading post data");
59         
60                         if(arg && arg[0]) {
61
62                                 tmp_buf = buffer_init(1024);
63                                 buffer_add(tmp_buf,arg);
64                                 buffer_add(tmp_buf,buffer->buf);
65                                 arg = (char*) apr_pstrdup(p, tmp_buf->buf);
66                                 buffer_free(tmp_buf);
67
68                         } else if(buffer->n_used > 0){
69                                         arg = (char*) apr_pstrdup(p, buffer->buf);
70
71                         } else { 
72                                 arg = NULL; 
73                         }
74
75                         buffer_free(buffer);
76                 }
77         } 
78
79
80         osrfLogDebug(OSRF_LOG_MARK, "gateway done mangling post data");
81
82         if( !arg || !arg[0] ) { /* we received no request */
83                 return NULL;
84         }
85
86
87         osrfLogDebug(OSRF_LOG_MARK, "parsing URL params from post/get request data: %s", arg);
88         int sanity = 0;
89         while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {
90
91                 key = ap_getword(r->pool, (const char**) &val, '=');
92                 if(!key || !key[0])
93                         break;
94
95                 ap_unescape_url((char*)key);
96                 ap_unescape_url((char*)val);
97
98                 osrfLogDebug(OSRF_LOG_MARK, "parsed URL params %s=%s", key, val);
99
100                 string_array_add(sarray, key);
101                 string_array_add(sarray, val);
102
103                 if( sanity++ > 1000 ) {
104                         osrfLogError(OSRF_LOG_MARK, 
105                                 "Parsing URL params failed sanity check: 1000 iterations");
106                         string_array_destroy(sarray);
107                         return NULL;
108                 }
109
110         }
111
112         if(sarray)
113                 osrfLogDebug(OSRF_LOG_MARK, 
114                         "Apache tools parsed %d params key/values", sarray->size / 2 );
115
116         return sarray;
117 }
118
119
120
121 string_array* apacheGetParamKeys(string_array* params) {
122         if(params == NULL) return NULL; 
123         string_array* sarray    = init_string_array(12); 
124         int i;
125         osrfLogDebug(OSRF_LOG_MARK, "Fetching URL param keys");
126         for( i = 0; i < params->size; i++ ) 
127                 string_array_add(sarray, string_array_get_string(params, i++)); 
128         return sarray;
129 }
130
131 string_array* apacheGetParamValues(string_array* params, char* key) {
132
133         if(params == NULL || key == NULL) return NULL;  
134         string_array* sarray    = init_string_array(12); 
135
136         osrfLogDebug(OSRF_LOG_MARK, "Fetching URL values for key %s", key);
137         int i;
138         for( i = 0; i < params->size; i++ ) {
139                 char* nkey = string_array_get_string(params, i++);      
140                 if(key && !strcmp(nkey, key)) 
141                         string_array_add(sarray, string_array_get_string(params, i));   
142         }
143         return sarray;
144 }
145
146
147 char* apacheGetFirstParamValue(string_array* params, char* key) {
148         if(params == NULL || key == NULL) return NULL;  
149
150         int i;
151         osrfLogDebug(OSRF_LOG_MARK, "Fetching first URL value for key %s", key);
152         for( i = 0; i < params->size; i++ ) {
153                 char* nkey = string_array_get_string(params, i++);      
154                 if(key && !strcmp(nkey, key)) 
155                         return strdup(string_array_get_string(params, i));
156         }
157
158         return NULL;
159 }
160
161
162 int apacheDebug( char* msg, ... ) {
163         VA_LIST_TO_STRING(msg);
164         fprintf(stderr, "%s\n", VA_BUF);
165         fflush(stderr);
166         return 0;
167 }
168
169
170 int apacheError( char* msg, ... ) {
171         VA_LIST_TO_STRING(msg);
172         fprintf(stderr, "%s\n", VA_BUF);
173         fflush(stderr);
174         return HTTP_INTERNAL_SERVER_ERROR; 
175 }
176
177
178 /* taken more or less directly from O'Reillly - Writing Apache Modules in Perl and C */
179 /* needs updating...
180  
181 apr_table_t* apacheParseCookies(request_rec *r) {
182
183    const char *data = apr_table_get(r->headers_in, "Cookie");
184         osrfLogDebug(OSRF_LOG_MARK, "Loaded cookies: %s", data);
185
186    apr_table_t* cookies;
187    const char *pair;
188    if(!data) return NULL;
189
190    cookies = apr_make_table(r->pool, 4);
191    while(*data && (pair = ap_getword(r->pool, &data, ';'))) {
192        const char *name, *value;
193        if(*data == ' ') ++data;
194        name = ap_getword(r->pool, &pair, '=');
195        while(*pair && (value = ap_getword(r->pool, &pair, '&'))) {
196            ap_unescape_url((char *)value);
197            apr_table_add(cookies, name, value);
198        }
199    }
200
201     return cookies;
202 }
203
204 */ 
205
206