2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 #include <utils/linked_list.h>
27 #include <utils/randomizer.h>
29 typedef struct private_session_t private_session_t
;
32 * private data of the task manager
34 struct private_session_t
{
47 * list of controller instances controller_t
49 linked_list_t
*controllers
;
52 * list of filter instances filter_t
54 linked_list_t
*filters
;
57 * user defined session context
63 * Implementation of session_t.add_controller.
65 static void add_controller(private_session_t
*this, controller_t
*controller
)
67 this->controllers
->insert_last(this->controllers
, controller
);
71 * Implementation of session_t.add_filter.
73 static void add_filter(private_session_t
*this, filter_t
*filter
)
75 this->filters
->insert_last(this->filters
, filter
);
79 * Create a session ID and a cookie
81 static void create_sid(private_session_t
*this, request_t
*request
)
84 chunk_t chunk
= chunk_from_buf(buf
);
85 randomizer_t
*randomizer
= randomizer_create();
87 randomizer
->get_pseudo_random_bytes(randomizer
, sizeof(buf
), buf
);
88 this->sid
= chunk_to_hex(chunk
, FALSE
);
89 request
->add_cookie(request
, "SID", this->sid
);
90 randomizer
->destroy(randomizer
);
94 * run all registered filters
96 static bool run_filter(private_session_t
*this, request_t
*request
,
97 controller_t
*controller
)
102 iterator
= this->filters
->create_iterator(this->filters
, TRUE
);
103 while (iterator
->iterate(iterator
, (void**)&filter
))
105 if (!filter
->run(filter
, request
, controller
))
107 iterator
->destroy(iterator
);
111 iterator
->destroy(iterator
);
116 * Implementation of session_t.process.
118 static void process(private_session_t
*this, request_t
*request
)
120 char *pos
, *start
, *param
[6] = {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
121 iterator_t
*iterator
;
122 bool handled
= FALSE
;
123 controller_t
*current
;
126 if (this->sid
== NULL
)
128 create_sid(this, request
);
131 start
= request
->get_path(request
);
134 if (*start
== '/') start
++;
135 while ((pos
= strchr(start
, '/')) != NULL
&& i
< 5)
137 param
[i
++] = strndup(start
, pos
- start
);
140 param
[i
] = strdup(start
);
141 iterator
= this->controllers
->create_iterator(this->controllers
, TRUE
);
142 while (iterator
->iterate(iterator
, (void**)¤t
))
144 if (streq(current
->get_name(current
), param
[0]))
146 if (run_filter(this, request
, current
))
148 current
->handle(current
, request
, param
[1], param
[2],
149 param
[3], param
[4], param
[5]);
155 iterator
->destroy(iterator
);
156 for (i
= 0; i
< 6; i
++)
163 if (this->controllers
->get_first(this->controllers
,
164 (void**)¤t
) == SUCCESS
)
166 request
->redirect(request
, current
->get_name(current
));
172 * Implementation of session_t.get_sid.
174 static char* get_sid(private_session_t
*this)
180 * Implementation of session_t.destroy
182 static void destroy(private_session_t
*this)
184 this->controllers
->destroy_offset(this->controllers
, offsetof(controller_t
, destroy
));
185 this->filters
->destroy_offset(this->filters
, offsetof(filter_t
, destroy
));
186 if (this->context
) this->context
->destroy(this->context
);
194 session_t
*session_create(context_t
*context
)
196 private_session_t
*this = malloc_thing(private_session_t
);
198 this->public.add_controller
= (void(*)(session_t
*, controller_t
*))add_controller
;
199 this->public.add_filter
= (void(*)(session_t
*, filter_t
*))add_filter
;
200 this->public.process
= (void(*)(session_t
*,request_t
*))process
;
201 this->public.get_sid
= (char*(*)(session_t
*))get_sid
;
202 this->public.destroy
= (void(*)(session_t
*))destroy
;
205 this->controllers
= linked_list_create();
206 this->filters
= linked_list_create();
207 this->context
= context
;
209 return &this->public;