105 #define ENABLE_NOT_ACCEPTED 200 {
"text/vnd.wap.wml",
201 "application/vnd.wap.wmlc",
203 {
"text/vnd.wap.wmlscript",
204 "application/vnd.wap.wmlscriptc",
212 #define NUM_CONVERTERS ((long)(sizeof(converters) / sizeof(converters[0]))) 219 {
"application/vnd.wap.multipart.form-data",
220 "multipart/form-data; boundary=kannel_boundary",
228 #define NUM_DECONVERTERS ((long)(sizeof(deconverters) / sizeof(deconverters[0]))) 322 case S_MethodInvoke_Ind:
324 res->
u.S_MethodInvoke_Res.server_transaction_id =
325 ind->
u.S_MethodInvoke_Ind.server_transaction_id;
326 res->
u.S_MethodInvoke_Res.session_id =
327 ind->
u.S_MethodInvoke_Ind.session_id;
332 case S_Unit_MethodInvoke_Ind:
337 tuple = ind->
u.S_Connect_Ind.addr_tuple;
343 res->
u.S_Connect_Res.server_headers = NULL;
344 res->
u.S_Connect_Res.negotiated_capabilities =
346 res->
u.S_Connect_Res.session_id =
347 ind->
u.S_Connect_Ind.session_id;
353 case S_Disconnect_Ind:
354 sid = ind->
u.S_Disconnect_Ind.session_handle;
361 sid = ind->
u.S_Suspend_Ind.session_id;
368 sid = ind->
u.S_Resume_Ind.session_id;
373 res->
u.S_Resume_Res.server_headers = NULL;
374 res->
u.S_Resume_Res.session_id = ind->
u.S_Resume_Ind.session_id;
380 case S_MethodResult_Cnf:
384 case S_ConfirmedPush_Cnf:
389 case S_MethodAbort_Ind:
394 case S_PushAbort_Ind:
399 case Pom_Connect_Res:
405 panic(0,
"WAP-APPL: Can't handle %s event",
431 debug(
"wap.convert",0,
"WSP: Converting from <%s> to <%s>",
441 if (new_body != NULL) {
447 debug(
"wap.convert",0,
"WSP: Content-type is " 448 "now <%s>, size %ld bytes (before: %ld bytes), content body is:",
453 debug(
"wap.convert",0,
"WSP: Content convertion failed!");
458 return (failed ? -1 : 0);
475 debug(
"wap.deconvert",0,
"WSP deconvert: Trying to deconvert:");
479 debug(
"wap.deconvert",0,
"WSP: Deconverting from <%s> to <%s>",
483 if (new_body != NULL) {
489 debug(
"wap.convert",0,
"WSP: Content-type is " 490 "now <%s>, size %ld bytes (before: %ld bytes), content body is:",
495 debug(
"wap.deconvert",0,
"WSP: Content convertion failed!");
500 return (failed ? -1 : 0);
550 if (session_id != -1) {
552 sprintf(buf,
"%ld", session_id);
597 if (gateway_time == NULL) {
598 warning(0,
"Could not add X-WAP.TOD response header.");
609 Octstr *send_msisdn_header)
614 if (send_msisdn_header == NULL ||
octstr_len(send_msisdn_header) == 0)
622 warning(0,
"MSISDN header <%s> already present on request, " 687 return sm ? sm->referer_url : NULL;
700 e->
u.S_MethodResult_Req.server_transaction_id = server_transaction_id;
701 e->
u.S_MethodResult_Req.status =
status;
702 e->
u.S_MethodResult_Req.response_headers = headers;
703 e->
u.S_MethodResult_Req.response_body =
body;
704 e->
u.S_MethodResult_Req.session_id = session_id;
719 e->
u.S_Unit_MethodResult_Req.addr_tuple =
721 e->
u.S_Unit_MethodResult_Req.transaction_id = transaction_id;
722 e->
u.S_Unit_MethodResult_Req.status =
status;
723 e->
u.S_Unit_MethodResult_Req.response_headers = headers;
724 e->
u.S_Unit_MethodResult_Req.response_body =
body;
746 warning(0,
"WSP: Device doesn't support charset <%s> neither UTF-8",
749 debug(
"wsp",0,
"Converting wml/xhtml from charset <%s> to UTF-8",
765 long sdu_size,
WAPEvent *orig_event,
long session_id,
772 List *device_headers, *t_headers;
788 t_headers = (orig_event->
type == S_MethodInvoke_Ind) ?
789 orig_event->
u.S_MethodInvoke_Ind.session_headers :
792 t_headers = (orig_event->
type == S_MethodInvoke_Ind) ?
793 orig_event->
u.S_MethodInvoke_Ind.request_headers :
794 orig_event->
u.S_Unit_MethodInvoke_Ind.request_headers;
804 orig_event->
u.S_MethodInvoke_Ind.addr_tuple :
805 orig_event->
u.S_Unit_MethodInvoke_Ind.addr_tuple;
808 if (headers != NULL) {
816 alog(
"%s %s %s <%s> (%s, charset='%s') %ld %d <%s> <%s>",
831 error(0,
"WSP: HTTP lookup failed, oops.");
844 debug(
"wap.wsp",0,
"WSP: returning smart error WML deck for referer URL");
853 debug(
"wap.wsp",0,
"WSP: returning smart error WML deck for device-home URL");
856 debug(
"wap.wsp",0,
"WSP: returning smart error WML deck");
881 #ifdef ENABLE_COOKIES 882 if (session_id != -1)
884 error(0,
"WSP: Failed to extract cookies");
918 warning(0,
"WSP: All converters for `%s' at `%s' failed.",
932 debug(
"wap.wsp",0,
"WSP: returning smart error WML deck for failed converters");
940 else if (converted == 1) {
947 if (session_id != -1) {
948 debug(
"wap.wsp.http",0,
"WSP: Setting Referer URL to <%s>",
953 error(0,
"WSP: Failed to find session machine for ID %ld",
981 warning(0,
"WSP: Content type <%s> not supported by client," 999 debug(
"wsp",0,
"WSP: HEAD request, removing body, content-type is now <%s>",
1004 #ifdef ENABLE_NOT_ACCEPTED 1009 warning(0,
"WSP: content-type <%s> not supported",
1036 warning(0,
"WSP: Entity at %s too large (size %ld B, limit %lu B)",
1043 if (orig_event->
type == S_MethodInvoke_Ind) {
1048 orig_event->
u.S_Unit_MethodInvoke_Ind.transaction_id,
1097 #define HEALTH_DECK \ 1098 "<?xml version=\"1.0\"?>" \ 1099 "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD 1.1//EN\" " \ 1100 "\"http://www.wapforum.org/DTD/wml_1.1.xml\">" \ 1101 "<wml><card id=\"health\"><p>Ok</p></card></wml>" 1108 List *session_headers;
1110 List *actual_headers;
1120 Octstr *send_msisdn_query, *send_msisdn_header, *send_msisdn_format;
1126 if (
event->
type == S_MethodInvoke_Ind) {
1127 struct S_MethodInvoke_Ind *p;
1130 p = &
event->u.S_MethodInvoke_Ind;
1131 session_headers = p->session_headers;
1132 request_headers = p->request_headers;
1135 session_id = p->session_id;
1136 client_SDU_size = p->client_SDU_size;
1140 struct S_Unit_MethodInvoke_Ind *p;
1143 p = &
event->u.S_Unit_MethodInvoke_Ind;
1144 session_headers = NULL;
1145 request_headers = p->request_headers;
1149 client_SDU_size = 0;
1166 &send_msisdn_format, &accept_cookies);
1168 if (send_msisdn_header == NULL)
1169 send_msisdn_header =
octstr_create(
"X-WAP-Network-Client-MSISDN");
1173 if (session_headers != NULL)
1175 if (request_headers != NULL)
1185 #ifdef ENABLE_COOKIES 1188 if (accept_cookies != 0 && (session_id != -1) &&
1192 error(0,
"WSP: Failed to add cookies");
1230 return_reply(ret, content_body, resp_headers, client_SDU_size,
1231 event, session_id,
method,
url, x_wap_tod, actual_headers,
1246 request_body = NULL;
1276 p = gw_malloc(
sizeof(*p));
1288 request_body, 0, p, NULL);
1299 return_reply(ret, content_body, resp_headers, client_SDU_size,
1300 event, session_id,
method,
url, x_wap_tod, actual_headers,
1330 warning(0,
"WSP: WML compilation failed.");
1340 unsigned char *result_data;
1344 memset(¶ms, 0,
sizeof(params));
1356 if (compiler == NULL) {
1357 panic(0,
"WSP: could not create WMLScript compiler");
1363 &result_data, &result_size);
1364 if (result !=
WS_OK) {
1365 warning(0,
"WSP: WMLScript compilation failed: %s",
1463 List **application_headers)
1468 Octstr *appid_name, *coded_octstr;
1469 char *appid_value, *coded_value;
1473 if (*headers == NULL ||
gwlist_len(inh) == 0) {
1474 http_header_add(*application_headers,
"Accept-Application",
"wml ua");
1475 debug(
"wap.appl.push", 0,
"APPL: No push application, assuming wml" 1477 if (*headers != NULL)
1492 if (coded_value != NULL)
1493 appid_value = (
char *)wsp_application_id_to_cstr((
long) coded_value);
1495 if (appid_value != NULL && coded_value != NULL)
1499 error(0,
"OTA: Unknown application is, skipping: ");
1506 debug(
"wap.appl.push", 0,
"application headers were");
1527 unsigned char coded_value;
1529 if (*headers == NULL) {
1530 debug(
"wap.appl", 0,
"APPL: no client headers, continuing");
1537 debug(
"wap.appl.push", 0,
"APPL: No bearer indication headers," 1544 error(0,
"APPL: To many bearer indication header(s), skipping" 1555 value = (
char *)wsp_bearer_indication_to_cstr(coded_value);
1557 if (value != NULL && coded_value != 0) {
1559 debug(
"wap.appl.push", 0,
"bearer indication header was");
1563 error(0,
"APPL: Illegal bearer indication value, skipping:");
1577 if (*headers == NULL)
1592 List *push_headers, *application_headers, *bearer_headers;
1599 ppg_event->
u.Pom_Connect_Ind.addr_tuple =
1601 ppg_event->
u.Pom_Connect_Ind.requested_capabilities =
1605 ppg_event->
u.Pom_Connect_Ind.accept_application = application_headers;
1611 ppg_event->
u.Pom_Connect_Ind.bearer_indication = NULL;
1613 ppg_event->
u.Pom_Connect_Ind.bearer_indication = bearer_headers;
1615 ppg_event->
u.Pom_Connect_Ind.push_headers = push_headers;
1616 ppg_event->
u.Pom_Connect_Ind.session_id = e->
u.S_Connect_Ind.session_id;
1617 debug(
"wap.appl", 0,
"APPL: making OTA connection indication to PPG");
1628 ppg_event->
u.Pom_Disconnect_Ind.reason_code =
1629 e->
u.S_Disconnect_Ind.reason_code;
1630 ppg_event->
u.Pom_Disconnect_Ind.error_headers =
1632 ppg_event->
u.Pom_Disconnect_Ind.error_body =
1634 ppg_event->
u.Pom_Disconnect_Ind.session_handle =
1635 e->
u.S_Disconnect_Ind.session_handle;
1649 ppg_event->
u.Po_ConfirmedPush_Cnf.server_push_id =
1650 e->
u.S_ConfirmedPush_Cnf.server_push_id;
1651 ppg_event->
u.Po_ConfirmedPush_Cnf.session_handle =
1652 e->
u.S_ConfirmedPush_Cnf.session_id;
1654 debug(
"wap.appl", 0,
"OTA: confirming push for ppg");
1664 ppg_event->
u.Po_PushAbort_Ind.push_id = e->
u.S_PushAbort_Ind.push_id;
1665 ppg_event->
u.Po_PushAbort_Ind.reason = e->
u.S_PushAbort_Ind.reason;
1666 ppg_event->
u.Po_PushAbort_Ind.session_handle =
1667 e->
u.S_PushAbort_Ind.session_id;
1669 debug(
"wap.push.ota", 0,
"OTA: making push abort indication for ppg");
1679 ppg_event->
u.Pom_Suspend_Ind.reason = e->
u.S_Suspend_Ind.reason;
1680 ppg_event->
u.Pom_Suspend_Ind.session_id = e->
u.S_Suspend_Ind.session_id;
1693 List *push_headers, *bearer_headers;
1700 e->
u.S_Resume_Ind.addr_tuple);
1706 ppg_event->
u.Pom_Resume_Ind.bearer_indication = NULL;
1708 ppg_event->
u.Pom_Resume_Ind.bearer_indication = bearer_headers;
1710 ppg_event->
u.Pom_Resume_Ind.client_headers = push_headers;
1711 ppg_event->
u.Pom_Resume_Ind.session_id = e->
u.S_Resume_Ind.session_id;
1728 wsp_event->
u.S_Connect_Res.session_id = e->
u.Pom_Connect_Res.session_id;
1729 wsp_event->
u.S_Connect_Res.negotiated_capabilities =
1731 debug(
"wap.appl", 0,
"APPL: making push connect response");
int get_cookies(List *headers, const WSPMachine *sm)
static void return_replies_thread(void *)
static void indicate_push_connection(WAPEvent *e)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
Octstr * radius_acct_get_msisdn(Octstr *client_ip)
static void add_session_id(List *headers, long session_id)
Octstr * error_requesting_back(Octstr *url, Octstr *referer)
List * http_header_find_all(List *headers, char *name)
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
List * wml_charsets(void)
static void return_unit_reply(WAPAddrTuple *tuple, long transaction_id, long status, List *headers, Octstr *body)
static void add_charset_headers(List *headers)
unsigned int print_symbolic_assembler
void http_header_add(List *headers, char *name, char *contents)
static void normalize_charset(struct content *content, List *device_headers)
gw_assert(wtls_machine->packet_to_send !=NULL)
void http_caller_signal_shutdown(HTTPCaller *caller)
void counter_destroy(Counter *counter)
static void main_thread(void *)
PPGSessionMachine * wap_push_ppg_have_push_session_for(WAPAddrTuple *tuple)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
static void indicate_push_suspend(WAPEvent *e)
static void start_fetch(WAPEvent *)
void http_header_combine(List *old_headers, List *new_headers)
static void indicate_push_resume(WAPEvent *e)
static Octstr * get_referer_url(const WSPMachine *sm)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Octstr * error_converting(Octstr *url, Octstr *type)
WsCompilerPtr ws_create(WsCompilerParams *params)
static void add_via(List *headers)
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
unsigned int use_latin1_strings
static Octstr * convert_wml_to_wmlc(struct content *content)
unsigned long counter_decrease(Counter *counter)
int http_name2method(Octstr *method)
List * wsp_cap_duplicate_list(List *caps_list)
int mime_decompile(Octstr *binary_mime, Octstr **mime)
#define octstr_get_cstr(ostr)
static void indicate_push_abort(WAPEvent *e)
void gwthread_join_every(gwthread_func_t *func)
static int deconvert_content(struct content *content)
unsigned long counter_increase(Counter *counter)
void http_header_mark_transformation(List *headers, Octstr *new_body, Octstr *new_type)
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
static void add_accept_headers(List *headers)
static struct @30 converters[]
void wsp_unit_dispatch_event(WAPEvent *event)
static void add_kannel_version(List *headers)
Octstr * error_requesting(Octstr *url)
void http_destroy_headers(List *headers)
void wap_appl_shutdown(void)
static void return_reply(int status, Octstr *content_body, List *headers, long sdu_size, WAPEvent *orig_event, long session_id, Octstr *method, Octstr *url, int x_wap_tod, List *request_headers, Octstr *msisdn)
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Octstr * octstr_imm(const char *cstr)
static void add_x_wap_tod(List *headers)
Counter * counter_create(void)
WsResult ws_compile_data(WsCompilerPtr compiler, const char *input_name, const unsigned char *input, size_t input_len, unsigned char **output_return, size_t *output_len_return)
static Octstr * deconvert_multipart_formdata(struct content *content)
void gwlist_remove_producer(List *list)
static void response_push_connection(WAPEvent *e)
WSPMachine * find_session_machine_by_id(int)
static Octstr * convert_wmlscript_to_wmlscriptc(struct content *content)
List * http_create_empty_headers(void)
void wap_event_destroy_item(void *event)
static enum @29 run_status
static void add_client_sdu_size(List *headers, long sdu_size)
void http_header_pack(List *headers)
unsigned int print_assembler
#define octstr_duplicate(ostr)
#define octstr_dump(ostr, level,...)
void wap_map_user_destroy(void)
int http_status_class(int code)
const char * wap_event_name(WAPEventName type)
void * meta_name_cb_context
int wml_compile(Octstr *wml_text, Octstr *charset, Octstr **wml_binary, Octstr *version)
WsPragmaMetaProc meta_name_cb
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
#define wap_event_create(type)
void warning(int err, const char *fmt,...)
static void split_header_list(List **headers, List **new_headers, char *name)
void http_remove_hop_headers(List *headers)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
unsigned long counter_value(Counter *counter)
Octstr * get_official_name(void)
static void set_referer_url(Octstr *url, WSPMachine *sm)
static void confirm_push(WAPEvent *e)
#define http_receive_result(caller, status, final_url, headers, body)
void wap_map_destroy(void)
Octstr * http_header_value(List *headers, Octstr *name)
long octstr_len(const Octstr *ostr)
void wsp_session_dispatch_event(WAPEvent *event)
void * gwlist_consume(List *list)
static List * negotiate_capabilities(List *req_caps)
void alog(const char *fmt,...)
static int convert_content(struct content *content, List *request_headers, int allow_empty)
WsPragmaMetaProc meta_http_equiv_cb
void debug(const char *place, int err, const char *fmt,...)
const char * ws_result_to_string(WsResult result)
long wap_appl_get_load(void)
static struct @31 deconverters[]
Octstr * find_charset_encoding(Octstr *document)
void * meta_http_equiv_cb_context
int octstr_str_compare(const Octstr *ostr, const char *str)
long http_header_remove_all(List *headers, char *name)
static void return_session_reply(long server_transaction_id, long status, List *headers, Octstr *body, long session_id)
void wap_push_ppg_dispatch_event(WAPEvent *e)
HTTPCaller * http_caller_create(void)
int http_charset_accepted(List *headers, char *charset)
List * http_header_duplicate(List *headers)
int set_cookies(List *headers, WSPMachine *sm)
static void add_network_info(List *headers, WAPAddrTuple *addr_tuple)
static void dev_null(const char *data, size_t len, void *context)
void wap_appl_init(Cfg *cfg)
static void server(int lport, int pport)
Octstr * date_format_http(unsigned long unixtime)
void http_caller_destroy(HTTPCaller *caller)
static HTTPCaller * caller
static void indicate_push_disconnect(WAPEvent *e)
int http_type_accepted(List *headers, char *type)
static void add_msisdn(List *headers, WAPAddrTuple *addr_tuple, Octstr *send_msisdn_header)
void gwlist_add_producer(List *list)
static void check_application_headers(List **headers, List **app_headers)
int octstr_get_char(const Octstr *ostr, long pos)
#define octstr_create_from_data(data, len)
void http_header_dump(List *headers)
alert u SEC_Terminate_Req addr_tuple
void wap_event_destroy(WAPEvent *event)
void wap_appl_dispatch(WAPEvent *event)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
PPGSessionMachine * wap_push_ppg_have_push_session_for_sid(long sid)
static void decode_bearer_indication(List **headers, List **bearer_headers)
void wap_map_url(Octstr **osp, Octstr **send_msisdn_query, Octstr **send_msisdn_header, Octstr **send_msisdn_format, int *accept_cookies)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)