Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wap-appl.c File Reference
#include <string.h>
#include "gwlib/gwlib.h"
#include "wmlscript/ws.h"
#include "xml_shared.h"
#include "wml_compiler.h"
#include "mime_decompiler.h"
#include "wap/wap.h"
#include "wap-appl.h"
#include "wap_push_ppg.h"
#include "wap/wsp_strings.h"
#include "wap/wsp_caps.h"
#include "wap/wsp.h"
#include "radius/radius_acct.h"
#include "wap-error.h"
#include "wap-maps.h"

Go to the source code of this file.

Data Structures

struct  content
 
struct  request_data
 

Macros

#define ENABLE_NOT_ACCEPTED
 
#define NUM_CONVERTERS   ((long)(sizeof(converters) / sizeof(converters[0])))
 
#define NUM_DECONVERTERS   ((long)(sizeof(deconverters) / sizeof(deconverters[0])))
 
#define HEALTH_DECK
 

Enumerations

enum  { limbo, running, terminating }
 

Functions

static void main_thread (void *)
 
static void start_fetch (WAPEvent *)
 
static void return_replies_thread (void *)
 
static void dev_null (const char *data, size_t len, void *context)
 
static Octstrconvert_wml_to_wmlc (struct content *content)
 
static Octstrconvert_wmlscript_to_wmlscriptc (struct content *content)
 
static Octstrdeconvert_multipart_formdata (struct content *content)
 
static Listnegotiate_capabilities (List *req_caps)
 
static void indicate_push_connection (WAPEvent *e)
 
static void indicate_push_disconnect (WAPEvent *e)
 
static void indicate_push_suspend (WAPEvent *e)
 
static void indicate_push_resume (WAPEvent *e)
 
static void confirm_push (WAPEvent *e)
 
static void indicate_push_abort (WAPEvent *e)
 
static void split_header_list (List **headers, List **new_headers, char *name)
 
static void check_application_headers (List **headers, List **app_headers)
 
static void decode_bearer_indication (List **headers, List **bearer_headers)
 
static void response_push_connection (WAPEvent *e)
 
void wap_appl_init (Cfg *cfg)
 
void wap_appl_shutdown (void)
 
void wap_appl_dispatch (WAPEvent *event)
 
long wap_appl_get_load (void)
 
static int convert_content (struct content *content, List *request_headers, int allow_empty)
 
static int deconvert_content (struct content *content)
 
static void add_kannel_version (List *headers)
 
static void add_charset_headers (List *headers)
 
static void add_accept_headers (List *headers)
 
static void add_network_info (List *headers, WAPAddrTuple *addr_tuple)
 
static void add_session_id (List *headers, long session_id)
 
static void add_client_sdu_size (List *headers, long sdu_size)
 
static void add_via (List *headers)
 
static void add_x_wap_tod (List *headers)
 
static void add_msisdn (List *headers, WAPAddrTuple *addr_tuple, Octstr *send_msisdn_header)
 
static void set_referer_url (Octstr *url, WSPMachine *sm)
 
static Octstrget_referer_url (const WSPMachine *sm)
 
static void return_session_reply (long server_transaction_id, long status, List *headers, Octstr *body, long session_id)
 
static void return_unit_reply (WAPAddrTuple *tuple, long transaction_id, long status, List *headers, Octstr *body)
 
static void normalize_charset (struct content *content, List *device_headers)
 
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)
 

Variables

static enum { ... }  run_status = limbo
 
static Listqueue = NULL
 
static HTTPCallercaller = NULL
 
static Counterfetches = NULL
 
static Listcharsets = NULL
 
int wsp_smart_errors
 
Octstrdevice_home
 
static int have_ppg = 0
 
struct {
   char *   type
 
   char *   result_type
 
   Octstr *(*   convert )(struct content *)
 
converters []
 
struct {
   char *   type
 
   char *   result_type
 
   Octstr *(*   deconvert )(struct content *)
 
deconverters []
 

Macro Definition Documentation

#define ENABLE_NOT_ACCEPTED

Definition at line 105 of file wap-appl.c.

#define HEALTH_DECK
Value:
"<?xml version=\"1.0\"?>" \
"<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD 1.1//EN\" " \
"\"http://www.wapforum.org/DTD/wml_1.1.xml\">" \
"<wml><card id=\"health\"><p>Ok</p></card></wml>"

Definition at line 1097 of file wap-appl.c.

Referenced by start_fetch().

#define NUM_CONVERTERS   ((long)(sizeof(converters) / sizeof(converters[0])))

Definition at line 212 of file wap-appl.c.

Referenced by add_accept_headers(), and convert_content().

#define NUM_DECONVERTERS   ((long)(sizeof(deconverters) / sizeof(deconverters[0])))

Definition at line 228 of file wap-appl.c.

Referenced by deconvert_content().

Enumeration Type Documentation

anonymous enum
Enumerator
limbo 
running 
terminating 

Definition at line 117 of file wap-appl.c.

static enum @29 run_status

Function Documentation

static void add_accept_headers ( List headers)
static

Definition at line 523 of file wap-appl.c.

References converters, http_header_add(), http_type_accepted(), NUM_CONVERTERS, result_type, and type.

Referenced by start_fetch().

524 {
525  int i;
526 
527  for (i = 0; i < NUM_CONVERTERS; i++) {
528  if (http_type_accepted(headers, "*/*") || (
530  && !http_type_accepted(headers, converters[i].type))) {
531  http_header_add(headers, "Accept", converters[i].type);
532  }
533  }
534 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
static struct @30 converters[]
#define NUM_CONVERTERS
Definition: wap-appl.c:212
char * type
Definition: wap-appl.c:196
char * result_type
Definition: wap-appl.c:197
int http_type_accepted(List *headers, char *type)
Definition: http.c:3480
static void add_charset_headers ( List headers)
static

Definition at line 515 of file wap-appl.c.

References http_charset_accepted(), and http_header_add().

Referenced by start_fetch().

516 {
517  if (!http_charset_accepted(headers, "utf-8"))
518  http_header_add(headers, "Accept-Charset", "utf-8");
519 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
int http_charset_accepted(List *headers, char *charset)
Definition: http.c:3486
static void add_client_sdu_size ( List headers,
long  sdu_size 
)
static

Definition at line 559 of file wap-appl.c.

References http_header_add(), octstr_destroy(), octstr_format(), and octstr_get_cstr.

Referenced by start_fetch().

560 {
561  if (sdu_size > 0) {
562  Octstr *buf;
563 
564  buf = octstr_format("%ld", sdu_size);
565  http_header_add(headers, "X-WAP-Client-SDU-Size", octstr_get_cstr(buf));
566  octstr_destroy(buf);
567  }
568 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
static void add_kannel_version ( List headers)
static

Definition at line 505 of file wap-appl.c.

References http_header_add().

Referenced by start_fetch().

506 {
507  http_header_add(headers, "X-WAP-Gateway", GW_NAME "/" GW_VERSION);
508 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
static void add_msisdn ( List headers,
WAPAddrTuple addr_tuple,
Octstr send_msisdn_header 
)
static

Definition at line 608 of file wap-appl.c.

References WAPAddr::address, http_header_add(), http_header_remove_all(), http_header_value(), octstr_destroy(), octstr_get_cstr, octstr_len(), radius_acct_get_msisdn(), WAPAddrTuple::remote, and warning().

Referenced by start_fetch().

610 {
611  Octstr *msisdn = NULL;
612  Octstr *value = NULL;
613 
614  if (send_msisdn_header == NULL || octstr_len(send_msisdn_header) == 0)
615  return;
616 
617  /*
618  * Security considerations. If there are headers with the header name we
619  * use to pass on the MSISDN number, then remove them.
620  */
621  if ((value = http_header_value(headers, send_msisdn_header)) != NULL) {
622  warning(0, "MSISDN header <%s> already present on request, "
623  "header value=<%s>", octstr_get_cstr(send_msisdn_header),
624  octstr_get_cstr(value));
625  http_header_remove_all(headers, octstr_get_cstr(send_msisdn_header));
626  }
627 
628  /*
629  * XXX Add generic msisdn provisioning cleanly in here!
630  * See revision 1.89 for Bruno's try.
631  */
632 
633  /* We do not accept NULL values to be added to the HTTP header */
634  if ((msisdn = radius_acct_get_msisdn(addr_tuple->remote->address)) != NULL) {
635  http_header_add(headers, octstr_get_cstr(send_msisdn_header), octstr_get_cstr(msisdn));
636  }
637 
638  octstr_destroy(value);
639  octstr_destroy(msisdn);
640 }
Octstr * radius_acct_get_msisdn(Octstr *client_ip)
Definition: radius_acct.c:363
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
Octstr * address
Definition: wap_addr.h:68
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
WAPAddr * remote
Definition: wap_addr.h:74
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void add_network_info ( List headers,
WAPAddrTuple addr_tuple 
)
static

Definition at line 538 of file wap-appl.c.

References WAPAddr::address, http_header_add(), octstr_get_cstr, octstr_len(), and WAPAddrTuple::remote.

Referenced by start_fetch().

539 {
540  if (octstr_len(addr_tuple->remote->address) > 0) {
541  http_header_add(headers, "X-WAP-Network-Client-IP",
542  octstr_get_cstr(addr_tuple->remote->address));
543  }
544 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
Octstr * address
Definition: wap_addr.h:68
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
WAPAddr * remote
Definition: wap_addr.h:74
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void add_session_id ( List headers,
long  session_id 
)
static

Definition at line 548 of file wap-appl.c.

References http_header_add().

Referenced by start_fetch().

549 {
550  if (session_id != -1) {
551  char buf[40];
552  sprintf(buf, "%ld", session_id);
553  http_header_add(headers, "X-WAP-Session-ID", buf);
554  }
555 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
static void add_via ( List headers)
static

Definition at line 571 of file wap-appl.c.

References get_official_name(), http_header_add(), http_header_value(), octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_imm(), and content::version.

Referenced by start_fetch().

572 {
573  Octstr *os;
574  Octstr *version;
575 
576  version = http_header_value(headers, octstr_imm("Encoding-Version"));
577  os = octstr_format("WAP/%s %S (" GW_NAME "/%s)",
578  (version ? octstr_get_cstr(version) : "1.1"),
579  get_official_name(), GW_VERSION);
580  http_header_add(headers, "Via", octstr_get_cstr(os));
581  octstr_destroy(os);
582  octstr_destroy(version);
583 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Octstr * get_official_name(void)
Definition: socket.c:627
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
Definition: octstr.c:118
static void add_x_wap_tod ( List headers)
static

Definition at line 592 of file wap-appl.c.

References date_format_http(), http_header_add(), octstr_destroy(), octstr_get_cstr, and warning().

Referenced by return_reply().

593 {
594  Octstr *gateway_time;
595 
596  gateway_time = date_format_http(time(NULL));
597  if (gateway_time == NULL) {
598  warning(0, "Could not add X-WAP.TOD response header.");
599  return;
600  }
601 
602  http_header_add(headers, "X-WAP.TOD", octstr_get_cstr(gateway_time));
603  octstr_destroy(gateway_time);
604 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
Octstr * date_format_http(unsigned long unixtime)
Definition: date.c:89
static void check_application_headers ( List **  headers,
List **  app_headers 
)
static

Definition at line 1462 of file wap-appl.c.

References debug(), error(), GW_ERROR, gwlist_len(), http_destroy_headers(), http_header_add(), http_header_dump(), http_header_get(), octstr_destroy(), octstr_dump, octstr_get_cstr, and split_header_list().

Referenced by indicate_push_connection().

1464 {
1465  List *inh = NULL;
1466  int i;
1467  long len;
1468  Octstr *appid_name, *coded_octstr;
1469  char *appid_value, *coded_value;
1470 
1471  split_header_list(headers, &inh, "Accept-Application");
1472 
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"
1476  " ua");
1477  if (*headers != NULL)
1478  http_destroy_headers(inh);
1479  return;
1480  }
1481 
1482  i = 0;
1483  len = gwlist_len(inh);
1484  coded_value = NULL;
1485  appid_value = NULL;
1486 
1487  while (i < len) {
1488  http_header_get(inh, i, &appid_name, &coded_octstr);
1489 
1490  /* Greatest value reserved by WINA is 0xFF00 0000*/
1491  coded_value = octstr_get_cstr(coded_octstr);
1492  if (coded_value != NULL)
1493  appid_value = (char *)wsp_application_id_to_cstr((long) coded_value);
1494 
1495  if (appid_value != NULL && coded_value != NULL)
1496  http_header_add(*application_headers, "Accept-Application",
1497  appid_value);
1498  else {
1499  error(0, "OTA: Unknown application is, skipping: ");
1500  octstr_dump(coded_octstr, 0, GW_ERROR);
1501  }
1502 
1503  i++;
1504  }
1505 
1506  debug("wap.appl.push", 0, "application headers were");
1507  http_header_dump(*application_headers);
1508 
1509  http_destroy_headers(inh);
1510  octstr_destroy(appid_name);
1511  octstr_destroy(coded_octstr);
1512 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
long gwlist_len(List *list)
Definition: list.c:166
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
static void split_header_list(List **headers, List **new_headers, char *name)
Definition: wap-appl.c:1575
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: log.h:69
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Definition: list.c:102
void http_header_dump(List *headers)
Definition: http.c:3404
static void confirm_push ( WAPEvent e)
static

Definition at line 1644 of file wap-appl.c.

References debug(), WAPEvent::u, wap_event_create, and wap_push_ppg_dispatch_event().

Referenced by main_thread().

1645 {
1646  WAPEvent *ppg_event;
1647 
1648  ppg_event = wap_event_create(Po_ConfirmedPush_Cnf);
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;
1653 
1654  debug("wap.appl", 0, "OTA: confirming push for ppg");
1655  wap_push_ppg_dispatch_event(ppg_event);
1656 }
#define wap_event_create(type)
Definition: wap_events.h:107
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
union WAPEvent::@87 u
static int convert_content ( struct content content,
List request_headers,
int  allow_empty 
)
static

Definition at line 421 of file wap-appl.c.

References content::body, converters, debug(), http_type_accepted(), NUM_CONVERTERS, octstr_create, octstr_destroy(), octstr_dump, octstr_get_cstr, octstr_len(), octstr_str_compare(), result_type, and content::type.

Referenced by return_reply().

423 {
424  Octstr *new_body;
425  int failed = 0;
426  int i;
427 
428  for (i = 0; i < NUM_CONVERTERS; i++) {
429  if (octstr_str_compare(content->type, converters[i].type) == 0 &&
430  !http_type_accepted(request_headers, octstr_get_cstr(content->type))) {
431  debug("wap.convert",0,"WSP: Converting from <%s> to <%s>",
432  octstr_get_cstr(content->type), converters[i].result_type);
433  /*
434  * Note: if request is HEAD, body is empty and we still need to adapt
435  * content-type but we don't need to convert a 0 bytes body
436  */
437  if (allow_empty && octstr_len(content->body) == 0)
438  return 1;
439 
440  new_body = converters[i].convert(content);
441  if (new_body != NULL) {
442  long s = octstr_len(content->body);
443  octstr_destroy(content->body);
444  octstr_destroy(content->type);
445  content->body = new_body;
446  content->type = octstr_create(converters[i].result_type);
447  debug("wap.convert",0,"WSP: Content-type is "
448  "now <%s>, size %ld bytes (before: %ld bytes), content body is:",
449  converters[i].result_type, octstr_len(new_body), s);
450  octstr_dump(new_body, 0);
451  return 1;
452  }
453  debug("wap.convert",0,"WSP: Content convertion failed!");
454  failed = 1;
455  }
456  }
457 
458  return (failed ? -1 : 0);
459 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * body
Definition: wap-appl.c:144
static struct @30 converters[]
Octstr * type
Definition: wap-appl.c:145
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define NUM_CONVERTERS
Definition: wap-appl.c:212
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
char * result_type
Definition: wap-appl.c:197
int http_type_accepted(List *headers, char *type)
Definition: http.c:3480
static Octstr * convert_wml_to_wmlc ( struct content content)
static

Definition at line 1316 of file wap-appl.c.

References content::body, content::charset, octstr_destroy(), content::version, warning(), and wml_compile().

1317 {
1318  Octstr *wmlc;
1319  int ret;
1320 
1321  /* content->charset is passed from the HTTP header parsing */
1322  ret = wml_compile(content->body, content->charset, &wmlc,
1323  content->version);
1324 
1325  /* wmlc is created implicitely in wml_compile() */
1326  if (ret == 0)
1327  return wmlc;
1328 
1329  octstr_destroy(wmlc);
1330  warning(0, "WSP: WML compilation failed.");
1331  return NULL;
1332 }
Octstr * version
Definition: wap-appl.c:148
Octstr * body
Definition: wap-appl.c:144
int wml_compile(Octstr *wml_text, Octstr *charset, Octstr **wml_binary, Octstr *version)
Definition: wml_compiler.c:360
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
Octstr * charset
Definition: wap-appl.c:146
static Octstr * convert_wmlscript_to_wmlscriptc ( struct content content)
static

Definition at line 1335 of file wap-appl.c.

References content::body, dev_null(), WsCompilerParamsRec::meta_http_equiv_cb, WsCompilerParamsRec::meta_http_equiv_cb_context, WsCompilerParamsRec::meta_name_cb, WsCompilerParamsRec::meta_name_cb_context, octstr_create_from_data, octstr_get_cstr, octstr_len(), panic, WsCompilerParamsRec::print_assembler, WsCompilerParamsRec::print_symbolic_assembler, WsCompilerParamsRec::stderr_cb, WsCompilerParamsRec::stdout_cb, content::url, WsCompilerParamsRec::use_latin1_strings, warning(), ws_compile_data(), ws_create(), WS_OK, and ws_result_to_string().

1336 {
1337  WsCompilerParams params;
1338  WsCompilerPtr compiler;
1339  WsResult result;
1340  unsigned char *result_data;
1341  size_t result_size;
1342  Octstr *wmlscriptc;
1343 
1344  memset(&params, 0, sizeof(params));
1345  params.use_latin1_strings = 0;
1346  params.print_symbolic_assembler = 0;
1347  params.print_assembler = 0;
1348  params.meta_name_cb = NULL;
1349  params.meta_name_cb_context = NULL;
1350  params.meta_http_equiv_cb = NULL;
1351  params.meta_http_equiv_cb_context = NULL;
1352  params.stdout_cb = dev_null;
1353  params.stderr_cb = dev_null;
1354 
1355  compiler = ws_create(&params);
1356  if (compiler == NULL) {
1357  panic(0, "WSP: could not create WMLScript compiler");
1358  }
1359 
1360  result = ws_compile_data(compiler, octstr_get_cstr(content->url),
1361  (unsigned char *)octstr_get_cstr(content->body),
1362  octstr_len(content->body),
1363  &result_data, &result_size);
1364  if (result != WS_OK) {
1365  warning(0, "WSP: WMLScript compilation failed: %s",
1366  ws_result_to_string(result));
1367  wmlscriptc = NULL;
1368  } else {
1369  wmlscriptc = octstr_create_from_data((char *)result_data, result_size);
1370  }
1371 
1372  return wmlscriptc;
1373 }
unsigned int print_symbolic_assembler
Definition: ws.h:154
WsCompilerPtr ws_create(WsCompilerParams *params)
Definition: ws.c:135
unsigned int use_latin1_strings
Definition: ws.h:109
WsResult
Definition: ws.h:203
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * body
Definition: wap-appl.c:144
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)
Definition: ws.c:206
Definition: ws.h:206
unsigned int print_assembler
Definition: ws.h:157
void * meta_name_cb_context
Definition: ws.h:174
WsPragmaMetaProc meta_name_cb
Definition: ws.h:173
void warning(int err, const char *fmt,...)
Definition: log.c:624
Octstr * url
Definition: wap-appl.c:147
WsIOProc stdout_cb
Definition: ws.h:164
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
WsPragmaMetaProc meta_http_equiv_cb
Definition: ws.h:178
const char * ws_result_to_string(WsResult result)
Definition: ws.c:234
#define panic
Definition: log.h:87
void * meta_http_equiv_cb_context
Definition: ws.h:179
static void dev_null(const char *data, size_t len, void *context)
Definition: wap-appl.c:1310
WsIOProc stderr_cb
Definition: ws.h:168
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
static void decode_bearer_indication ( List **  headers,
List **  bearer_headers 
)
static

Definition at line 1522 of file wap-appl.c.

References debug(), error(), GW_ERROR, gwlist_len(), http_destroy_headers(), http_header_add(), http_header_dump(), http_header_get(), name, octstr_dump, octstr_get_char(), and split_header_list().

Referenced by indicate_push_connection(), and indicate_push_resume().

1523 {
1524  List *inb;
1525  Octstr *name, *coded_octstr;
1526  char *value;
1527  unsigned char coded_value;
1528 
1529  if (*headers == NULL) {
1530  debug("wap.appl", 0, "APPL: no client headers, continuing");
1531  return;
1532  }
1533 
1534  split_header_list(headers, &inb, "Bearer-Indication");
1535 
1536  if (gwlist_len(inb) == 0) {
1537  debug("wap.appl.push", 0, "APPL: No bearer indication headers,"
1538  " continuing");
1539  http_destroy_headers(inb);
1540  return;
1541  }
1542 
1543  if (gwlist_len(inb) > 1) {
1544  error(0, "APPL: To many bearer indication header(s), skipping"
1545  " them");
1546  http_destroy_headers(inb);
1547  return;
1548  }
1549 
1550  http_header_get(inb, 0, &name, &coded_octstr);
1551  http_destroy_headers(inb);
1552 
1553  /* Greatest assigned number for a bearer type is 0xff, see wdp, appendix C */
1554  coded_value = octstr_get_char(coded_octstr, 0);
1555  value = (char *)wsp_bearer_indication_to_cstr(coded_value);
1556 
1557  if (value != NULL && coded_value != 0) {
1558  http_header_add(*bearer_headers, "Bearer-Indication", value);
1559  debug("wap.appl.push", 0, "bearer indication header was");
1560  http_header_dump(*bearer_headers);
1561  return;
1562  } else {
1563  error(0, "APPL: Illegal bearer indication value, skipping:");
1564  octstr_dump(coded_octstr, 0, GW_ERROR);
1565  http_destroy_headers(*bearer_headers);
1566  return;
1567  }
1568 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
long gwlist_len(List *list)
Definition: list.c:166
void http_destroy_headers(List *headers)
Definition: http.c:2856
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
char * name
Definition: smsc_cimd2.c:212
static void split_header_list(List **headers, List **new_headers, char *name)
Definition: wap-appl.c:1575
Definition: log.h:69
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Definition: list.c:102
void http_header_dump(List *headers)
Definition: http.c:3404
static int deconvert_content ( struct content content)
static

Definition at line 469 of file wap-appl.c.

References content::body, debug(), deconverters, NUM_DECONVERTERS, octstr_create, octstr_destroy(), octstr_dump, octstr_get_cstr, octstr_len(), octstr_str_compare(), result_type, and content::type.

Referenced by start_fetch().

470 {
471  Octstr *new_body;
472  int failed = 0;
473  int i;
474 
475  debug("wap.deconvert",0,"WSP deconvert: Trying to deconvert:");
476  octstr_dump(content->body, 0);
477  for (i = 0; i < NUM_DECONVERTERS; i++) {
478  if (octstr_str_compare(content->type, deconverters[i].type) == 0) {
479  debug("wap.deconvert",0,"WSP: Deconverting from <%s> to <%s>",
480  octstr_get_cstr(content->type),
481  deconverters[i].result_type);
482  new_body = deconverters[i].deconvert(content);
483  if (new_body != NULL) {
484  long s = octstr_len(content->body);
485  octstr_destroy(content->body);
486  octstr_destroy(content->type);
487  content->body = new_body;
489  debug("wap.convert",0,"WSP: Content-type is "
490  "now <%s>, size %ld bytes (before: %ld bytes), content body is:",
491  deconverters[i].result_type, octstr_len(new_body), s);
492  octstr_dump(new_body, 0);
493  return 1;
494  }
495  debug("wap.deconvert",0,"WSP: Content convertion failed!");
496  failed = 1;
497  }
498  }
499 
500  return (failed ? -1 : 0);
501 }
#define NUM_DECONVERTERS
Definition: wap-appl.c:228
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * body
Definition: wap-appl.c:144
Octstr * type
Definition: wap-appl.c:145
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static struct @31 deconverters[]
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
char * result_type
Definition: wap-appl.c:197
static Octstr * deconvert_multipart_formdata ( struct content content)
static

Definition at line 1399 of file wap-appl.c.

References content::body, and mime_decompile().

1400 {
1401  Octstr *mime;
1402 
1403  if ((mime_decompile(content->body, &mime)) == 0)
1404  return mime;
1405 
1406  return NULL;
1407 }
int mime_decompile(Octstr *binary_mime, Octstr **mime)
Octstr * body
Definition: wap-appl.c:144
Definition: octstr.c:118
static void dev_null ( const char *  data,
size_t  len,
void *  context 
)
static

Definition at line 1310 of file wap-appl.c.

Referenced by convert_wmlscript_to_wmlscriptc().

1311 {
1312  /* nothing */
1313 }
static Octstr* get_referer_url ( const WSPMachine sm)
static

Definition at line 685 of file wap-appl.c.

Referenced by return_reply().

686 {
687  return sm ? sm->referer_url : NULL;
688 }
static void indicate_push_abort ( WAPEvent e)
static

Definition at line 1659 of file wap-appl.c.

References debug(), WAPEvent::u, wap_event_create, and wap_push_ppg_dispatch_event().

Referenced by main_thread().

1660 {
1661  WAPEvent *ppg_event;
1662 
1663  ppg_event = wap_event_create(Po_PushAbort_Ind);
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;
1668 
1669  debug("wap.push.ota", 0, "OTA: making push abort indication for ppg");
1670  wap_push_ppg_dispatch_event(ppg_event);
1671 }
#define wap_event_create(type)
Definition: wap_events.h:107
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
union WAPEvent::@87 u
static void indicate_push_connection ( WAPEvent e)
static

Definition at line 1589 of file wap-appl.c.

References check_application_headers(), debug(), decode_bearer_indication(), gwlist_len(), http_create_empty_headers(), http_destroy_headers(), http_header_duplicate(), WAPEvent::u, wap_addr_tuple_duplicate(), wap_event_create, wap_push_ppg_dispatch_event(), and wsp_cap_duplicate_list().

Referenced by main_thread().

1590 {
1591  WAPEvent *ppg_event;
1592  List *push_headers, *application_headers, *bearer_headers;
1593 
1594  push_headers = http_header_duplicate(e->u.S_Connect_Ind.client_headers);
1595  application_headers = http_create_empty_headers();
1596  bearer_headers = http_create_empty_headers();
1597 
1598  ppg_event = wap_event_create(Pom_Connect_Ind);
1599  ppg_event->u.Pom_Connect_Ind.addr_tuple =
1600  wap_addr_tuple_duplicate(e->u.S_Connect_Ind.addr_tuple);
1601  ppg_event->u.Pom_Connect_Ind.requested_capabilities =
1602  wsp_cap_duplicate_list(e->u.S_Connect_Ind.requested_capabilities);
1603 
1604  check_application_headers(&push_headers, &application_headers);
1605  ppg_event->u.Pom_Connect_Ind.accept_application = application_headers;
1606 
1607  decode_bearer_indication(&push_headers, &bearer_headers);
1608 
1609  if (gwlist_len(bearer_headers) == 0) {
1610  http_destroy_headers(bearer_headers);
1611  ppg_event->u.Pom_Connect_Ind.bearer_indication = NULL;
1612  } else
1613  ppg_event->u.Pom_Connect_Ind.bearer_indication = bearer_headers;
1614 
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");
1618 
1619  wap_push_ppg_dispatch_event(ppg_event);
1620 }
long gwlist_len(List *list)
Definition: list.c:166
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
void http_destroy_headers(List *headers)
Definition: http.c:2856
List * http_create_empty_headers(void)
Definition: http.c:2849
#define wap_event_create(type)
Definition: wap_events.h:107
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
static void check_application_headers(List **headers, List **app_headers)
Definition: wap-appl.c:1462
Definition: list.c:102
static void decode_bearer_indication(List **headers, List **bearer_headers)
Definition: wap-appl.c:1522
static void indicate_push_disconnect ( WAPEvent e)
static

Definition at line 1623 of file wap-appl.c.

References octstr_duplicate, WAPEvent::u, wap_event_create, and wap_push_ppg_dispatch_event().

Referenced by main_thread().

1624 {
1625  WAPEvent *ppg_event;
1626 
1627  ppg_event = wap_event_create(Pom_Disconnect_Ind);
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 =
1631  octstr_duplicate(e->u.S_Disconnect_Ind.error_headers);
1632  ppg_event->u.Pom_Disconnect_Ind.error_body =
1633  octstr_duplicate(e->u.S_Disconnect_Ind.error_body);
1634  ppg_event->u.Pom_Disconnect_Ind.session_handle =
1635  e->u.S_Disconnect_Ind.session_handle;
1636 
1637  wap_push_ppg_dispatch_event(ppg_event);
1638 }
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
union WAPEvent::@87 u
static void indicate_push_resume ( WAPEvent e)
static

Definition at line 1690 of file wap-appl.c.

References decode_bearer_indication(), gwlist_len(), http_create_empty_headers(), http_destroy_headers(), http_header_duplicate(), WAPEvent::u, wap_addr_tuple_duplicate(), wap_event_create, and wap_push_ppg_dispatch_event().

Referenced by main_thread().

1691 {
1692  WAPEvent *ppg_event;
1693  List *push_headers, *bearer_headers;
1694 
1695  push_headers = http_header_duplicate(e->u.S_Resume_Ind.client_headers);
1696  bearer_headers = http_create_empty_headers();
1697 
1698  ppg_event = wap_event_create(Pom_Resume_Ind);
1699  ppg_event->u.Pom_Resume_Ind.addr_tuple = wap_addr_tuple_duplicate(
1700  e->u.S_Resume_Ind.addr_tuple);
1701 
1702  decode_bearer_indication(&push_headers, &bearer_headers);
1703 
1704  if (gwlist_len(bearer_headers) == 0) {
1705  http_destroy_headers(bearer_headers);
1706  ppg_event->u.Pom_Resume_Ind.bearer_indication = NULL;
1707  } else
1708  ppg_event->u.Pom_Resume_Ind.bearer_indication = bearer_headers;
1709 
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;
1712 
1713  wap_push_ppg_dispatch_event(ppg_event);
1714 }
long gwlist_len(List *list)
Definition: list.c:166
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
void http_destroy_headers(List *headers)
Definition: http.c:2856
List * http_create_empty_headers(void)
Definition: http.c:2849
#define wap_event_create(type)
Definition: wap_events.h:107
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
Definition: list.c:102
static void decode_bearer_indication(List **headers, List **bearer_headers)
Definition: wap-appl.c:1522
static void indicate_push_suspend ( WAPEvent e)
static

Definition at line 1674 of file wap-appl.c.

References WAPEvent::u, wap_event_create, and wap_push_ppg_dispatch_event().

Referenced by main_thread().

1675 {
1676  WAPEvent *ppg_event;
1677 
1678  ppg_event = wap_event_create(Pom_Suspend_Ind);
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;
1681 
1682  wap_push_ppg_dispatch_event(ppg_event);
1683 }
#define wap_event_create(type)
Definition: wap_events.h:107
void wap_push_ppg_dispatch_event(WAPEvent *e)
Definition: wap_push_ppg.c:476
union WAPEvent::@87 u
static void main_thread ( void *  arg)
static

Definition at line 314 of file wap-appl.c.

References confirm_push(), gwlist_consume(), have_ppg, indicate_push_abort(), indicate_push_connection(), indicate_push_disconnect(), indicate_push_resume(), indicate_push_suspend(), negotiate_capabilities(), panic, response_push_connection(), run_status, running, start_fetch(), WAPEvent::type, WAPEvent::u, wap_event_create, wap_event_destroy(), wap_event_name(), wap_push_ppg_have_push_session_for(), wap_push_ppg_have_push_session_for_sid(), and wsp_session_dispatch_event().

Referenced by wap_appl_init(), and wap_appl_shutdown().

315 {
316  WAPEvent *ind, *res;
317  long sid;
318  WAPAddrTuple *tuple;
319 
320  while (run_status == running && (ind = gwlist_consume(queue)) != NULL) {
321  switch (ind->type) {
322  case S_MethodInvoke_Ind:
323  res = wap_event_create(S_MethodInvoke_Res);
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;
329  start_fetch(ind);
330  break;
331 
332  case S_Unit_MethodInvoke_Ind:
333  start_fetch(ind);
334  break;
335 
336  case S_Connect_Ind:
337  tuple = ind->u.S_Connect_Ind.addr_tuple;
340  } else {
341  res = wap_event_create(S_Connect_Res);
342  /* FIXME: Not yet used by WSP layer */
343  res->u.S_Connect_Res.server_headers = NULL;
344  res->u.S_Connect_Res.negotiated_capabilities =
345  negotiate_capabilities(ind->u.S_Connect_Ind.requested_capabilities);
346  res->u.S_Connect_Res.session_id =
347  ind->u.S_Connect_Ind.session_id;
349  }
350  wap_event_destroy(ind);
351  break;
352 
353  case S_Disconnect_Ind:
354  sid = ind->u.S_Disconnect_Ind.session_handle;
357  wap_event_destroy(ind);
358  break;
359 
360  case S_Suspend_Ind:
361  sid = ind->u.S_Suspend_Ind.session_id;
364  wap_event_destroy(ind);
365  break;
366 
367  case S_Resume_Ind:
368  sid = ind->u.S_Resume_Ind.session_id;
371  } else {
372  res = wap_event_create(S_Resume_Res);
373  res->u.S_Resume_Res.server_headers = NULL;
374  res->u.S_Resume_Res.session_id = ind->u.S_Resume_Ind.session_id;
376  }
377  wap_event_destroy(ind);
378  break;
379 
380  case S_MethodResult_Cnf:
381  wap_event_destroy(ind);
382  break;
383 
384  case S_ConfirmedPush_Cnf:
385  confirm_push(ind);
386  wap_event_destroy(ind);
387  break;
388 
389  case S_MethodAbort_Ind:
390  /* XXX Interrupt the fetch thread somehow */
391  wap_event_destroy(ind);
392  break;
393 
394  case S_PushAbort_Ind:
395  indicate_push_abort(ind);
396  wap_event_destroy(ind);
397  break;
398 
399  case Pom_Connect_Res:
401  wap_event_destroy(ind);
402  break;
403 
404  default:
405  panic(0, "WAP-APPL: Can't handle %s event",
406  wap_event_name(ind->type));
407  break;
408  } /* switch */
409  } /* while */
410 }
static void indicate_push_connection(WAPEvent *e)
Definition: wap-appl.c:1589
PPGSessionMachine * wap_push_ppg_have_push_session_for(WAPAddrTuple *tuple)
Definition: wap_push_ppg.c:488
static int have_ppg
Definition: wap-appl.c:176
static void indicate_push_suspend(WAPEvent *e)
Definition: wap-appl.c:1674
static void start_fetch(WAPEvent *)
Definition: wap-appl.c:1103
static void indicate_push_resume(WAPEvent *e)
Definition: wap-appl.c:1690
static void indicate_push_abort(WAPEvent *e)
Definition: wap-appl.c:1659
static void response_push_connection(WAPEvent *e)
Definition: wap-appl.c:1721
static enum @29 run_status
const char * wap_event_name(WAPEventName type)
Definition: wap_events.c:169
#define wap_event_create(type)
Definition: wap_events.h:107
static void confirm_push(WAPEvent *e)
Definition: wap-appl.c:1644
void wsp_session_dispatch_event(WAPEvent *event)
Definition: wsp_session.c:228
void * gwlist_consume(List *list)
Definition: list.c:427
static List * negotiate_capabilities(List *req_caps)
Definition: wap-appl.c:1439
#define panic
Definition: log.h:87
WAPEventName type
Definition: wap_events.h:88
static void indicate_push_disconnect(WAPEvent *e)
Definition: wap-appl.c:1623
static List * queue
Definition: wap-appl.c:123
union WAPEvent::@87 u
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
PPGSessionMachine * wap_push_ppg_have_push_session_for_sid(long sid)
Definition: wap_push_ppg.c:503
static List * negotiate_capabilities ( List req_caps)
static

Definition at line 1439 of file wap-appl.c.

References gwlist_create.

Referenced by main_thread().

1440 {
1441  /* Currently we don't know or care about any capabilities,
1442  * though it is likely that "Extended Methods" will be
1443  * the first. */
1444  return gwlist_create();
1445 }
#define gwlist_create()
Definition: list.h:136
static void normalize_charset ( struct content content,
List device_headers 
)
static

Definition at line 729 of file wap-appl.c.

References content::body, charset, content::charset, charset_convert(), debug(), find_charset_encoding(), http_charset_accepted(), octstr_case_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_len(), and warning().

Referenced by return_reply().

730 {
731  Octstr* charset;
732 
733  if ((charset = find_charset_encoding(content->body)) == NULL) {
734  if (octstr_len(content->charset) > 0) {
735  charset = octstr_duplicate(content->charset);
736  } else {
737  charset = octstr_imm("UTF-8");
738  }
739  }
740 
741  debug("wap-appl",0,"Normalizing charset from %s", octstr_get_cstr(charset));
742 
743  if (octstr_case_compare(charset, octstr_imm("UTF-8")) != 0 &&
744  !http_charset_accepted(device_headers, octstr_get_cstr(charset))) {
745  if (!http_charset_accepted(device_headers, "UTF-8")) {
746  warning(0, "WSP: Device doesn't support charset <%s> neither UTF-8",
747  octstr_get_cstr(charset));
748  } else {
749  debug("wsp",0,"Converting wml/xhtml from charset <%s> to UTF-8",
750  octstr_get_cstr(charset));
751  if (charset_convert(content->body,
752  octstr_get_cstr(charset), "UTF-8") >= 0) {
753  octstr_destroy(content->charset);
754  content->charset = octstr_create("UTF-8");
755  }
756  }
757  }
758  octstr_destroy(charset);
759 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
Octstr * body
Definition: wap-appl.c:144
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * find_charset_encoding(Octstr *document)
Definition: xml_shared.c:145
Octstr * charset
Definition: wap-appl.c:146
int http_charset_accepted(List *headers, char *charset)
Definition: http.c:3486
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
static void response_push_connection ( WAPEvent e)
static

Definition at line 1721 of file wap-appl.c.

References debug(), gw_assert(), WAPEvent::type, WAPEvent::u, wap_event_create, wsp_cap_duplicate_list(), and wsp_session_dispatch_event().

Referenced by main_thread().

1722 {
1723  WAPEvent *wsp_event;
1724 
1725  gw_assert(e->type = Pom_Connect_Res);
1726 
1727  wsp_event = wap_event_create(S_Connect_Res);
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 =
1730  wsp_cap_duplicate_list(e->u.Pom_Connect_Res.negotiated_capabilities);
1731  debug("wap.appl", 0, "APPL: making push connect response");
1732 
1733  wsp_session_dispatch_event(wsp_event);
1734 }
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
void wsp_session_dispatch_event(WAPEvent *event)
Definition: wsp_session.c:228
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static void return_replies_thread ( void *  arg)
static

Definition at line 1066 of file wap-appl.c.

References content::body, request_data::client_SDU_size, request_data::event, http_destroy_headers(), http_receive_result, request_data::method, request_data::msisdn, octstr_destroy(), request_data::request_headers, return_reply(), run_status, running, request_data::session_id, request_data::url, wap_event_destroy(), and request_data::x_wap_tod.

Referenced by wap_appl_init(), and wap_appl_shutdown().

1067 {
1068  Octstr *body;
1069  struct request_data *p;
1070  int status;
1071  Octstr *final_url;
1072  List *headers;
1073 
1074  while (run_status == running) {
1075 
1076  p = http_receive_result(caller, &status, &final_url, &headers, &body);
1077  if (p == NULL)
1078  break;
1079 
1080  return_reply(status, body, headers, p->client_SDU_size,
1081  p->event, p->session_id, p->method, p->url, p->x_wap_tod,
1082  p->request_headers, p->msisdn);
1083 
1086  octstr_destroy(p->msisdn);
1087  gw_free(p);
1088  octstr_destroy(final_url);
1089  }
1090 }
Octstr * msisdn
Definition: wap-appl.c:163
Octstr * method
Definition: wap-appl.c:159
void http_destroy_headers(List *headers)
Definition: http.c:2856
long session_id
Definition: wap-appl.c:158
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)
Definition: wap-appl.c:764
List * request_headers
Definition: wap-appl.c:162
static enum @29 run_status
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:383
Definition: octstr.c:118
long x_wap_tod
Definition: wap-appl.c:161
WAPEvent * event
Definition: wap-appl.c:157
long client_SDU_size
Definition: wap-appl.c:156
static HTTPCaller * caller
Definition: wap-appl.c:129
Octstr * url
Definition: wap-appl.c:160
Definition: list.c:102
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
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 
)
static

Definition at line 764 of file wap-appl.c.

References add_x_wap_tod(), addr_tuple, WAPAddr::address, alog(), content::body, content::charset, convert_content(), counter_decrease(), debug(), error(), error_converting(), error_requesting(), error_requesting_back(), find_session_machine_by_id(), get_cookies(), get_referer_url(), gwlist_create, HTTP_BAD_GATEWAY, http_create_empty_headers(), http_destroy_headers(), http_header_combine(), http_header_get_content_type(), http_header_mark_transformation(), http_header_remove_all(), http_header_value(), HTTP_NOT_ACCEPTABLE, HTTP_OK, http_remove_hop_headers(), http_status_class(), HTTP_STATUS_SUCCESSFUL, http_type_accepted(), normalize_charset(), octstr_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_search(), WAPAddrTuple::remote, return_session_reply(), return_unit_reply(), server(), set_referer_url(), WAPEvent::type, content::type, WAPEvent::u, url, content::url, content::version, warning(), and wsp_smart_errors.

Referenced by return_replies_thread(), and start_fetch().

768 {
769  struct content content;
770  int converted;
771  WSPMachine *sm;
772  List *device_headers, *t_headers;
774  Octstr *ua, *server;
775 
776  content.url = url;
777  content.body = content_body;
779  server = ua = NULL;
780 
781  /* Get session machine for this session. If this was a connection-less
782  * request be obviously will not find any session machine entry. */
783  sm = find_session_machine_by_id(session_id);
784 
785  device_headers = gwlist_create();
786 
787  /* ensure we pass only the original headers to the convertion routine */
788  t_headers = (orig_event->type == S_MethodInvoke_Ind) ?
789  orig_event->u.S_MethodInvoke_Ind.session_headers :
790  NULL;
791  if (t_headers != NULL) http_header_combine(device_headers, t_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;
795  if (t_headers != NULL) http_header_combine(device_headers, t_headers);
796 
797  /*
798  * We are acting as a proxy. Hence ensure we log a correct HTTP response
799  * code to our access-log file to allow identification of failed proxying
800  * requests in the main accesss-log.
801  */
802  /* get client IP and User-Agent identifier */
803  addr_tuple = (orig_event->type == S_MethodInvoke_Ind) ?
804  orig_event->u.S_MethodInvoke_Ind.addr_tuple :
805  orig_event->u.S_Unit_MethodInvoke_Ind.addr_tuple;
806  ua = http_header_value(request_headers, octstr_imm("User-Agent"));
807 
808  if (headers != NULL) {
809  /* get response content type and Server identifier */
811  server = http_header_value(headers, octstr_imm("Server"));
812  }
813 
814  /* log the access */
815  /* XXX make this configurable in the future */
816  alog("%s %s %s <%s> (%s, charset='%s') %ld %d <%s> <%s>",
817  octstr_get_cstr(addr_tuple->remote->address),
818  msisdn ? octstr_get_cstr(msisdn) : "-",
819  octstr_get_cstr(method), octstr_get_cstr(url),
823  ua ? octstr_get_cstr(ua) : "",
824  server ? octstr_get_cstr(server) : "");
825 
826  octstr_destroy(ua);
827  octstr_destroy(server);
828 
829 
830  if (status < 0) {
831  error(0, "WSP: HTTP lookup failed, oops.");
832  /* smart WSP error messaging?! */
833  if (wsp_smart_errors) {
834  Octstr *referer_url;
835  status = HTTP_OK;
836  content.type = octstr_create("text/vnd.wap.wml");
838  /*
839  * check if a referer for this URL exists and
840  * get back to the previous page in this case
841  */
842  if ((referer_url = get_referer_url(find_session_machine_by_id(session_id)))) {
843  content.body = error_requesting_back(url, referer_url);
844  debug("wap.wsp",0,"WSP: returning smart error WML deck for referer URL");
845  }
846  /*
847  * if there is no referer to retun to, check if we have a
848  * device-home defined and return to that, otherwise simply
849  * drop an error wml deck.
850  */
851  else if (device_home != NULL) {
853  debug("wap.wsp",0,"WSP: returning smart error WML deck for device-home URL");
854  } else {
856  debug("wap.wsp",0,"WSP: returning smart error WML deck");
857  }
858 
859  /*
860  * if we did not connect at all there is no content in
861  * the headers list, so create for the upcoming transformation
862  */
863  if (headers == NULL)
864  headers = http_create_empty_headers();
865 
866  converted = convert_content(&content, device_headers, 0);
867  if (converted == 1)
869 
870  } else {
871  /* no WSP smart error messaging */
872  status = HTTP_BAD_GATEWAY;
873  content.type = octstr_create("text/plain");
875  content.body = octstr_create("");
876  }
877 
878  } else {
879  /* received response by HTTP server */
880 
881 #ifdef ENABLE_COOKIES
882  if (session_id != -1)
883  if (get_cookies(headers, find_session_machine_by_id(session_id)) == -1)
884  error(0, "WSP: Failed to extract cookies");
885 #endif
886 
887  /*
888  * XXX why do we transcode charsets on the content body here?!
889  * Why is this not in the scope of the HTTP server, rather
890  * then doing this inside Kannel?! st.
891  */
892 
893  /*
894  * Adapts content body's charset to device.
895  * If device doesn't support body's charset but supports UTF-8, this
896  * block tries to convert body to UTF-8.
897  * (This is required for Sharp GX20 for example)
898  */
899  if (octstr_search(content.type, octstr_imm("text/vnd.wap.wml"), 0) >= 0 ||
900  octstr_search(content.type, octstr_imm("application/xhtml+xml"), 0) >= 0 ||
901  octstr_search(content.type, octstr_imm("application/vnd.wap.xhtml+xml"), 0) >= 0) {
902 
903  normalize_charset(&content, device_headers);
904  }
905 
906  /* set WBXML Encoding-Version for wml->wmlc conversion */
907  if (sm != NULL) {
908  content.version = http_header_value(sm->http_headers,
909  octstr_imm("Encoding-Version"));
910  } else {
911  content.version = NULL;
912  }
913 
914  /* convert content-type by our own converter table */
915  converted = convert_content(&content, device_headers,
916  octstr_compare(method, octstr_imm("HEAD")) == 0);
917  if (converted < 0) {
918  warning(0, "WSP: All converters for `%s' at `%s' failed.",
920 
921  /*
922  * Don't change status; just send the client what we did get.
923  * Or if smart error messages are configured, send a wmlc deck
924  * with accurate information.
925  */
926  if (wsp_smart_errors) {
930  content.charset = octstr_create("UTF-8");
931 
932  debug("wap.wsp",0,"WSP: returning smart error WML deck for failed converters");
933 
934  converted = convert_content(&content, device_headers, 0);
935  if (converted == 1)
937 
938  }
939  }
940  else if (converted == 1) {
942 
943  /*
944  * set referer URL to WSPMachine, but only if this was a converted
945  * content-type, like .wml
946  */
947  if (session_id != -1) {
948  debug("wap.wsp.http",0,"WSP: Setting Referer URL to <%s>",
949  octstr_get_cstr(url));
950  if ((sm = find_session_machine_by_id(session_id)) != NULL) {
951  set_referer_url(url, sm);
952  } else {
953  error(0,"WSP: Failed to find session machine for ID %ld",
954  session_id);
955  }
956  }
957  }
958 
959  /* if converted == 0 then we pass the content wihtout modification */
960  }
961 
962  if (headers == NULL)
963  headers = http_create_empty_headers();
964  http_remove_hop_headers(headers);
965  http_header_remove_all(headers, "X-WAP.TOD");
966  if (x_wap_tod)
967  add_x_wap_tod(headers);
968 
969  if (content.body == NULL)
970  content.body = octstr_create("");
971 
972  /*
973  * Deal with otherwise wap-aware servers that return text/html error
974  * messages if they report an error.
975  * (Normally we leave the content type alone even if the client doesn't
976  * claim to accept it, because the server might know better than the
977  * gateway.)
978  */
979  if (http_status_class(status) != HTTP_STATUS_SUCCESSFUL &&
980  !http_type_accepted(request_headers, octstr_get_cstr(content.type))) {
981  warning(0, "WSP: Content type <%s> not supported by client,"
982  " deleting body.", octstr_get_cstr(content.type));
984  content.body = octstr_create("");
986  content.type = octstr_create("text/plain");
988  }
989  /* remove body if request method was HEAD, we act strictly here */
990  else if (octstr_compare(method, octstr_imm("HEAD")) == 0) {
992  content.body = octstr_create("");
993  /* change to text/plain if received content-type is not accepted */
994  if (!http_type_accepted(request_headers, "*/*") &&
995  !http_type_accepted(request_headers, octstr_get_cstr(content.type))) {
997  content.type = octstr_create("text/plain");
998  }
999  debug("wsp",0,"WSP: HEAD request, removing body, content-type is now <%s>",
1002  }
1003 
1004 #ifdef ENABLE_NOT_ACCEPTED
1005  /* Returns HTTP response 406 if content-type is not supported by device */
1006  else if (request_headers && content.type &&
1007  !http_type_accepted(request_headers, octstr_get_cstr(content.type)) &&
1008  !http_type_accepted(request_headers, "*/*")) {
1009  warning(0, "WSP: content-type <%s> not supported",
1011  status = HTTP_NOT_ACCEPTABLE;
1013  content.type = octstr_create("text/plain");
1017  content.body = octstr_create("");
1019  }
1020 #endif
1021 
1022  /*
1023  * If the response is too large to be sent to the client,
1024  * suppress it and inform the client.
1025  */
1026  if (octstr_len(content.body) > sdu_size && sdu_size > 0) {
1027  /*
1028  * Only change the status if it indicated success.
1029  * If it indicated an error, then that information is
1030  * more useful to the client than our "Bad Gateway" would be.
1031  * The too-large body is probably an error page in html.
1032  */
1033  /* XXX add WSP smart messaging here too */
1035  status = HTTP_BAD_GATEWAY;
1036  warning(0, "WSP: Entity at %s too large (size %ld B, limit %lu B)",
1037  octstr_get_cstr(url), octstr_len(content.body), sdu_size);
1039  content.body = octstr_create("");
1041  }
1042 
1043  if (orig_event->type == S_MethodInvoke_Ind) {
1044  return_session_reply(orig_event->u.S_MethodInvoke_Ind.server_transaction_id,
1045  status, headers, content.body, session_id);
1046  } else {
1047  return_unit_reply(orig_event->u.S_Unit_MethodInvoke_Ind.addr_tuple,
1048  orig_event->u.S_Unit_MethodInvoke_Ind.transaction_id,
1049  status, headers, content.body);
1050  }
1051 
1052  octstr_destroy(content.version); /* body was re-used above */
1053  octstr_destroy(content.type); /* body was re-used above */
1055  octstr_destroy(url); /* same as content.url */
1056  http_destroy_headers(device_headers);
1057 
1059 }
int get_cookies(List *headers, const WSPMachine *sm)
Definition: cookies.c:111
void error(int err, const char *fmt,...)
Definition: log.c:612
Octstr * error_requesting_back(Octstr *url, Octstr *referer)
Definition: wap-error.c:67
static Counter * fetches
Definition: wap-appl.c:135
static void return_unit_reply(WAPAddrTuple *tuple, long transaction_id, long status, List *headers, Octstr *body)
Definition: wap-appl.c:713
static void normalize_charset(struct content *content, List *device_headers)
Definition: wap-appl.c:729
void http_header_combine(List *old_headers, List *new_headers)
Definition: http.c:3045
static Octstr * get_referer_url(const WSPMachine *sm)
Definition: wap-appl.c:685
Octstr * address
Definition: wap_addr.h:68
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
Octstr * error_converting(Octstr *url, Octstr *type)
Definition: wap-error.c:109
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_header_mark_transformation(List *headers, Octstr *new_body, Octstr *new_type)
Definition: http.c:3180
Octstr * version
Definition: wap-appl.c:148
Octstr * body
Definition: wap-appl.c:144
Octstr * error_requesting(Octstr *url)
Definition: wap-error.c:89
void http_destroy_headers(List *headers)
Definition: http.c:2856
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: http.h:142
static void add_x_wap_tod(List *headers)
Definition: wap-appl.c:592
Octstr * type
Definition: wap-appl.c:145
WSPMachine * find_session_machine_by_id(int)
Definition: wsp_session.c:1434
List * http_create_empty_headers(void)
Definition: http.c:2849
int http_status_class(int code)
Definition: http.c:3621
void warning(int err, const char *fmt,...)
Definition: log.c:624
void http_remove_hop_headers(List *headers)
Definition: http.c:3138
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static void set_referer_url(Octstr *url, WSPMachine *sm)
Definition: wap-appl.c:675
Octstr * url
Definition: wap-appl.c:147
WAPAddr * remote
Definition: wap_addr.h:74
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static int convert_content(struct content *content, List *request_headers, int allow_empty)
Definition: wap-appl.c:421
void alog(const char *fmt,...)
Definition: accesslog.c:206
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * charset
Definition: wap-appl.c:146
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
WAPEventName type
Definition: wap_events.h:88
int wsp_smart_errors
Definition: wapbox.c:111
static void return_session_reply(long server_transaction_id, long status, List *headers, Octstr *body, long session_id)
Definition: wap-appl.c:694
#define gwlist_create()
Definition: list.h:136
static void server(int lport, int pport)
int http_type_accepted(List *headers, char *type)
Definition: http.c:3480
union WAPEvent::@87 u
Octstr * device_home
Definition: wapbox.c:112
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
alert u SEC_Terminate_Req addr_tuple
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static void return_session_reply ( long  server_transaction_id,
long  status,
List headers,
Octstr body,
long  session_id 
)
static

Definition at line 694 of file wap-appl.c.

References content::body, WAPEvent::u, wap_event_create, and wsp_session_dispatch_event().

Referenced by return_reply().

696 {
697  WAPEvent *e;
698 
699  e = wap_event_create(S_MethodResult_Req);
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;
706 }
Octstr * body
Definition: wap-appl.c:144
#define wap_event_create(type)
Definition: wap_events.h:107
void wsp_session_dispatch_event(WAPEvent *event)
Definition: wsp_session.c:228
union WAPEvent::@87 u
static void return_unit_reply ( WAPAddrTuple tuple,
long  transaction_id,
long  status,
List headers,
Octstr body 
)
static

Definition at line 713 of file wap-appl.c.

References content::body, WAPEvent::u, wap_addr_tuple_duplicate(), wap_event_create, and wsp_unit_dispatch_event().

Referenced by return_reply().

715 {
716  WAPEvent *e;
717 
718  e = wap_event_create(S_Unit_MethodResult_Req);
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;
726 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
Octstr * body
Definition: wap-appl.c:144
void wsp_unit_dispatch_event(WAPEvent *event)
Definition: wsp_unit.c:124
#define wap_event_create(type)
Definition: wap_events.h:107
union WAPEvent::@87 u
static void set_referer_url ( Octstr url,
WSPMachine sm 
)
static

Definition at line 675 of file wap-appl.c.

References gw_assert(), octstr_destroy(), and octstr_duplicate.

Referenced by return_reply().

676 {
677  gw_assert(url != NULL);
678  gw_assert(sm != NULL);
679 
680  octstr_destroy(sm->referer_url);
681  sm->referer_url = octstr_duplicate(url);
682 }
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
static void split_header_list ( List **  headers,
List **  new_headers,
char *  name 
)
static

Definition at line 1575 of file wap-appl.c.

References http_header_find_all(), and http_header_remove_all().

Referenced by check_application_headers(), and decode_bearer_indication().

1576 {
1577  if (*headers == NULL)
1578  return;
1579 
1580  *new_headers = http_header_find_all(*headers, name);
1581  http_header_remove_all(*headers, name);
1582 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3092
char * name
Definition: smsc_cimd2.c:212
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void start_fetch ( WAPEvent event)
static

Definition at line 1103 of file wap-appl.c.

References add_accept_headers(), add_charset_headers(), add_client_sdu_size(), add_kannel_version(), add_msisdn(), add_network_info(), add_session_id(), add_via(), addr_tuple, WAPAddr::address, content::body, content::charset, request_data::client_SDU_size, counter_increase(), deconvert_content(), error(), request_data::event, find_session_machine_by_id(), gwlist_create, HEALTH_DECK, http_create_empty_headers(), http_destroy_headers(), http_header_add(), http_header_combine(), http_header_get_content_type(), http_header_mark_transformation(), http_header_pack(), http_header_remove_all(), http_name2method(), HTTP_NOT_IMPLEMENTED, HTTP_OK, http_remove_hop_headers(), http_start_request(), info(), method, request_data::method, request_data::msisdn, octstr_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_len(), octstr_str_compare(), WAPAddr::port, radius_acct_get_msisdn(), WAPAddrTuple::remote, request_data::request_headers, return_reply(), request_data::session_id, set_cookies(), WAPEvent::type, content::type, url, request_data::url, wap_event_destroy(), wap_map_url(), and request_data::x_wap_tod.

Referenced by main_thread().

1104 {
1105  int ret;
1106  long client_SDU_size; /* 0 means no limit */
1107  Octstr *url;
1108  List *session_headers;
1109  List *request_headers;
1110  List *actual_headers;
1111  List *resp_headers;
1113  long session_id;
1114  Octstr *content_body;
1115  Octstr *method; /* type of request, normally a get or a post */
1116  Octstr *request_body;
1117  int x_wap_tod; /* X-WAP.TOD header was present in request */
1118  Octstr *magic_url;
1119  struct request_data *p;
1120  Octstr *send_msisdn_query, *send_msisdn_header, *send_msisdn_format;
1121  int accept_cookies;
1122  Octstr *msisdn;
1123 
1125 
1126  if (event->type == S_MethodInvoke_Ind) {
1127  struct S_MethodInvoke_Ind *p;
1128 
1129  /* WSP, connection orientated */
1130  p = &event->u.S_MethodInvoke_Ind;
1131  session_headers = p->session_headers;
1132  request_headers = p->request_headers;
1133  url = octstr_duplicate(p->request_uri);
1134  addr_tuple = p->addr_tuple;
1135  session_id = p->session_id;
1136  client_SDU_size = p->client_SDU_size;
1137  request_body = octstr_duplicate(p->request_body);
1138  method = p->method;
1139  } else {
1140  struct S_Unit_MethodInvoke_Ind *p;
1141 
1142  /* WDP, non orientated */
1143  p = &event->u.S_Unit_MethodInvoke_Ind;
1144  session_headers = NULL;
1145  request_headers = p->request_headers;
1146  url = octstr_duplicate(p->request_uri);
1147  addr_tuple = p->addr_tuple;
1148  session_id = -1;
1149  client_SDU_size = 0; /* No limit */
1150  request_body = octstr_duplicate(p->request_body);
1151  method = p->method;
1152  }
1153 
1154  msisdn = radius_acct_get_msisdn(addr_tuple->remote->address);
1155  info(0, "Fetching URL <%s> for MSISDN <%s>, IP <%s:%ld>", octstr_get_cstr(url),
1156  msisdn ? octstr_get_cstr(msisdn) : "",
1157  addr_tuple->remote->address ? octstr_get_cstr(addr_tuple->remote->address) : "",
1158  addr_tuple->remote->port);
1159 
1160  /*
1161  * XXX this URL mapping needs to be rebuild! st.
1162  */
1163 
1164  /* try to rewrite URL */
1165  wap_map_url(&url, &send_msisdn_query, &send_msisdn_header,
1166  &send_msisdn_format, &accept_cookies);
1167  /* if no mapping found, then use our RADIUS acct proxy header */
1168  if (send_msisdn_header == NULL)
1169  send_msisdn_header = octstr_create("X-WAP-Network-Client-MSISDN");
1170 
1171  actual_headers = gwlist_create();
1172 
1173  if (session_headers != NULL)
1174  http_header_combine(actual_headers, session_headers);
1175  if (request_headers != NULL)
1176  http_header_combine(actual_headers, request_headers);
1177 
1178  x_wap_tod = http_header_remove_all(actual_headers, "X-WAP.TOD");
1179  add_accept_headers(actual_headers);
1180  add_charset_headers(actual_headers);
1181  add_network_info(actual_headers, addr_tuple);
1182  add_client_sdu_size(actual_headers, client_SDU_size);
1183  add_via(actual_headers);
1184 
1185 #ifdef ENABLE_COOKIES
1186  /* DAVI: to finish - accept_cookies -1,
1187  * use global accept-cookies, 0 = no, 1 = yes ? */
1188  if (accept_cookies != 0 && (session_id != -1) &&
1189  /* DAVI (set_cookies(url, actual_headers,
1190  find_session_machine_by_id(session_id)) == -1)) */
1191  (set_cookies(actual_headers, find_session_machine_by_id(session_id)) == -1))
1192  error(0, "WSP: Failed to add cookies");
1193 #endif
1194 
1195  /* set referer URL to HTTP header from WSPMachine */
1196  /*
1197  * XXX This makes Open Group's test suite wml/events/tasks/go/5 failing,
1198  * which requires that device is *not* sending referer, but Kannel drops
1199  * it in. We have to remove this for now.
1200  */
1201  /*
1202  if (session_id != -1) {
1203  if ((referer_url = get_referer_url(find_session_machine_by_id(session_id))) != NULL) {
1204  add_referer_url(actual_headers, referer_url);
1205  }
1206  }
1207  */
1208 
1209  add_kannel_version(actual_headers);
1210  add_session_id(actual_headers, session_id);
1211 
1212  add_msisdn(actual_headers, addr_tuple, send_msisdn_header);
1213  octstr_destroy(send_msisdn_query);
1214  octstr_destroy(send_msisdn_header);
1215  octstr_destroy(send_msisdn_format);
1216 
1217  http_remove_hop_headers(actual_headers);
1218  http_header_pack(actual_headers);
1219 
1220  magic_url = octstr_imm("kannel:alive");
1221 
1222  /* check if this request is a call for our magic URL */
1223  if (octstr_str_compare(method, "GET") == 0 &&
1224  octstr_compare(url, magic_url) == 0) {
1225  ret = HTTP_OK;
1226  resp_headers = gwlist_create();
1227  http_header_add(resp_headers, "Content-Type", "text/vnd.wap.wml");
1228  content_body = octstr_create(HEALTH_DECK);
1229  octstr_destroy(request_body);
1230  return_reply(ret, content_body, resp_headers, client_SDU_size,
1231  event, session_id, method, url, x_wap_tod, actual_headers,
1232  msisdn);
1233  wap_event_destroy(event);
1234  http_destroy_headers(actual_headers);
1235  octstr_destroy(msisdn);
1236  }
1237  /* otherwise it should be a GET, POST or HEAD request type */
1238  else if (octstr_str_compare(method, "GET") == 0 ||
1239  octstr_str_compare(method, "POST") == 0 ||
1240  octstr_str_compare(method, "HEAD") == 0) {
1241 
1242  /* we don't allow a body within a GET or HEAD request */
1243  if (request_body != NULL && (octstr_str_compare(method, "GET") == 0 ||
1244  octstr_str_compare(method, "HEAD") == 0)) {
1245  octstr_destroy(request_body);
1246  request_body = NULL;
1247  }
1248 
1249  /*
1250  * Call deconvert_content() here for transformations of binary
1251  * encoded POST requests from the client into plain text decoded
1252  * POST requests for the HTTP server.
1253  * Mainly this is used for multipart/form-data transmissions,
1254  * including MMS on-the-fly message decoding.
1255  * When we are doing mms, the phone POSTs contents and acknowled-
1256  * gements. In this case, we dont do not deconvert anything.
1257  */
1258  if (octstr_str_compare(method, "POST") == 0 && request_body &&
1259  octstr_len(request_body)) {
1260  struct content content;
1261  int converted;
1262 
1263  http_header_get_content_type(actual_headers, &content.type,
1264  &content.charset);
1265  content.body = request_body;
1266  converted = deconvert_content(&content);
1267  if (converted == 1)
1268  http_header_mark_transformation(actual_headers, content.body,
1269  content.type);
1270  request_body = content.body;
1273  }
1274 
1275  /* struct that is used for the HTTP response identifier */
1276  p = gw_malloc(sizeof(*p));
1277  p->client_SDU_size = client_SDU_size;
1278  p->event = event;
1279  p->session_id = session_id;
1280  p->method = method;
1281  p->url = url;
1282  p->x_wap_tod = x_wap_tod;
1283  p->request_headers = actual_headers;
1284  p->msisdn = msisdn;
1285 
1286  /* issue the request to the HTTP server */
1287  http_start_request(caller, http_name2method(method), url, actual_headers,
1288  request_body, 0, p, NULL);
1289 
1290  octstr_destroy(request_body);
1291  }
1292  /* we don't support the WSP/HTTP method the client asked us */
1293  else {
1294  error(0, "WSP: Method %s not supported.", octstr_get_cstr(method));
1295  content_body = octstr_create("");
1296  resp_headers = http_create_empty_headers();
1297  ret = HTTP_NOT_IMPLEMENTED;
1298  octstr_destroy(request_body);
1299  return_reply(ret, content_body, resp_headers, client_SDU_size,
1300  event, session_id, method, url, x_wap_tod, actual_headers,
1301  msisdn);
1302  wap_event_destroy(event);
1303  http_destroy_headers(actual_headers);
1304  octstr_destroy(msisdn);
1305  }
1306 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * radius_acct_get_msisdn(Octstr *client_ip)
Definition: radius_acct.c:363
static void add_session_id(List *headers, long session_id)
Definition: wap-appl.c:548
static Counter * fetches
Definition: wap-appl.c:135
static void add_charset_headers(List *headers)
Definition: wap-appl.c:515
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void http_header_combine(List *old_headers, List *new_headers)
Definition: http.c:3045
Octstr * msisdn
Definition: wap-appl.c:163
Octstr * address
Definition: wap_addr.h:68
Octstr * method
Definition: wap-appl.c:159
static void add_via(List *headers)
Definition: wap-appl.c:571
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
int http_name2method(Octstr *method)
Definition: http.c:3633
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static int deconvert_content(struct content *content)
Definition: wap-appl.c:469
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
void http_header_mark_transformation(List *headers, Octstr *new_body, Octstr *new_type)
Definition: http.c:3180
static void add_accept_headers(List *headers)
Definition: wap-appl.c:523
Octstr * body
Definition: wap-appl.c:144
static void add_kannel_version(List *headers)
Definition: wap-appl.c:505
void http_destroy_headers(List *headers)
Definition: http.c:2856
long session_id
Definition: wap-appl.c:158
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)
Definition: wap-appl.c:764
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
List * request_headers
Definition: wap-appl.c:162
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: http.h:142
#define HEALTH_DECK
Definition: wap-appl.c:1097
Octstr * type
Definition: wap-appl.c:145
WSPMachine * find_session_machine_by_id(int)
Definition: wsp_session.c:1434
List * http_create_empty_headers(void)
Definition: http.c:2849
static void add_client_sdu_size(List *headers, long sdu_size)
Definition: wap-appl.c:559
void http_header_pack(List *headers)
Definition: http.c:2969
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void http_remove_hop_headers(List *headers)
Definition: http.c:3138
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static int method
Definition: test_http.c:76
long port
Definition: wap_addr.h:70
WAPAddr * remote
Definition: wap_addr.h:74
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
long x_wap_tod
Definition: wap-appl.c:161
WAPEvent * event
Definition: wap-appl.c:157
Octstr * charset
Definition: wap-appl.c:146
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
WAPEventName type
Definition: wap_events.h:88
int set_cookies(List *headers, WSPMachine *sm)
Definition: cookies.c:162
static void add_network_info(List *headers, WAPAddrTuple *addr_tuple)
Definition: wap-appl.c:538
#define gwlist_create()
Definition: list.h:136
long client_SDU_size
Definition: wap-appl.c:156
static HTTPCaller * caller
Definition: wap-appl.c:129
Octstr * url
Definition: wap-appl.c:160
static void add_msisdn(List *headers, WAPAddrTuple *addr_tuple, Octstr *send_msisdn_header)
Definition: wap-appl.c:608
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
alert u SEC_Terminate_Req addr_tuple
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
void wap_map_url(Octstr **osp, Octstr **send_msisdn_query, Octstr **send_msisdn_header, Octstr **send_msisdn_format, int *accept_cookies)
Definition: wap-maps.c:208
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void wap_appl_dispatch ( WAPEvent event)

Definition at line 288 of file wap-appl.c.

References gw_assert(), gwlist_produce(), run_status, and running.

Referenced by main().

289 {
291  gwlist_produce(queue, event);
292 }
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static enum @29 run_status
gw_assert(wtls_machine->packet_to_send!=NULL)
static List * queue
Definition: wap-appl.c:123
long wap_appl_get_load ( void  )

Definition at line 295 of file wap-appl.c.

References counter_value(), gw_assert(), gwlist_len(), run_status, and running.

Referenced by main().

296 {
299 }
static Counter * fetches
Definition: wap-appl.c:135
long gwlist_len(List *list)
Definition: list.c:166
static enum @29 run_status
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
gw_assert(wtls_machine->packet_to_send!=NULL)
static List * queue
Definition: wap-appl.c:123
void wap_appl_init ( Cfg cfg)

Definition at line 249 of file wap-appl.c.

References counter_create(), gw_assert(), gwlist_add_producer(), gwlist_create, gwthread_create, have_ppg, http_caller_create(), limbo, main_thread(), return_replies_thread(), run_status, running, and wml_charsets().

Referenced by main().

250 {
252  queue = gwlist_create();
260 
261  if (cfg != NULL)
262  have_ppg = 1;
263  else
264  have_ppg = 0;
265 }
static void return_replies_thread(void *)
Definition: wap-appl.c:1066
static Counter * fetches
Definition: wap-appl.c:135
List * wml_charsets(void)
Definition: xml_shared.c:262
static void main_thread(void *)
Definition: wap-appl.c:314
static int have_ppg
Definition: wap-appl.c:176
Counter * counter_create(void)
Definition: counter.c:94
static enum @29 run_status
#define gwthread_create(func, arg)
Definition: gwthread.h:90
gw_assert(wtls_machine->packet_to_send!=NULL)
HTTPCaller * http_caller_create(void)
Definition: http.c:897
#define gwlist_create()
Definition: list.h:136
static HTTPCaller * caller
Definition: wap-appl.c:129
static List * queue
Definition: wap-appl.c:123
static List * charsets
Definition: wap-appl.c:141
void gwlist_add_producer(List *list)
Definition: list.c:383
void wap_appl_shutdown ( void  )

Definition at line 268 of file wap-appl.c.

References counter_destroy(), gw_assert(), gwlist_destroy(), gwlist_remove_producer(), gwthread_join_every(), http_caller_destroy(), http_caller_signal_shutdown(), main_thread(), octstr_destroy_item(), return_replies_thread(), run_status, running, terminating, wap_event_destroy_item(), wap_map_destroy(), and wap_map_user_destroy().

Referenced by main().

269 {
272 
275 
278 
279  wap_map_destroy();
285 }
static void return_replies_thread(void *)
Definition: wap-appl.c:1066
static Counter * fetches
Definition: wap-appl.c:135
void http_caller_signal_shutdown(HTTPCaller *caller)
Definition: http.c:913
void counter_destroy(Counter *counter)
Definition: counter.c:110
static void main_thread(void *)
Definition: wap-appl.c:314
void gwthread_join_every(gwthread_func_t *func)
void gwlist_remove_producer(List *list)
Definition: list.c:401
void wap_event_destroy_item(void *event)
Definition: wap_events.c:130
static enum @29 run_status
void wap_map_user_destroy(void)
Definition: wap-maps.c:174
void octstr_destroy_item(void *os)
Definition: octstr.c:334
gw_assert(wtls_machine->packet_to_send!=NULL)
void wap_map_destroy(void)
Definition: wap-maps.c:152
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
static HTTPCaller * caller
Definition: wap-appl.c:129
static List * queue
Definition: wap-appl.c:123
static List * charsets
Definition: wap-appl.c:141
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

Variable Documentation

HTTPCaller* caller = NULL
static

Definition at line 129 of file wap-appl.c.

List* charsets = NULL
static

Definition at line 141 of file wap-appl.c.

Octstr*(* convert) (struct content *)

Definition at line 198 of file wap-appl.c.

struct { ... } converters[]
Initial value:
= {
{ "text/vnd.wap.wml",
"application/vnd.wap.wmlc",
{ "text/vnd.wap.wmlscript",
"application/vnd.wap.wmlscriptc",
}
static Octstr * convert_wml_to_wmlc(struct content *content)
Definition: wap-appl.c:1316
static Octstr * convert_wmlscript_to_wmlscriptc(struct content *content)
Definition: wap-appl.c:1335

Referenced by add_accept_headers(), and convert_content().

Octstr*(* deconvert) (struct content *)

Definition at line 217 of file wap-appl.c.

struct { ... } deconverters[]
Initial value:
= {
{ "application/vnd.wap.multipart.form-data",
"multipart/form-data; boundary=kannel_boundary",
}
static Octstr * deconvert_multipart_formdata(struct content *content)
Definition: wap-appl.c:1399

Referenced by deconvert_content().

Octstr* device_home

Definition at line 112 of file wapbox.c.

Counter* fetches = NULL
static

Definition at line 135 of file wap-appl.c.

int have_ppg = 0
static

Definition at line 176 of file wap-appl.c.

Referenced by main_thread(), and wap_appl_init().

List* queue = NULL
static

Definition at line 123 of file wap-appl.c.

Referenced by main().

char* result_type

Definition at line 197 of file wap-appl.c.

Referenced by add_accept_headers(), convert_content(), and deconvert_content().

char* type

Definition at line 196 of file wap-appl.c.

Referenced by add_accept_headers().

int wsp_smart_errors

Definition at line 111 of file wapbox.c.

Referenced by config_reload(), and return_reply().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.