LP#1243841 - Quiet remaining Make install warnings.
[OpenSRF.git] / src / gateway / apachetools.c
1 #include "apachetools.h"
2
3 osrfStringArray* apacheParseParms(request_rec* r) {
4
5         if( r == NULL ) return NULL;
6
7         char* arg = NULL;
8         apr_pool_t *p = r->pool;        /* memory pool */
9         growing_buffer* buffer = buffer_init(1025);
10
11         /* gather the post args and append them to the url query string */
12         if( !strcmp(r->method,"POST") ) {
13
14                 ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
15                 
16                 osrfLogDebug(OSRF_LOG_MARK, "gateway reading post data..");
17
18                 if(ap_should_client_block(r)) {
19
20
21                         /* Start with url query string, if any */
22                         
23                         if(r->args && r->args[0])
24                                 buffer_add(buffer, r->args);
25
26                         char body[1025];
27
28                         osrfLogDebug(OSRF_LOG_MARK, "gateway client has post data, reading...");
29
30                         /* Append POST data */
31                         
32                         long bread;
33                         while( (bread = ap_get_client_block(r, body, sizeof(body) - 1)) ) {
34
35                                 if(bread < 0) {
36                                         osrfLogInfo(OSRF_LOG_MARK, 
37                                                 "ap_get_client_block(): returned error, exiting POST reader");
38                                         break;
39                                 }
40
41                                 body[bread] = '\0';
42                                 buffer_add( buffer, body );
43
44                                 osrfLogDebug(OSRF_LOG_MARK, 
45                                         "gateway read %ld bytes: %d bytes of data so far", bread, buffer->n_used);
46
47                                 if(buffer->n_used > APACHE_TOOLS_MAX_POST_SIZE) {
48                                         osrfLogError(OSRF_LOG_MARK, "gateway received POST larger "
49                                                 "than %d bytes. dropping request", APACHE_TOOLS_MAX_POST_SIZE);
50                                         buffer_free(buffer);
51                                         return NULL;
52                                 }
53                         }
54
55                         osrfLogDebug(OSRF_LOG_MARK, "gateway done reading post data");
56                 }
57
58         } else { /* GET */
59
60         if(r->args && r->args[0])
61             buffer_add(buffer, r->args);
62     }
63
64
65     if(buffer->n_used > 0)
66         arg = apr_pstrdup(p, buffer->buf);
67     else
68         arg = NULL; 
69     buffer_free(buffer);
70
71         if( !arg || !arg[0] ) { /* we received no request */
72                 return NULL;
73         }
74
75         osrfLogDebug(OSRF_LOG_MARK, "parsing URL params from post/get request data: %s", arg);
76         
77         osrfStringArray* sarray         = osrfNewStringArray(12); /* method parameters */
78         int sanity = 0;
79         char* key                                       = NULL; /* query item name */
80         char* val                                       = NULL; /* query item value */
81
82         /* Parse the post/get request data into a series of name/value pairs.   */
83         /* Load each name into an even-numbered slot of an osrfStringArray, and */
84         /* the corresponding value into the following odd-numbered slot.        */
85
86         while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {
87
88                 key = ap_getword(r->pool, (const char**) &val, '=');
89                 if(!key || !key[0])
90                         break;
91
92                 ap_unescape_url(key);
93                 ap_unescape_url(val);
94
95                 osrfLogDebug(OSRF_LOG_MARK, "parsed URL params %s=%s", key, val);
96
97                 osrfStringArrayAdd(sarray, key);
98                 osrfStringArrayAdd(sarray, val);
99
100                 if( sanity++ > 1000 ) {
101                         osrfLogError(OSRF_LOG_MARK, 
102                                 "Parsing URL params failed sanity check: 1000 iterations");
103                         osrfStringArrayFree(sarray);
104                         return NULL;
105                 }
106
107         }
108
109         osrfLogDebug(OSRF_LOG_MARK,
110                 "Apache tools parsed %d params key/values", sarray->size / 2 );
111
112         return sarray;
113 }
114
115
116
117 osrfStringArray* apacheGetParamKeys(osrfStringArray* params) {
118         if(params == NULL) return NULL; 
119         osrfStringArray* sarray = osrfNewStringArray(12);
120         int i;
121         osrfLogDebug(OSRF_LOG_MARK, "Fetching URL param keys");
122         for( i = 0; i < params->size; i++ ) 
123                 osrfStringArrayAdd(sarray, osrfStringArrayGetString(params, i++));
124         return sarray;
125 }
126
127 osrfStringArray* apacheGetParamValues(osrfStringArray* params, char* key) {
128
129         if(params == NULL || key == NULL) return NULL;  
130         osrfStringArray* sarray = osrfNewStringArray(12);
131
132         osrfLogDebug(OSRF_LOG_MARK, "Fetching URL values for key %s", key);
133         int i;
134         for( i = 0; i < params->size; i++ ) {
135                 const char* nkey = osrfStringArrayGetString(params, i++);
136                 if(nkey && !strcmp(nkey, key)) 
137                         osrfStringArrayAdd(sarray, osrfStringArrayGetString(params, i));
138         }
139         return sarray;
140 }
141
142
143 char* apacheGetFirstParamValue(osrfStringArray* params, char* key) {
144         if(params == NULL || key == NULL) return NULL;  
145
146         int i;
147         osrfLogDebug(OSRF_LOG_MARK, "Fetching first URL value for key %s", key);
148         for( i = 0; i < params->size; i++ ) {
149                 const char* nkey = osrfStringArrayGetString(params, i++);
150                 if(nkey && !strcmp(nkey, key)) 
151                         return strdup(osrfStringArrayGetString(params, i));
152         }
153
154         return NULL;
155 }
156
157
158 int apacheDebug( char* msg, ... ) {
159         VA_LIST_TO_STRING(msg);
160         fprintf(stderr, "%s\n", VA_BUF);
161         fflush(stderr);
162         return 0;
163 }
164
165
166 int apacheError( char* msg, ... ) {
167         VA_LIST_TO_STRING(msg);
168         fprintf(stderr, "%s\n", VA_BUF);
169         fflush(stderr);
170         return HTTP_INTERNAL_SERVER_ERROR; 
171 }
172
173 int crossOriginHeaders(request_rec* r, osrfStringArray* allowedOrigins) {
174         const char *origin = apr_table_get(r->headers_in, "Origin");
175         if (!origin)
176                 return 0;
177
178         /* remove scheme from address */
179         const char *host = origin;
180         if ( !strncmp(origin, "http://", 7) )
181                 host = origin + 7;
182         if ( !strncmp(origin, "https://", 8) )
183                 host = origin + 8;
184
185         int found = 0;
186         int i;
187         for ( i = 0; i < allowedOrigins->size; i++ ) {
188                 const char* allowedOrigin = osrfStringArrayGetString(allowedOrigins, i);
189                 if ( !strcmp(host, allowedOrigin) || !strcmp("*", allowedOrigin) ) {
190                         found = 1;
191                         break;
192                 }
193         }
194
195         if (!found)
196                 return 0;
197
198         /* allow CORS response to be cached for 24 hours */
199         apr_table_set(r->headers_out, "Access-Control-Max-Age", "86400");
200         apr_table_set(r->headers_out, "Access-Control-Allow-Credentials", "true");
201         apr_table_set(r->headers_out, "Access-Control-Allow-Origin", origin);
202         apr_table_set(r->headers_out, "Access-Control-Allow-Methods", "POST,OPTIONS");
203         apr_table_set(r->headers_out, "Access-Control-Allow-Headers", OSRF_HTTP_ALL_HEADERS);
204         apr_table_set(r->headers_out, "Access-Control-Expose-Headers", OSRF_HTTP_ALL_HEADERS);
205
206         osrfLogInfo(OSRF_LOG_MARK, "Set cross-origin headers for request from %s", origin);
207
208         return 1;
209 }
210
211
212
213 /* taken more or less directly from O'Reillly - Writing Apache Modules in Perl and C */
214 /* needs updating...
215  
216 apr_table_t* apacheParseCookies(request_rec *r) {
217
218    const char *data = apr_table_get(r->headers_in, "Cookie");
219         osrfLogDebug(OSRF_LOG_MARK, "Loaded cookies: %s", data);
220
221    apr_table_t* cookies;
222    const char *pair;
223    if(!data) return NULL;
224
225    cookies = apr_make_table(r->pool, 4);
226    while(*data && (pair = ap_getword(r->pool, &data, ';'))) {
227        const char *name, *value;
228        if(*data == ' ') ++data;
229        name = ap_getword(r->pool, &pair, '=');
230        while(*pair && (value = ap_getword(r->pool, &pair, '&'))) {
231            ap_unescape_url((char *)value);
232            apr_table_add(cookies, name, value);
233        }
234    }
235
236     return cookies;
237 }
238
239 */ 
240
241