📄 wap-appl.c.backup
字号:
struct wsp_http_map { struct wsp_http_map *next; unsigned flags;#define WSP_HTTP_MAP_INPREFIX 0x0001 /* prefix-match incoming string */#define WSP_HTTP_MAP_OUTPREFIX 0x0002 /* prefix-replace outgoing string */#define WSP_HTTP_MAP_INOUTPREFIX 0x0003 /* combine the two for masking */ char *in; int in_len; char *out; int out_len;};static struct wsp_http_map *wsp_http_map = 0;static struct wsp_http_map *wsp_http_map_last = 0;/* * Add mapping for src URL to dst URL. */static void wsp_http_map_url_do_config(char *src, char *dst){ struct wsp_http_map *new_map; int in_len = src ? strlen(src) : 0; int out_len = dst ? strlen(dst) : 0; if (!in_len) { warning(0, "wsp_http_map_url_do_config: empty incoming string"); return; } gw_assert(in_len > 0); new_map = gw_malloc(sizeof(*new_map)); new_map->next = NULL; new_map->flags = 0; /* incoming string * later, the incoming URL will be prefix-compared to new_map->in, * using exactly new_map->in_len characters for comparison. */ new_map->in = gw_strdup(src); if (src[in_len-1] == '*') { new_map->flags |= WSP_HTTP_MAP_INPREFIX; in_len--; /* do not include `*' in comparison */ } else { in_len++; /* include \0 in comparisons */ } new_map->in_len = in_len; /* replacement string * later, when an incoming URL matches, it will be replaced * or modified according to this string. If the replacement * string ends with an asterisk, and the match string indicates * a prefix match (also ends with an asterisk), the trailing * part of the matching URL will be appended to the replacement * string, i.e. we do a prefix replacement. */ new_map->out = gw_strdup(dst); if (dst[out_len-1] == '*') { new_map->flags |= WSP_HTTP_MAP_OUTPREFIX; out_len--; /* exclude `*' */ } new_map->out_len = out_len; /* insert at tail of existing list */ if (wsp_http_map == NULL) { wsp_http_map = wsp_http_map_last = new_map; } else { wsp_http_map_last->next = new_map; wsp_http_map_last = new_map; }}/* Called during configuration read, once for each "map-url" statement. * Interprets parameter value as a space-separated two-tuple of src and dst. */void wsp_http_map_url_config(char *s){ char *in, *out; s = gw_strdup(s); in = strtok(s, " \t"); if (!in) return; out = strtok(NULL, " \t"); if (!out) return; wsp_http_map_url_do_config(in, out); gw_free(s);}/* Called during configuration read, this adds a mapping for the source URL * "DEVICE:home", to the given destination. The mapping is configured * as an in/out prefix mapping. */void wsp_http_map_url_config_device_home(char *to){ int len; char *newto = 0; if (!to) return; len = strlen(to); if (to[len] != '*') { newto = gw_malloc(len+2); strcpy(newto, to); newto[len] = '*'; newto[len+1] = '\0'; to = newto; } wsp_http_map_url_do_config("DEVICE:home*", to); if (newto) gw_free(newto);}/* show mapping list at info level, after configuration is done. */void wsp_http_map_url_config_info(void){ struct wsp_http_map *run; for (run = wsp_http_map; run; run = run->next) { char *s1 = (run->flags & WSP_HTTP_MAP_INPREFIX) ? "*" : ""; char *s2 = (run->flags & WSP_HTTP_MAP_OUTPREFIX) ? "*" : ""; info(0, "map-url %.*s%s %.*s%s", run->in_len, run->in, s1, run->out_len, run->out, s2); }}/* Search list of mappings for the given URL, returning the map structure. */static struct wsp_http_map *wsp_http_map_find(char *s){ struct wsp_http_map *run; for (run = wsp_http_map; run; run = run->next) if (0 == strncasecmp(s, run->in, run->in_len)) break; if (run) { debug("wap.wsp.http", 0, "WSP: found mapping for url <%s>", s); } return run;}/* * Maybe rewrite URL, if there is a mapping. This is where the runtime * lookup comes in (called from further down this file, wsp_http.c) */static void wsp_http_map_url(Octstr **osp){ struct wsp_http_map *map; Octstr *old = *osp; char *oldstr = octstr_get_cstr(old); map = wsp_http_map_find(oldstr); if (!map) return; *osp = octstr_create_from_data(map->out, map->out_len); /* * If both prefix flags are set, append tail of incoming URL * to outgoing URL. */ if (WSP_HTTP_MAP_INOUTPREFIX == (map->flags & WSP_HTTP_MAP_INOUTPREFIX)) octstr_append_cstr(*osp, oldstr + map->in_len); debug("wap.wsp.http", 0, "WSP: url <%s> mapped to <%s>", oldstr, octstr_get_cstr(*osp)); octstr_destroy(old);}void wsp_http_map_destroy(void) { struct wsp_http_map *p, *q; p = wsp_http_map; while (p != NULL) { q = p; if (q -> in) gw_free (q -> in); if (q -> out) gw_free (q -> out); p = q -> next; gw_free (q); }}/* * Ota submodule implements indications, responses and confirmations part of * ota. *//* * If Accept-Application is empty, add header indicating default application * wml ua (see ota 6.4.1). Otherwise decode application id (see http://www. * wapforum.org/wina/push-app-id.htm). FIXME: capability negotiation (no- * thing means default, if so negotiated). * Function does not allocate memory neither for headers nor application_ * headers. * Returns encoded application headers and input header list without them. */static void check_application_headers(List **headers, List **application_headers){ List *inh; int i; Octstr *appid_name, *coded_octstr; char *appid_value, *coded_value; split_header_list(headers, &inh, "Accept-Application"); if (*headers == NULL || list_len(inh) == 0) { http_header_add(*application_headers, "Accept-Application", "wml ua"); debug("wap.appl.push", 0, "APPL: No push application, assuming wml" " ua"); if (*headers != NULL) http_destroy_headers(inh); return; } i = 0; coded_value = NULL; appid_value = NULL; while (list_len(inh) > 0) { http_header_get(inh, i, &appid_name, &coded_octstr); /* Greatest value reserved by WINA is 0xFF00 0000*/ coded_value = octstr_get_cstr(coded_octstr); if (coded_value != NULL) appid_value = wsp_application_id_to_cstr((long) coded_value); if (appid_value != NULL && coded_value != NULL) http_header_add(*application_headers, "Accept-Application", appid_value); else { error(0, "OTA: Unknown application is, skipping: "); octstr_dump(coded_octstr, 0); } i++; } debug("wap.appl.push", 0, "application headers were"); http_header_dump(*application_headers); http_destroy_headers(inh); octstr_destroy(appid_name); octstr_destroy(coded_octstr);}/* * Bearer-Indication field is defined in ota 6.4.1. * Skip the header, if it is malformed or if there is more than one bearer * indication. * Function does not allocate memory neither for headers nor bearer_headers. * Return encoded bearer indication header and input header list without it. */static void decode_bearer_indication(List **headers, List **bearer_headers){ List *inb; Octstr *name, *coded_octstr; char *value; unsigned char coded_value; if (*headers == NULL) { debug("wap.appl", 0, "APPL: no client headers, continuing"); return; } split_header_list(headers, &inb, "Bearer-Indication"); if (list_len(inb) == 0) { debug("wap.appl.push", 0, "APPL: No bearer indication headers," " continuing"); http_destroy_headers(inb); return; } if (list_len(inb) > 1) { error(0, "APPL: To many bearer indication header(s), skipping" " them"); http_destroy_headers(inb); return; } http_header_get(inb, 0, &name, &coded_octstr); http_destroy_headers(inb); /* Greatest assigned number for a bearer type is 0xff, see wdp, appendix C */ coded_value = octstr_get_char(coded_octstr, 0); value = wsp_bearer_indication_to_cstr(coded_value); if (value != NULL && coded_value != 0) { http_header_add(*bearer_headers, "Bearer-Indication", value); debug("wap.appl.push", 0, "bearer indication header was"); http_header_dump(*bearer_headers); return; } else { error(0, "APPL: Illegal bearer indication value, skipping"); octstr_dump(coded_octstr, 0); http_destroy_headers(*bearer_headers); return; }}/* * Separate headers into two lists, one having all headers named "name" and * the other rest of them. */static void split_header_list(List **headers, List **new_headers, char *name){ if (*headers == NULL) return; *new_headers = http_header_find_all(*headers, name); http_header_remove_all(*headers, name); }/* * Find headers Accept-Application and Bearer-Indication amongst push headers, * decode them and add them to their proper field. */static void indicate_push_connection(WAPEvent *e){ WAPEvent *ppg_event; List *push_headers, *application_headers, *bearer_headers; push_headers = http_header_duplicate(e->u.S_Connect_Ind.client_headers); application_headers = http_create_empty_headers(); bearer_headers = http_create_empty_headers(); ppg_event = wap_event_create(Pom_Connect_Ind); ppg_event->u.Pom_Connect_Ind.addr_tuple = wap_addr_tuple_duplicate(e->u.S_Connect_Ind.addr_tuple); ppg_event->u.Pom_Connect_Ind.requested_capabilities = wsp_cap_duplicate_list(e->u.S_Connect_Ind.requested_capabilities); check_application_headers(&push_headers, &application_headers); ppg_event->u.Pom_Connect_Ind.accept_application = application_headers; decode_bearer_indication(&push_headers, &bearer_headers); if (list_len(bearer_headers) == 0) { http_destroy_headers(bearer_headers); ppg_event->u.Pom_Connect_Ind.bearer_indication = NULL; } else ppg_event->u.Pom_Connect_Ind.bearer_indication = bearer_headers; ppg_event->u.Pom_Connect_Ind.push_headers = push_headers; ppg_event->u.Pom_Connect_Ind.session_id = e->u.S_Connect_Ind.session_id; debug("wap.appl", 0, "APPL: making OTA connection indication to PPG"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_disconnect(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Pom_Disconnect_Ind); ppg_event->u.Pom_Disconnect_Ind.reason_code = e->u.S_Disconnect_Ind.reason_code; ppg_event->u.Pom_Disconnect_Ind.error_headers = octstr_duplicate(e->u.S_Disconnect_Ind.error_headers); ppg_event->u.Pom_Disconnect_Ind.error_body = octstr_duplicate(e->u.S_Disconnect_Ind.error_body); ppg_event->u.Pom_Disconnect_Ind.session_handle = e->u.S_Disconnect_Ind.session_handle; wap_push_ppg_dispatch_event(ppg_event);}/* * We do not implement acknowledgement headers */static void confirm_push(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Po_ConfirmedPush_Cnf); ppg_event->u.Po_ConfirmedPush_Cnf.server_push_id = e->u.S_ConfirmedPush_Cnf.server_push_id; ppg_event->u.Po_ConfirmedPush_Cnf.session_handle = e->u.S_ConfirmedPush_Cnf.session_id; debug("wap.appl", 0, "OTA: confirming push for ppg"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_abort(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Po_PushAbort_Ind); ppg_event->u.Po_PushAbort_Ind.push_id = e->u.S_PushAbort_Ind.push_id; ppg_event->u.Po_PushAbort_Ind.reason = e->u.S_PushAbort_Ind.reason; ppg_event->u.Po_PushAbort_Ind.session_handle = e->u.S_PushAbort_Ind.session_id; debug("wap.push.ota", 0, "OTA: making push abort indication for ppg"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_suspend(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Pom_Suspend_Ind); ppg_event->u.Pom_Suspend_Ind.reason = e->u.S_Suspend_Ind.reason; ppg_event->u.Pom_Suspend_Ind.session_id = e->u.S_Suspend_Ind.session_id; wap_push_ppg_dispatch_event(ppg_event);}/* * Find Bearer-Indication amongst client headers, decode it and assign it to * a separate field in the event structure. */static void indicate_push_resume(WAPEvent *e){ WAPEvent *ppg_event; List *push_headers, *bearer_headers; push_headers = http_header_duplicate(e->u.S_Resume_Ind.client_headers); bearer_headers = http_create_empty_headers(); ppg_event = wap_event_create(Pom_Resume_Ind); ppg_event->u.Pom_Resume_Ind.addr_tuple = wap_addr_tuple_duplicate( e->u.S_Resume_Ind.addr_tuple); decode_bearer_indication(&push_headers, &bearer_headers); if (list_len(bearer_headers) == 0) { http_destroy_headers(bearer_headers); ppg_event->u.Pom_Resume_Ind.bearer_indication = NULL; } else ppg_event->u.Pom_Resume_Ind.bearer_indication = bearer_headers; ppg_event->u.Pom_Resume_Ind.client_headers = push_headers; ppg_event->u.Pom_Resume_Ind.session_id = e->u.S_Resume_Ind.session_id; wap_push_ppg_dispatch_event(ppg_event);}/* * Server headers are mentioned in table in ota 6.4.1, but none of the primit- * ives use them. They are optional in S_Connect_Res, so we do not use them. */static void response_push_connection(WAPEvent *e){ WAPEvent *wsp_event; gw_assert(e->type = Pom_Connect_Res); wsp_event = wap_event_create(S_Connect_Res); wsp_event->u.S_Connect_Res.session_id = e->u.Pom_Connect_Res.session_id; wsp_event->u.S_Connect_Res.negotiated_capabilities = wsp_cap_duplicate_list(e->u.Pom_Connect_Res.negotiated_capabilities); debug("wap.appl", 0, "APPL: making push connect response"); wsp_session_dispatch_event(wsp_event);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -