1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* Cherokee/MonetDB OSM Handler
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
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>
40 /* Plug-in initialization
42 PLUGIN_INFO_HANDLER_EASIEST_INIT (osm
, http_get
| http_put
| http_post
| http_delete
);
45 /* Methods implementation
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
));
64 cherokee_handler_osm_configure (cherokee_config_node_t
*conf
, cherokee_server_t
*srv
, cherokee_module_props_t
**_props
)
69 cherokee_handler_osm_props_t
*props
;
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
));
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
));
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
);
112 PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf
->key
.buf
);
117 ret
= handler_osm_db_connection_new(&props
->db_hostname
,
125 ret
= cherokee_list_add_content(&(props
->dbh_pool
), db_connection
);
131 cherokee_handler_osm_new (cherokee_handler_t
**hdl
, cherokee_connection_t
*cnt
, cherokee_module_props_t
*props
)
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
;
150 ret
= cherokee_buffer_init (&n
->buffer
);
151 if (unlikely(ret
!= ret_ok
))
154 ret
= cherokee_buffer_ensure_size (&n
->buffer
, 4*1024);
155 if (unlikely(ret
!= ret_ok
))
167 cherokee_handler_osm_init (cherokee_handler_osm_t
*hdl
)
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
;
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) {
191 mapi_destroy(hdl
->dbh
);
192 TRACE("sql", "Unusable\n");
196 TRACE("list", "EMPTY\n");
198 // CHEROKEE_RWLOCK_UNLOCK (OSM_LOCK(HDL_OSM_PROPS(hdl)));
200 if (ret
== ret_error
) {
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
)) {
211 conn
->error_code
= http_service_unavailable
;
212 TRACE("osm_db", "Making a new connection failed!");
219 switch (conn
->header
.method
) {
221 ret
= cherokee_handler_osm_init_get(hdl
);
226 ret
= cherokee_handler_osm_init_put(hdl
);
229 ret
= cherokee_handler_osm_init_delete(hdl
);
232 TRACE("osm", "%s did an other request\n", (conn
->realm_ref
? conn
->realm_ref
->buf
: "none"));
233 conn
->error_code
= http_bad_request
;
241 cherokee_handler_osm_free (cherokee_handler_osm_t
*hdl
)
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
);
251 if (free_connections
> 10) /* make configurable */
253 mapi_destroy(hdl
->dbh
);
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)));
264 cherokee_buffer_mrproper (&hdl
->buffer
);
270 cherokee_handler_osm_step (cherokee_handler_osm_t
*hdl
, cherokee_buffer_t
*buffer
)
274 if (cherokee_buffer_is_empty (&hdl
->buffer
))
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
;
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
);