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
24 #include <utils/linked_list.h>
28 typedef struct private_session_t private_session_t
;
31 * private data of the task manager
33 struct private_session_t
{
43 char sid
[COOKIE_LEN
* 2 + 1];
46 * have we sent the session cookie?
51 * list of controller instances controller_t
53 linked_list_t
*controllers
;
56 * list of filter instances filter_t
58 linked_list_t
*filters
;
61 * user defined session context
66 METHOD(session_t
, add_controller
, void,
67 private_session_t
*this, controller_t
*controller
)
69 this->controllers
->insert_last(this->controllers
, controller
);
72 METHOD(session_t
, add_filter
, void,
73 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)
86 memset(buf
, 0, sizeof(buf
));
87 memset(this->sid
, 0, sizeof(this->sid
));
88 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
91 rng
->get_bytes(rng
, sizeof(buf
), buf
);
94 chunk_to_hex(chunk_create(buf
, sizeof(buf
)), this->sid
, FALSE
);
98 * run all registered filters
100 static bool run_filter(private_session_t
*this, request_t
*request
, char *p0
,
101 char *p1
, char *p2
, char *p3
, char *p4
, char *p5
)
103 enumerator_t
*enumerator
;
106 enumerator
= this->filters
->create_enumerator(this->filters
);
107 while (enumerator
->enumerate(enumerator
, &filter
))
109 if (!filter
->run(filter
, request
, p0
, p1
, p2
, p3
, p4
, p5
))
111 enumerator
->destroy(enumerator
);
115 enumerator
->destroy(enumerator
);
119 METHOD(session_t
, process
, void,
120 private_session_t
*this, request_t
*request
)
122 char *pos
, *start
, *param
[6] = {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
123 enumerator_t
*enumerator
;
124 bool handled
= FALSE
;
125 controller_t
*current
;
128 if (!this->cookie_sent
)
130 request
->add_cookie(request
, "SID", this->sid
);
131 this->cookie_sent
= TRUE
;
134 start
= request
->get_path(request
);
141 while ((pos
= strchr(start
, '/')) != NULL
&& i
< 5)
143 param
[i
++] = strndupa(start
, pos
- start
);
146 param
[i
] = strdupa(start
);
148 if (run_filter(this, request
, param
[0], param
[1], param
[2], param
[3],
151 enumerator
= this->controllers
->create_enumerator(this->controllers
);
152 while (enumerator
->enumerate(enumerator
, ¤t
))
154 if (streq(current
->get_name(current
), param
[0]))
156 current
->handle(current
, request
, param
[1], param
[2],
157 param
[3], param
[4], param
[5]);
162 enumerator
->destroy(enumerator
);
171 if (this->controllers
->get_first(this->controllers
,
172 (void**)¤t
) == SUCCESS
)
174 request
->streamf(request
,
175 "Status: 301 Moved permanently\nLocation: %s/%s\n\n",
176 request
->get_base(request
), current
->get_name(current
));
181 METHOD(session_t
, get_sid
, char*,
182 private_session_t
*this)
187 METHOD(session_t
, destroy
, void,
188 private_session_t
*this)
190 this->controllers
->destroy_offset(this->controllers
, offsetof(controller_t
, destroy
));
191 this->filters
->destroy_offset(this->filters
, offsetof(filter_t
, destroy
));
192 DESTROY_IF(this->context
);
199 session_t
*session_create(context_t
*context
)
201 private_session_t
*this;
205 .add_controller
= _add_controller
,
206 .add_filter
= _add_filter
,
211 .controllers
= linked_list_create(),
212 .filters
= linked_list_create(),
217 return &this->public;