Add an easy way to migrate to uints.
[handlerosm.git] / handler_osm.c
blob2b4ac855a8d3eea4e69af1e9e6c587a6ab03bf9e
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* Cherokee/MonetDB OSM Handler
5 * Authors:
6 * Alvaro Lopez Ortega <alvaro@alobbs.com>
7 * Stefan de Konink <handlerosm@kinkrsoftware.nl>
9 * Copyright (C) 2001-2008 Alvaro Lopez Ortega
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
26 #include <cherokee/common-internal.h>
27 #include "handler_osm.h"
28 #include "handler_osm_sql.h"
29 #include "handler_osm_db.h"
30 #include "handler_osm_get.h"
31 #include "handler_osm_put.h"
32 #include "handler_osm_delete.h"
33 #include "handler_osm_gpx.h"
34 #include <cherokee/cherokee.h>
35 #include <limits.h>
37 #include <axl.h>
38 #include <Mapi.h>
40 /* Plug-in initialization
42 PLUGIN_INFO_HANDLER_EASIEST_INIT (osm, http_get | http_put | http_post | http_delete );
45 /* Methods implementation
47 static ret_t
48 props_free (cherokee_handler_osm_props_t *props)
50 cherokee_buffer_mrproper(&props->db_hostname);
51 cherokee_buffer_mrproper(&props->db_username);
52 cherokee_buffer_mrproper(&props->db_password);
53 cherokee_buffer_mrproper(&props->db_name);
55 // CHEROKEE_RWLOCK_DESTROY (OSM_LOCK(props));
57 if (!cherokee_list_empty(&(props->dbh_pool)))
58 cherokee_list_content_free(&(props->dbh_pool), (cherokee_list_free_func) mapi_destroy);
60 return cherokee_module_props_free_base (MODULE_PROPS(props));
63 ret_t
64 cherokee_handler_osm_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props)
66 ret_t ret;
67 Mapi db_connection;
68 cherokee_list_t *i;
69 cherokee_handler_osm_props_t *props;
71 UNUSED(srv);
73 if (*_props == NULL) {
74 CHEROKEE_NEW_STRUCT (n, handler_osm_props);
75 // CHEROKEE_NEW_STRUCT(m, handler_osm_priv);
77 cherokee_module_props_init_base (MODULE_PROPS(n),
78 MODULE_PROPS_FREE(props_free));
80 n->read_only = true;
81 n->db_port = 1025;
82 cherokee_buffer_init (&n->db_hostname);
83 cherokee_buffer_init (&n->db_username);
84 cherokee_buffer_init (&n->db_password);
85 cherokee_buffer_init (&n->db_name);
87 INIT_LIST_HEAD(&(n->dbh_pool));
88 // n->priv = m;
89 // CHEROKEE_RWLOCK_INIT(OSM_LOCK(n), NULL);
91 *_props = MODULE_PROPS(n);
94 props = PROP_OSM(*_props);
96 cherokee_config_node_foreach (i, conf) {
97 cherokee_config_node_t *subconf = CONFIG_NODE(i);
99 if (equal_buf_str (&subconf->key, "db_hostname")) {
100 cherokee_buffer_add_buffer (&props->db_hostname, &subconf->val);
101 } else if (equal_buf_str (&subconf->key, "db_port")) {
102 props->db_port = atoi(subconf->val.buf);
103 } else if (equal_buf_str (&subconf->key, "db_username")) {
104 cherokee_buffer_add_buffer (&props->db_username, &subconf->val);
105 } else if (equal_buf_str (&subconf->key, "db_password")) {
106 cherokee_buffer_add_buffer (&props->db_password, &subconf->val);
107 } else if (equal_buf_str (&subconf->key, "db_name")) {
108 cherokee_buffer_add_buffer (&props->db_name, &subconf->val);
109 } else if (equal_buf_str (&subconf->key, "read_only")) {
110 props->read_only = !!atoi (subconf->val.buf);
111 } else {
112 PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf->key.buf);
113 return ret_error;
117 ret = handler_osm_db_connection_new(&props->db_hostname,
118 props->db_port,
119 &props->db_username,
120 &props->db_password,
121 &props->db_name,
122 &db_connection);
124 if (ret == ret_ok)
125 ret = cherokee_list_add_content(&(props->dbh_pool), db_connection);
127 return ret;
130 ret_t
131 cherokee_handler_osm_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props)
133 ret_t ret;
134 CHEROKEE_NEW_STRUCT (n, handler_osm);
136 /* Init the base class object
138 cherokee_handler_init_base(HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(osm));
140 MODULE(n)->init = (handler_func_init_t) cherokee_handler_osm_init;
141 MODULE(n)->free = (module_func_free_t) cherokee_handler_osm_free;
142 HANDLER(n)->step = (handler_func_step_t) cherokee_handler_osm_step;
143 HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_osm_add_headers;
145 HANDLER(n)->support = hsupport_length;
148 /* Init
150 ret = cherokee_buffer_init (&n->buffer);
151 if (unlikely(ret != ret_ok))
152 return ret;
154 ret = cherokee_buffer_ensure_size (&n->buffer, 4*1024);
155 if (unlikely(ret != ret_ok))
156 return ret;
158 if (! axl_init ())
159 return ret_error;
161 *hdl = HANDLER(n);
163 return ret_ok;
166 ret_t
167 cherokee_handler_osm_init (cherokee_handler_osm_t *hdl)
169 ret_t ret;
171 cherokee_connection_t *conn = HANDLER_CONN(hdl);
173 TRACE("auth", "User: %s", (conn->realm_ref ? conn->realm_ref->buf : "none"));
175 if (HDL_OSM_PROPS(hdl)->read_only && conn->header.method != http_get) {
176 conn->error_code = http_access_denied;
177 return ret_error;
180 ret = ret_error;
182 #ifdef pooling
183 // CHEROKEE_RWLOCK_WRITER (OSM_LOCK(HDL_OSM_PROPS(hdl)));
184 if (!cherokee_list_empty(&(HDL_OSM_PROPS(hdl)->dbh_pool))) {
185 TRACE ("list", "NOT EMPTY\n");
186 if (cherokee_list_content_free_item_ptr(HDL_OSM_PROPS(hdl)->dbh_pool.next, (void **) &(hdl->dbh)) == ret_ok) {
187 TRACE ("list", "FREE ELEMENT\n");
188 if (mapi_ping(hdl->dbh) == 0 || mapi_reconnect(hdl->dbh) == 0) {
189 ret = ret_ok;
190 } else {
191 mapi_destroy(hdl->dbh);
192 TRACE("sql", "Unusable\n");
195 } else {
196 TRACE("list", "EMPTY\n");
198 // CHEROKEE_RWLOCK_UNLOCK (OSM_LOCK(HDL_OSM_PROPS(hdl)));
200 if (ret == ret_error) {
201 ret_t ret;
202 #endif
203 ret = handler_osm_db_connection_new(&HDL_OSM_PROPS(hdl)->db_hostname,
204 HDL_OSM_PROPS(hdl)->db_port,
205 &HDL_OSM_PROPS(hdl)->db_username,
206 &HDL_OSM_PROPS(hdl)->db_password,
207 &HDL_OSM_PROPS(hdl)->db_name,
208 (void *) &(hdl->dbh));
209 if (unlikely(ret != ret_ok)) {
210 hdl->dbh = NULL;
211 conn->error_code = http_service_unavailable;
212 TRACE("osm_db", "Making a new connection failed!");
213 return ret_error;
215 #ifdef pooling
217 #endif
219 switch (conn->header.method) {
220 case http_get: {
221 ret = cherokee_handler_osm_init_get(hdl);
222 break;
224 case http_post:
225 case http_put:
226 ret = cherokee_handler_osm_init_put(hdl);
227 break;
228 case http_delete:
229 ret = cherokee_handler_osm_init_delete(hdl);
230 break;
231 default:
232 TRACE("osm", "%s did an other request\n", (conn->realm_ref ? conn->realm_ref->buf : "none"));
233 conn->error_code = http_bad_request;
234 ret = ret_error;
237 return ret;
240 ret_t
241 cherokee_handler_osm_free (cherokee_handler_osm_t *hdl)
243 #ifdef pooling
244 size_t free_connections;
246 cherokee_list_get_len (&(HDL_OSM_PROPS(hdl)->dbh_pool), &free_connections);
248 TRACE("list", "Current free connections: %d\n", free_connections);
250 if (hdl->dbh) {
251 if (free_connections > 10) /* make configurable */
252 #endif
253 mapi_destroy(hdl->dbh);
254 #ifdef pooling
255 else {
256 // CHEROKEE_RWLOCK_WRITER (OSM_LOCK(HDL_OSM_PROPS(hdl)));
257 cherokee_list_add_content(&(HDL_OSM_PROPS(hdl)->dbh_pool), (void *) hdl->dbh);
258 // CHEROKEE_RWLOCK_UNLOCK (OSM_LOCK(HDL_OSM_PROPS(hdl)));
262 #endif
264 cherokee_buffer_mrproper (&hdl->buffer);
265 axl_end();
266 return ret_ok;
269 ret_t
270 cherokee_handler_osm_step (cherokee_handler_osm_t *hdl, cherokee_buffer_t *buffer)
272 cuint_t tosend;
274 if (cherokee_buffer_is_empty (&hdl->buffer))
275 return ret_eof;
277 tosend = (hdl->buffer.len > 1024 ? 1024 : hdl->buffer.len);
279 cherokee_buffer_add (buffer, hdl->buffer.buf, tosend);
280 cherokee_buffer_move_to_begin (&hdl->buffer, tosend);
282 if (cherokee_buffer_is_empty (&hdl->buffer))
283 return ret_eof_have_data;
285 return ret_ok;
289 ret_t
290 cherokee_handler_osm_add_headers (cherokee_handler_osm_t *hdl, cherokee_buffer_t *buffer)
292 cherokee_buffer_add_str (buffer, "Content-Type: text/xml; charset=utf-8"CRLF);
293 // cherokee_buffer_add_str (buffer, "Content-Disposition: attachment; filename=\"map.osm\""CRLF);
294 cherokee_buffer_add_va (buffer, "Content-Length: %d"CRLF, hdl->buffer.len);
295 return ret_ok;