Kannel: Open Source WAP and SMS gateway  svn-r5335
wsp_headers.h File Reference
#include "gwlib/gwlib.h"

Go to the source code of this file.

Data Structures

struct  parameter
 
struct  headerinfo
 

Macros

#define WSP_FIELD_VALUE_NUL_STRING   1
 
#define WSP_FIELD_VALUE_ENCODED   2
 
#define WSP_FIELD_VALUE_DATA   3
 
#define WSP_FIELD_VALUE_NONE   4 /* secondary_field_value only */
 
#define WSP_QUOTE   127
 
#define MAX_SHORT_INTEGER   127
 
#define BASIC_AUTHENTICATION   128
 
#define ABSOLUTE_TIME   128
 
#define RELATIVE_TIME   129
 
#define BYTE_RANGE   128
 
#define SUFFIX_BYTE_RANGE   129
 
#define LONG_AGO_VALUE   100000
 
#define LIST   1
 
#define BROKEN_LIST   2
 
#define TABLE_SIZE(table)   ((long)(sizeof(table) / sizeof(table[0])))
 

Typedefs

typedef struct parameter Parameter
 
typedef int header_pack_func_t(Octstr *packed, Octstr *value)
 

Functions

int wsp_field_value (ParseContext *context, int *well_known_value)
 
void wsp_skip_field_value (ParseContext *context)
 
int wsp_secondary_field_value (ParseContext *context, long *result)
 
void parm_destroy_item (void *parm)
 
Listwsp_strip_parameters (Octstr *value)
 
Octstrwsp_unpack_integer_value (ParseContext *context)
 
Octstrwsp_unpack_version_value (long value)
 
void wsp_unpack_all_parameters (ParseContext *context, Octstr *decoded)
 
Octstrwsp_unpack_date_value (ParseContext *context)
 
void wsp_unpack_well_known_field (List *unpacked, int field_type, ParseContext *context)
 
void wsp_unpack_app_header (List *unpacked, ParseContext *context)
 
void wsp_pack_integer_value (Octstr *packed, unsigned long integer)
 
int wsp_pack_date (Octstr *packet, Octstr *value)
 
int wsp_pack_retry_after (Octstr *packet, Octstr *value)
 
int wsp_pack_text (Octstr *packet, Octstr *value)
 
int wsp_pack_quoted_text (Octstr *packed, Octstr *text)
 
int wsp_pack_integer_string (Octstr *packet, Octstr *value)
 
int wsp_pack_version_value (Octstr *packet, Octstr *value)
 
int wsp_pack_constrained_value (Octstr *packed, Octstr *text, long value)
 
void wsp_pack_value (Octstr *packed, Octstr *encoded)
 
void wsp_pack_parameters (Octstr *packed, List *parms)
 
int wsp_pack_list (Octstr *packed, long fieldnum, List *elements, int i)
 
void wsp_pack_short_integer (Octstr *packed, unsigned long integer)
 
void wsp_pack_separate_content_type (Octstr *packed, List *headers)
 
Octstrwsp_unpack_accept_general_form (ParseContext *context)
 
Octstrwsp_unpack_accept_charset_general_form (ParseContext *context)
 
int wsp_pack_content_type (Octstr *packet, Octstr *value)
 
int wsp_pack_application_header (Octstr *packed, Octstr *fieldname, Octstr *value)
 
void wsp_pack_long_integer (Octstr *packed, unsigned long integer)
 
Listwsp_headers_unpack (Octstr *headers, int content_type)
 
Octstrwsp_headers_pack (List *headers, int separate_content_type, int wsp_version)
 

Macro Definition Documentation

◆ ABSOLUTE_TIME

#define ABSOLUTE_TIME   128

Definition at line 81 of file wsp_headers.h.

Referenced by unpack_retry_after(), and wsp_pack_retry_after().

◆ BASIC_AUTHENTICATION

#define BASIC_AUTHENTICATION   128

◆ BROKEN_LIST

#define BROKEN_LIST   2

Definition at line 100 of file wsp_headers.h.

Referenced by pack_known_header().

◆ BYTE_RANGE

#define BYTE_RANGE   128

Definition at line 83 of file wsp_headers.h.

Referenced by pack_range_value(), and unpack_range_value().

◆ LIST

#define LIST   1

Definition at line 94 of file wsp_headers.h.

Referenced by pack_known_header().

◆ LONG_AGO_VALUE

#define LONG_AGO_VALUE   100000

Definition at line 90 of file wsp_headers.h.

Referenced by pack_expires().

◆ MAX_SHORT_INTEGER

◆ RELATIVE_TIME

#define RELATIVE_TIME   129

Definition at line 82 of file wsp_headers.h.

Referenced by unpack_retry_after(), and wsp_pack_retry_after().

◆ SUFFIX_BYTE_RANGE

#define SUFFIX_BYTE_RANGE   129

Definition at line 84 of file wsp_headers.h.

Referenced by pack_range_value(), and unpack_range_value().

◆ TABLE_SIZE

#define TABLE_SIZE (   table)    ((long)(sizeof(table) / sizeof(table[0])))

Definition at line 102 of file wsp_headers.h.

Referenced by pack_known_header().

◆ WSP_FIELD_VALUE_DATA

#define WSP_FIELD_VALUE_DATA   3

◆ WSP_FIELD_VALUE_ENCODED

◆ WSP_FIELD_VALUE_NONE

#define WSP_FIELD_VALUE_NONE   4 /* secondary_field_value only */

◆ WSP_FIELD_VALUE_NUL_STRING

◆ WSP_QUOTE

#define WSP_QUOTE   127

Typedef Documentation

◆ header_pack_func_t

typedef int header_pack_func_t(Octstr *packed, Octstr *value)

Definition at line 111 of file wsp_headers.h.

◆ Parameter

typedef struct parameter Parameter

Definition at line 109 of file wsp_headers.h.

Function Documentation

◆ parm_destroy_item()

void parm_destroy_item ( void *  parm)

Definition at line 1515 of file wsp_headers.c.

References parm_destroy().

Referenced by pack_accept(), pack_accept_charset(), pack_accept_encoding(), pack_accept_language(), pack_challenge(), pack_content_disposition(), and pack_credentials().

1516 {
1517  parm_destroy(parm);
1518 }
Definition: seewbmp.c:154
static void parm_destroy(Parameter *parm)
Definition: wsp_headers.c:1505

◆ wsp_field_value()

int wsp_field_value ( ParseContext context,
int *  well_known_value 
)

Definition at line 107 of file wsp_headers.c.

References parse_get_char(), parse_get_uintvar(), parse_limit(), parse_skip(), WSP_FIELD_VALUE_DATA, WSP_FIELD_VALUE_ENCODED, WSP_FIELD_VALUE_NUL_STRING, and WSP_QUOTE.

Referenced by unpack_cache_directive(), unpack_field_name(), wsp_skip_field_value(), and wsp_unpack_well_known_field().

108 {
109  int val;
110  unsigned long len;
111 
112  val = parse_get_char(context);
113  if (val > 0 && val < 31) {
114  *well_known_value = -1;
115  parse_limit(context, val);
116  return WSP_FIELD_VALUE_DATA;
117  } else if (val == 31) {
118  *well_known_value = -1;
119  len = parse_get_uintvar(context);
120  parse_limit(context, len);
121  return WSP_FIELD_VALUE_DATA;
122  } else if (val > 127) {
123  *well_known_value = val - 128;
125  } else if (val == WSP_QUOTE || val == '"') { /* 127 */
126  *well_known_value = -1;
127  /* We already consumed the Quote */
129  } else { /* implicite val == 0 */
130  *well_known_value = -1;
131  /* Un-parse the character we just read */
132  parse_skip(context, -1);
134  }
135 }
#define WSP_FIELD_VALUE_DATA
Definition: wsp_headers.h:70
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
#define WSP_QUOTE
Definition: wsp_headers.h:74
int parse_limit(ParseContext *context, long length)
Definition: parse.c:121
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
#define WSP_FIELD_VALUE_NUL_STRING
Definition: wsp_headers.h:68
unsigned long parse_get_uintvar(ParseContext *context)
Definition: parse.c:246
#define WSP_FIELD_VALUE_ENCODED
Definition: wsp_headers.h:69

◆ wsp_headers_pack()

Octstr* wsp_headers_pack ( List headers,
int  separate_content_type,
int  wsp_version 
)

Definition at line 2963 of file wsp_headers.c.

References debug(), gwlist_len(), http_header_get(), octstr_create, octstr_destroy(), octstr_get_cstr, pack_known_header(), warning(), wsp_pack_application_header(), and wsp_pack_separate_content_type().

Referenced by main(), make_confirmedpush_pdu(), make_connectreply_pdu(), make_push_pdu(), make_resume_reply_pdu(), pack_into_push_datagram(), and pack_into_result_datagram().

2964 {
2965  Octstr *packed;
2966  long i, len;
2967  int errors;
2968 
2969  packed = octstr_create("");
2970  if (separate_content_type)
2971  wsp_pack_separate_content_type(packed, headers);
2972 
2973  len = gwlist_len(headers);
2974  for (i = 0; i < len; i++) {
2975  Octstr *fieldname;
2976  Octstr *value;
2977  long fieldnum;
2978 
2979  http_header_get(headers, i, &fieldname, &value);
2980  /* XXX we need to obey which WSP encoding-version to use */
2981  /* fieldnum = wsp_string_to_header(fieldname); */
2982  fieldnum = wsp_string_to_versioned_header(fieldname, wsp_version);
2983 
2984  errors = 0;
2985 
2986  if (separate_content_type && fieldnum == WSP_HEADER_CONTENT_TYPE) {
2987  /* already handled */
2988  debug("wsp",0,"WSP: content type already handled.");
2989  } else if (fieldnum < 0) {
2990  if (wsp_pack_application_header(packed, fieldname, value) < 0)
2991  errors = 1;
2992  } else {
2993  if (pack_known_header(packed, fieldnum, value) < 0)
2994  errors = 1;
2995  }
2996 
2997  if (errors)
2998  warning(0, "Skipping header: %s: %s",
2999  octstr_get_cstr(fieldname),
3000  octstr_get_cstr(value));
3001 
3002  octstr_destroy(fieldname);
3003  octstr_destroy(value);
3004  }
3005 
3006  /*
3007  http_header_dump(headers);
3008  octstr_dump(packed, 0);
3009  */
3010 
3011  return packed;
3012 }
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2902
long gwlist_len(List *list)
Definition: list.c:166
static int pack_known_header(Octstr *packed, long fieldnum, Octstr *value)
Definition: wsp_headers.c:2889
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void wsp_pack_separate_content_type(Octstr *packed, List *headers)
Definition: wsp_headers.c:2851
int wsp_pack_application_header(Octstr *packed, Octstr *fieldname, Octstr *value)
Definition: wsp_headers.c:2938
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ wsp_headers_unpack()

List* wsp_headers_unpack ( Octstr headers,
int  content_type 
)

Definition at line 1331 of file wsp_headers.c.

References debug(), gwlist_get(), gwlist_len(), http_create_empty_headers(), info(), octstr_dump, octstr_get_cstr, octstr_len(), parse_context_create(), parse_context_destroy(), parse_error(), parse_get_char(), parse_octets_left(), parse_skip(), warning(), wsp_skip_field_value(), wsp_unpack_app_header(), and wsp_unpack_well_known_field().

Referenced by main(), mime_decompile(), unpack_datagram(), and unpack_new_headers().

1332 {
1334  int byte;
1335  List *unpacked;
1336  int code_page;
1337 
1338  unpacked = http_create_empty_headers();
1339  context = parse_context_create(headers);
1340 
1341  if (octstr_len(headers) > 0) {
1342  debug("wsp", 0, "WSP: decoding headers:");
1343  octstr_dump(headers, 0);
1344  }
1345 
1346  if (content_type_present)
1347  wsp_unpack_well_known_field(unpacked,
1348  WSP_HEADER_CONTENT_TYPE, context);
1349 
1350  code_page = 1; /* default */
1351 
1352  while (parse_octets_left(context) > 0 && !parse_error(context)) {
1353  byte = parse_get_char(context);
1354 
1355  if (byte == 127 || (byte >= 1 && byte <= 31)) {
1356  if (byte == 127)
1357  code_page = parse_get_char(context);
1358  else
1359  code_page = byte;
1360  if (code_page == 1)
1361  info(0, "Returning to code page 1 (default).");
1362  else {
1363  warning(0, "Shift to unknown code page %d.",
1364  code_page);
1365  warning(0, "Will try to skip headers until "
1366  "next known code page.");
1367  }
1368  } else if (byte >= 128) { /* well-known-header */
1369  if (code_page == 1)
1370  wsp_unpack_well_known_field(unpacked, byte - 128, context);
1371  else {
1372  debug("wsp", 0, "Skipping field 0x%02x.", byte);
1374  }
1375  } else if (byte > 31 && byte < 127) {
1376  /* Un-parse the character we just read */
1377  parse_skip(context, -1);
1378  wsp_unpack_app_header(unpacked, context);
1379  } else {
1380  warning(0, "Unsupported token or header (start 0x%x)", byte);
1381  break;
1382  }
1383  }
1384 
1385  if (gwlist_len(unpacked) > 0) {
1386  long i;
1387 
1388  debug("wsp", 0, "WSP: decoded headers:");
1389  for (i = 0; i < gwlist_len(unpacked); i++) {
1390  Octstr *header = gwlist_get(unpacked, i);
1391  debug("wsp", 0, "%s", octstr_get_cstr(header));
1392  }
1393  debug("wsp", 0, "WSP: End of decoded headers.");
1394  }
1395 
1397  return unpacked;
1398 }
void info(int err, const char *fmt,...)
Definition: log.c:672
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void wsp_unpack_app_header(List *unpacked, ParseContext *context)
Definition: wsp_headers.c:1311
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
List * http_create_empty_headers(void)
Definition: http.c:2872
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void warning(int err, const char *fmt,...)
Definition: log.c:660
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
void parse_context_destroy(ParseContext *context)
Definition: parse.c:88
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void wsp_skip_field_value(ParseContext *context)
Definition: wsp_headers.c:138
void wsp_unpack_well_known_field(List *unpacked, int field_type, ParseContext *context)
Definition: wsp_headers.c:1030
int parse_error(ParseContext *context)
Definition: parse.c:100
ParseContext * parse_context_create(Octstr *str)
Definition: parse.c:74
Definition: list.c:102
long parse_octets_left(ParseContext *context)
Definition: parse.c:159

◆ wsp_pack_application_header()

int wsp_pack_application_header ( Octstr packed,
Octstr fieldname,
Octstr value 
)

Definition at line 2938 of file wsp_headers.c.

References is_token(), octstr_get_cstr, octstr_str_compare(), warning(), wsp_pack_date(), and wsp_pack_text().

Referenced by wsp_headers_pack().

2940 {
2941  if (!is_token(fieldname)) {
2942  warning(0, "WSP headers: `%s' is not a valid HTTP token.",
2943  octstr_get_cstr(fieldname));
2944  return -1;
2945  }
2946 
2947  /* We have to deal specially with the X-WAP.TOD header, because it
2948  * is the only case of a text-format header defined with a non-text
2949  * field value. */
2950  /* Normally this should be a case-insensitive comparison, but this
2951  * header will only be present if we generated it ourselves in the
2952  * application layer. */
2953  if (octstr_str_compare(fieldname, "X-WAP.TOD") == 0) {
2954  wsp_pack_text(packed, fieldname);
2955  return wsp_pack_date(packed, value);
2956  }
2957 
2958  wsp_pack_text(packed, fieldname);
2959  wsp_pack_text(packed, value);
2960  return 0;
2961 }
static int is_token(Octstr *token)
Definition: wsp_headers.c:1682
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:660
int wsp_pack_date(Octstr *packed, Octstr *value)
Definition: wsp_headers.c:2186
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973
int wsp_pack_text(Octstr *packed, Octstr *text)
Definition: wsp_headers.c:1615

◆ wsp_pack_constrained_value()

int wsp_pack_constrained_value ( Octstr packed,
Octstr text,
long  value 
)

Definition at line 1879 of file wsp_headers.c.

References text, wsp_pack_short_integer(), and wsp_pack_text().

Referenced by pack_accept(), pack_accept_charset(), pack_accept_language(), pack_cache_control(), pack_connection(), pack_encoding(), pack_field_name(), pack_method(), pack_range_unit(), and pack_transfer_encoding().

1880 {
1881  if (value >= 0)
1882  wsp_pack_short_integer(packed, value);
1883  else
1884  wsp_pack_text(packed, text);
1885  return 0;
1886 }
void wsp_pack_short_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1800
char * text
Definition: smsc_cimd2.c:921
int wsp_pack_text(Octstr *packed, Octstr *text)
Definition: wsp_headers.c:1615

◆ wsp_pack_content_type()

int wsp_pack_content_type ( Octstr packet,
Octstr value 
)

Definition at line 2626 of file wsp_headers.c.

References pack_accept().

Referenced by wsp_pack_separate_content_type().

2627 {
2628  /* The expansion of Content-type-value works out to be
2629  * equivalent to Accept-value. */
2630  return pack_accept(packed, value);
2631 }
static int pack_accept(Octstr *packet, Octstr *value)
Definition: wsp_headers.c:2325

◆ wsp_pack_date()

int wsp_pack_date ( Octstr packet,
Octstr value 
)

Definition at line 2186 of file wsp_headers.c.

References date_parse_http(), octstr_get_cstr, warning(), and wsp_pack_long_integer().

Referenced by pack_expires(), pack_if_range(), wsp_pack_application_header(), and wsp_pack_retry_after().

2187 {
2188  long timeval;
2189 
2190  /* If we get a negative timeval here, this means either
2191  * we're beyond the time_t 32 bit int positive border for the
2192  * timestamp or we're really handling time before epoch. */
2193  timeval = date_parse_http(value);
2194  if (timeval == -1) {
2195  warning(0, "WSP headers: cannot decode date '%s'",
2196  octstr_get_cstr(value));
2197  return -1;
2198  }
2199 
2200  /* We'll assume that we don't package time before epoch. */
2201  wsp_pack_long_integer(packed, (unsigned long) timeval);
2202  return 0;
2203 }
void wsp_pack_long_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1776
long date_parse_http(Octstr *date)
Definition: date.c:148
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:660

◆ wsp_pack_integer_string()

int wsp_pack_integer_string ( Octstr packet,
Octstr value 
)

Definition at line 1815 of file wsp_headers.c.

References debug(), octstr_get_char(), octstr_get_cstr, octstr_len(), warning(), and wsp_pack_integer_value().

Referenced by pack_cache_control(), pack_parameter(), and wsp_pack_retry_after().

1816 {
1817  unsigned long integer;
1818  long pos;
1819  int c;
1820  int digit;
1821 
1822  integer = 0;
1823  for (pos = 0; pos < octstr_len(value); pos++) {
1824  c = octstr_get_char(value, pos);
1825  if (!isdigit(c))
1826  break;
1827  digit = c - '0';
1828  if (integer > ULONG_MAX / 10)
1829  goto overflow;
1830  integer *= 10;
1831  if (integer > ULONG_MAX - digit)
1832  goto overflow;
1833  integer += digit;
1834  }
1835 
1836  debug("wsp",0,"WSP: %s: value `%s', integer 0x%04lx", __func__,
1837  octstr_get_cstr(value), integer);
1838  wsp_pack_integer_value(packed, integer);
1839  return 0;
1840 
1841 overflow:
1842  warning(0, "WSP: Number too large to handle: '%s'.",
1843  octstr_get_cstr(value));
1844  return -1;
1845 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:660
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void wsp_pack_integer_value(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1807
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ wsp_pack_integer_value()

void wsp_pack_integer_value ( Octstr packed,
unsigned long  integer 
)

Definition at line 1807 of file wsp_headers.c.

References MAX_SHORT_INTEGER, wsp_pack_long_integer(), and wsp_pack_short_integer().

Referenced by pack_accept(), pack_accept_charset(), pack_accept_language(), pack_language(), pack_parameter(), and wsp_pack_integer_string().

1808 {
1809  if (integer <= MAX_SHORT_INTEGER)
1810  wsp_pack_short_integer(packed, integer);
1811  else
1812  wsp_pack_long_integer(packed, integer);
1813 }
void wsp_pack_long_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1776
void wsp_pack_short_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1800
#define MAX_SHORT_INTEGER
Definition: wsp_headers.h:77

◆ wsp_pack_list()

int wsp_pack_list ( Octstr packed,
long  fieldnum,
List elements,
int  i 
)

Definition at line 2869 of file wsp_headers.c.

References gwlist_consume(), octstr_delete(), octstr_destroy(), octstr_len(), and wsp_pack_short_integer().

Referenced by pack_known_header().

2870 {
2871  long startpos;
2872  Octstr *element;
2873 
2874  while ((element = gwlist_consume(elements))) {
2875  startpos = octstr_len(packed);
2876 
2877  wsp_pack_short_integer(packed, fieldnum);
2878  if (headerinfo[i].func(packed, element) < 0) {
2879  /* Remove whatever we added */
2880  octstr_delete(packed, startpos,
2881  octstr_len(packed) - startpos);
2882  /* But continue processing elements */
2883  }
2885  }
2886  return 0;
2887 }
void wsp_pack_short_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1800
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427

◆ wsp_pack_long_integer()

void wsp_pack_long_integer ( Octstr packed,
unsigned long  integer 
)

Definition at line 1776 of file wsp_headers.c.

References octstr_append_char(), octstr_insert_data(), and octstr_len().

Referenced by pack_expires(), wsp_pack_date(), and wsp_pack_integer_value().

1777 {
1778  long oldlen = octstr_len(packed);
1779  unsigned char octet;
1780  long len;
1781 
1782  if (integer == 0) {
1783  /* The Multi-octet-integer has to be at least 1 octet long. */
1784  octstr_append_char(packed, 1); /* length */
1785  octstr_append_char(packed, 0); /* value */
1786  return;
1787  }
1788 
1789  /* Encode it back-to-front, by repeatedly inserting
1790  * at the same position, because that's easier. */
1791  for (len = 0; integer != 0; integer >>= 8, len++) {
1792  octet = integer & 0xff;
1793  octstr_insert_data(packed, oldlen, (char *)&octet, 1);
1794  }
1795 
1796  octet = len;
1797  octstr_insert_data(packed, oldlen, (char *)&octet, 1);
1798 }
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
Definition: octstr.c:1461
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ wsp_pack_parameters()

void wsp_pack_parameters ( Octstr packed,
List parms 
)

Definition at line 1973 of file wsp_headers.c.

References gwlist_get(), gwlist_len(), and pack_parameter().

Referenced by pack_accept(), pack_challenge(), pack_content_disposition(), and pack_credentials().

1974 {
1975  long i;
1976  Parameter *parm;
1977 
1978  for (i = 0; i < gwlist_len(parms); i++) {
1979  parm = gwlist_get(parms, i);
1980  pack_parameter(packed, parm);
1981  }
1982 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Definition: seewbmp.c:154
static void pack_parameter(Octstr *packed, Parameter *parm)
Definition: wsp_headers.c:1888

◆ wsp_pack_quoted_text()

int wsp_pack_quoted_text ( Octstr packed,
Octstr text 
)

Definition at line 1627 of file wsp_headers.c.

References octstr_append(), octstr_append_char(), and text.

Referenced by pack_if_range().

1628 {
1629  octstr_append_char(packed, '"');
1630  octstr_append(packed,text);
1631  octstr_append_char(packed,0);
1632  return 0;
1633 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
char * text
Definition: smsc_cimd2.c:921

◆ wsp_pack_retry_after()

int wsp_pack_retry_after ( Octstr packet,
Octstr value 
)

Definition at line 2727 of file wsp_headers.c.

References ABSOLUTE_TIME, error(), octstr_append_char(), octstr_create, octstr_destroy(), octstr_get_char(), RELATIVE_TIME, wsp_pack_date(), wsp_pack_integer_string(), and wsp_pack_value().

2728 {
2729  Octstr *encoded = NULL;
2730 
2731  encoded = octstr_create("");
2732  if (isdigit(octstr_get_char(value, 0))) {
2734  if (wsp_pack_integer_string(encoded, value) < 0)
2735  goto error;
2736  } else {
2738  if (wsp_pack_date(encoded, value) < 0)
2739  goto error;
2740  }
2741  wsp_pack_value(packed, encoded);
2742 
2743  octstr_destroy(encoded);
2744  return 0;
2745 
2746 error:
2747  octstr_destroy(encoded);
2748  return -1;
2749 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define ABSOLUTE_TIME
Definition: wsp_headers.h:81
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
void wsp_pack_value(Octstr *packed, Octstr *encoded)
Definition: wsp_headers.c:1761
#define RELATIVE_TIME
Definition: wsp_headers.h:82
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
int wsp_pack_date(Octstr *packed, Octstr *value)
Definition: wsp_headers.c:2186
Definition: octstr.c:118
int wsp_pack_integer_string(Octstr *packed, Octstr *value)
Definition: wsp_headers.c:1815
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ wsp_pack_separate_content_type()

void wsp_pack_separate_content_type ( Octstr packed,
List headers 
)

Definition at line 2851 of file wsp_headers.c.

References content_type, http_header_find_first, octstr_create, octstr_destroy(), octstr_strip_blanks(), warning(), and wsp_pack_content_type().

Referenced by wsp_headers_pack().

2852 {
2854 
2855  /* Can't use http_header_get_content_type because it
2856  * does not parse all possible parameters. */
2857  content_type = http_header_find_first(headers, "Content-Type");
2858 
2859  if (content_type == NULL) {
2860  warning(0, "WSP: Missing Content-Type header in "
2861  "response, guessing application/octet-stream");
2862  content_type = octstr_create("application/octet-stream");
2863  }
2867 }
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
int wsp_pack_content_type(Octstr *packed, Octstr *value)
Definition: wsp_headers.c:2626
#define http_header_find_first(headers, name)
Definition: http.h:603
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
const char * content_type
Definition: fakewap.c:249
Definition: octstr.c:118

◆ wsp_pack_short_integer()

void wsp_pack_short_integer ( Octstr packed,
unsigned long  integer 
)

Definition at line 1800 of file wsp_headers.c.

References gw_assert(), MAX_SHORT_INTEGER, and octstr_append_char().

Referenced by ota_pack_push_headers(), pack_cache_control(), pack_content_disposition(), pack_known_header(), pack_parameter(), pack_pragma(), pack_range(), pack_warning(), wsp_pack_constrained_value(), wsp_pack_integer_value(), wsp_pack_list(), and wsp_pack_version_value().

1801 {
1802  gw_assert(integer <= MAX_SHORT_INTEGER);
1803 
1804  octstr_append_char(packed, integer + 0x80);
1805 }
gw_assert(wtls_machine->packet_to_send !=NULL)
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
#define MAX_SHORT_INTEGER
Definition: wsp_headers.h:77

◆ wsp_pack_text()

int wsp_pack_text ( Octstr packet,
Octstr value 
)

Definition at line 1615 of file wsp_headers.c.

References octstr_append(), octstr_append_char(), octstr_get_char(), text, and WSP_QUOTE.

Referenced by pack_accept(), pack_accept_charset(), pack_accept_language(), pack_cache_control(), pack_challenge(), pack_credentials(), pack_language(), pack_parameter(), pack_uri(), pack_warning(), wsp_pack_application_header(), wsp_pack_constrained_value(), and wsp_pack_version_value().

1616 {
1617  /* This check catches 0-length strings as well, because
1618  * octstr_get_char will return -1. */
1619  if (octstr_get_char(text, 0) >= 128 || octstr_get_char(text, 0) < 32)
1620  octstr_append_char(packed, WSP_QUOTE);
1621  octstr_append(packed, text);
1622  octstr_append_char(packed, 0);
1623  return 0;
1624 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
#define WSP_QUOTE
Definition: wsp_headers.h:74
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
char * text
Definition: smsc_cimd2.c:921
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ wsp_pack_value()

void wsp_pack_value ( Octstr packed,
Octstr encoded 
)

Definition at line 1761 of file wsp_headers.c.

References octstr_append(), octstr_append_char(), octstr_append_uintvar(), and octstr_len().

Referenced by pack_accept(), pack_accept_charset(), pack_accept_language(), pack_cache_control(), pack_challenge(), pack_content_disposition(), pack_content_range(), pack_credentials(), pack_pragma(), pack_range_value(), pack_warning(), and wsp_pack_retry_after().

1762 {
1763  long len;
1764 
1765  len = octstr_len(encoded);
1766  if (len <= 30)
1767  octstr_append_char(packed, len);
1768  else {
1769  octstr_append_char(packed, 31);
1770  octstr_append_uintvar(packed, len);
1771  }
1772 
1773  octstr_append(packed, encoded);
1774 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931

◆ wsp_pack_version_value()

int wsp_pack_version_value ( Octstr packet,
Octstr value 
)

Definition at line 1848 of file wsp_headers.c.

References debug(), octstr_get_char(), octstr_get_cstr, octstr_len(), octstr_parse_long(), wsp_pack_short_integer(), and wsp_pack_text().

Referenced by pack_parameter().

1849 {
1850  unsigned long integer;
1851  long major, minor;
1852  long pos;
1853 
1854  pos = octstr_parse_long(&major, version, 0, 10);
1855  if (pos < 0 || major < 1 || major > 7)
1856  goto usetext;
1857 
1858  if (pos == octstr_len(version))
1859  minor = 15;
1860  else {
1861  if (octstr_get_char(version, pos) != '.')
1862  goto usetext;
1863  pos = octstr_parse_long(&minor, version, pos + 1, 10);
1864  if (pos != octstr_len(version) || minor < 0 || minor > 14)
1865  goto usetext;
1866  }
1867 
1868  integer = major << 4 | minor;
1869  debug("wsp",0,"WSP: %s: value `%s', integer 0x%04lx", __func__,
1870  octstr_get_cstr(version), integer);
1871  wsp_pack_short_integer(packed, integer);
1872  return 0;
1873 
1874 usetext:
1875  wsp_pack_text(packed, version);
1876  return 0;
1877 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void wsp_pack_short_integer(Octstr *packed, unsigned long integer)
Definition: wsp_headers.c:1800
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
int wsp_pack_text(Octstr *packed, Octstr *text)
Definition: wsp_headers.c:1615
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ wsp_secondary_field_value()

int wsp_secondary_field_value ( ParseContext context,
long *  result 
)

Definition at line 183 of file wsp_headers.c.

References parse_get_char(), parse_get_uintvar(), parse_skip(), unpack_multi_octet_integer(), WSP_FIELD_VALUE_ENCODED, WSP_FIELD_VALUE_NONE, WSP_FIELD_VALUE_NUL_STRING, and WSP_QUOTE.

Referenced by unpack_accept_language_general_form(), unpack_parameter(), wsp_unpack_accept_charset_general_form(), and wsp_unpack_accept_general_form().

184 {
185  int val;
186  long length;
187 
188  val = parse_get_char(context);
189  if (val == 0) {
190  *result = 0;
191  return WSP_FIELD_VALUE_NONE;
192  } else if (val > 0 && val < 31) {
193  *result = unpack_multi_octet_integer(context, val);
195  } else if (val == 31) {
196  length = parse_get_uintvar(context);
197  *result = unpack_multi_octet_integer(context, length);
199  } else if (val > 127) {
200  *result = val - 128;
202  } else if (val == WSP_QUOTE) { /* 127 */
203  *result = -1;
205  } else {
206  *result = -1;
207  /* Un-parse the character we just read */
208  parse_skip(context, -1);
210  }
211 }
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
#define WSP_QUOTE
Definition: wsp_headers.h:74
#define WSP_FIELD_VALUE_NONE
Definition: wsp_headers.h:71
static long unpack_multi_octet_integer(ParseContext *context, long len)
Definition: wsp_headers.c:151
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
#define WSP_FIELD_VALUE_NUL_STRING
Definition: wsp_headers.h:68
unsigned long parse_get_uintvar(ParseContext *context)
Definition: parse.c:246
#define WSP_FIELD_VALUE_ENCODED
Definition: wsp_headers.h:69

◆ wsp_skip_field_value()

void wsp_skip_field_value ( ParseContext context)

Definition at line 138 of file wsp_headers.c.

References parse_pop_limit(), parse_skip_to_limit(), wsp_field_value(), and WSP_FIELD_VALUE_DATA.

Referenced by wsp_headers_unpack().

139 {
140  int val;
141  int ret;
142 
143  ret = wsp_field_value(context, &val);
144  if (ret == WSP_FIELD_VALUE_DATA) {
147  }
148 }
#define WSP_FIELD_VALUE_DATA
Definition: wsp_headers.h:70
Definition: parse.c:65
void parse_skip_to_limit(ParseContext *context)
Definition: parse.c:180
int parse_pop_limit(ParseContext *context)
Definition: parse.c:142
int wsp_field_value(ParseContext *context, int *well_known_value)
Definition: wsp_headers.c:107

◆ wsp_strip_parameters()

List* wsp_strip_parameters ( Octstr value)

Definition at line 1553 of file wsp_headers.c.

References gwlist_append(), gwlist_create, http_header_quoted_string_len(), octstr_copy, octstr_delete(), octstr_get_char(), octstr_len(), octstr_search_char(), octstr_strip_blanks(), and parm_create().

Referenced by pack_accept(), pack_accept_charset(), pack_accept_encoding(), pack_accept_language(), pack_challenge(), pack_content_disposition(), and pack_credentials().

1554 {
1555  long pos;
1556  long len;
1557  int c;
1558  long end;
1559  List *parms;
1560  long firstparm;
1561 
1562  len = octstr_len(value);
1563  /* Find the start of the first parameter. */
1564  for (pos = 0; pos < len; pos++) {
1565  c = octstr_get_char(value, pos);
1566  if (c == ';')
1567  break;
1568  else if (c == '"')
1569  pos += http_header_quoted_string_len(value, pos) - 1;
1570  }
1571 
1572  if (pos >= len)
1573  return NULL; /* no parameters */
1574 
1575  parms = gwlist_create();
1576  firstparm = pos;
1577 
1578  for (pos++; pos > 0 && pos < len; pos++) {
1579  Octstr *key = NULL;
1580  Octstr *val = NULL;
1581 
1582  end = octstr_search_char(value, '=', pos);
1583  if (end < 0)
1584  end = octstr_search_char(value, ';', pos);
1585  if (end < 0)
1586  end = octstr_len(value);
1587  key = octstr_copy(value, pos, end - pos);
1588  octstr_strip_blanks(key);
1589  pos = end;
1590 
1591  if (octstr_get_char(value, pos) == '=') {
1592  pos++;
1593  while (isspace(octstr_get_char(value, pos)))
1594  pos++;
1595  if (octstr_get_char(value, pos) == '"')
1596  end = pos + http_header_quoted_string_len(value, pos);
1597  else
1598  end = octstr_search_char(value, ';', pos);
1599  if (end < 0)
1600  end = octstr_len(value);
1601  val = octstr_copy(value, pos, end - pos);
1602  octstr_strip_blanks(val);
1603  pos = end;
1604  pos = octstr_search_char(value, ';', pos);
1605  }
1606 
1607  gwlist_append(parms, parm_create(key, val));
1608  }
1609 
1610  octstr_delete(value, firstparm, octstr_len(value) - firstparm);
1611  octstr_strip_blanks(value);
1612  return parms;
1613 }
static Parameter * parm_create(Octstr *key, Octstr *value)
Definition: wsp_headers.c:1495
void gwlist_append(List *list, void *item)
Definition: list.c:179
long http_header_quoted_string_len(Octstr *header, long start)
Definition: http.c:3293
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
#define gwlist_create()
Definition: list.h:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
Definition: list.c:102

◆ wsp_unpack_accept_charset_general_form()

Octstr* wsp_unpack_accept_charset_general_form ( ParseContext context)

Definition at line 557 of file wsp_headers.c.

References panic, parse_error(), parse_get_nul_string(), unpack_optional_q_value(), warning(), WSP_FIELD_VALUE_ENCODED, WSP_FIELD_VALUE_NONE, WSP_FIELD_VALUE_NUL_STRING, and wsp_secondary_field_value().

Referenced by wsp_unpack_well_known_field().

558 {
559  Octstr *decoded = NULL;
560  int ret;
561  long val;
562 
563  ret = wsp_secondary_field_value(context, &val);
564  if (parse_error(context) || ret == WSP_FIELD_VALUE_NONE) {
565  warning(0, "Bad accept-charset-general-form");
566  return NULL;
567  }
568 
569  if (ret == WSP_FIELD_VALUE_ENCODED) {
570  decoded = wsp_charset_to_string(val);
571  if (!decoded) {
572  warning(0, "Unknown character set %04lx.", val);
573  return NULL;
574  }
575  } else if (ret == WSP_FIELD_VALUE_NUL_STRING) {
576  decoded = parse_get_nul_string(context);
577  if (!decoded) {
578  warning(0, "Format error in accept-charset");
579  return NULL;
580  }
581  } else {
582  panic(0, "Unknown secondary field value type %d.", ret);
583  }
584 
586  return decoded;
587 }
Definition: parse.c:65
static void unpack_optional_q_value(ParseContext *context, Octstr *decoded)
Definition: wsp_headers.c:478
#define WSP_FIELD_VALUE_NONE
Definition: wsp_headers.h:71
void warning(int err, const char *fmt,...)
Definition: log.c:660
Definition: octstr.c:118
#define WSP_FIELD_VALUE_NUL_STRING
Definition: wsp_headers.h:68
#define panic
Definition: log.h:87
Octstr * parse_get_nul_string(ParseContext *context)
Definition: parse.c:263
int parse_error(ParseContext *context)
Definition: parse.c:100
#define WSP_FIELD_VALUE_ENCODED
Definition: wsp_headers.h:69
int wsp_secondary_field_value(ParseContext *context, long *result)
Definition: wsp_headers.c:183

◆ wsp_unpack_accept_general_form()

Octstr* wsp_unpack_accept_general_form ( ParseContext context)

Definition at line 513 of file wsp_headers.c.

References panic, parse_error(), parse_get_nul_string(), warning(), WSP_FIELD_VALUE_ENCODED, WSP_FIELD_VALUE_NONE, WSP_FIELD_VALUE_NUL_STRING, wsp_secondary_field_value(), and wsp_unpack_all_parameters().

Referenced by wsp_unpack_well_known_field().

514 {
515  Octstr *decoded = NULL;
516  int ret;
517  long val;
518 
519  /* The definition for Accept-general-form looks quite complicated,
520  * but the "Q-token Q-value" part fits the normal expansion of
521  * Parameter, so it simplifies to:
522  * Value-length Media-range *(Parameter)
523  * and we've already parsed Value-length.
524  */
525 
526  /* We use this function to parse content-general-form too,
527  * because its definition of Media-type is identical to Media-range.
528  */
529 
530  ret = wsp_secondary_field_value(context, &val);
531  if (parse_error(context) || ret == WSP_FIELD_VALUE_NONE) {
532  warning(0, "bad media-range or media-type");
533  return NULL;
534  }
535 
536  if (ret == WSP_FIELD_VALUE_ENCODED) {
537  decoded = wsp_content_type_to_string(val);
538  if (!decoded) {
539  warning(0, "Unknown content type 0x%02lx.", val);
540  return NULL;
541  }
542  } else if (ret == WSP_FIELD_VALUE_NUL_STRING) {
543  decoded = parse_get_nul_string(context);
544  if (!decoded) {
545  warning(0, "Format error in content type");
546  return NULL;
547  }
548  } else {
549  panic(0, "Unknown secondary field value type %d.", ret);
550  }
551 
553  return decoded;
554 }
Definition: parse.c:65
void wsp_unpack_all_parameters(ParseContext *context, Octstr *decoded)
Definition: wsp_headers.c:443
#define WSP_FIELD_VALUE_NONE
Definition: wsp_headers.h:71
void warning(int err, const char *fmt,...)
Definition: log.c:660
Definition: octstr.c:118
#define WSP_FIELD_VALUE_NUL_STRING
Definition: wsp_headers.h:68
#define panic
Definition: log.h:87
Octstr * parse_get_nul_string(ParseContext *context)
Definition: parse.c:263
int parse_error(ParseContext *context)
Definition: parse.c:100
#define WSP_FIELD_VALUE_ENCODED
Definition: wsp_headers.h:69
int wsp_secondary_field_value(ParseContext *context, long *result)
Definition: wsp_headers.c:183

◆ wsp_unpack_all_parameters()

void wsp_unpack_all_parameters ( ParseContext context,
Octstr decoded 
)

Definition at line 443 of file wsp_headers.c.

References parse_error(), parse_octets_left(), and unpack_parameter().

Referenced by unpack_disposition(), and wsp_unpack_accept_general_form().

444 {
445  int ret = 0;
446 
447  while (ret >= 0 && !parse_error(context) &&
448  parse_octets_left(context) > 0) {
449  ret = unpack_parameter(context, decoded);
450  }
451 }
static int unpack_parameter(ParseContext *context, Octstr *decoded)
Definition: wsp_headers.c:326
Definition: parse.c:65
int parse_error(ParseContext *context)
Definition: parse.c:100
long parse_octets_left(ParseContext *context)
Definition: parse.c:159

◆ wsp_unpack_app_header()

void wsp_unpack_app_header ( List unpacked,
ParseContext context 
)

Definition at line 1311 of file wsp_headers.c.

References http_header_add(), octstr_destroy(), octstr_get_cstr, parse_error(), parse_get_nul_string(), and warning().

Referenced by wsp_headers_unpack().

1312 {
1313  Octstr *header = NULL;
1314  Octstr *value = NULL;
1315 
1316  header = parse_get_nul_string(context);
1317  value = parse_get_nul_string(context);
1318 
1319  if (header && value) {
1320  http_header_add(unpacked, octstr_get_cstr(header),
1321  octstr_get_cstr(value));
1322  }
1323 
1324  if (parse_error(context))
1325  warning(0, "Error parsing application-header.");
1326 
1327  octstr_destroy(header);
1328  octstr_destroy(value);
1329 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
Definition: parse.c:65
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Octstr * parse_get_nul_string(ParseContext *context)
Definition: parse.c:263
int parse_error(ParseContext *context)
Definition: parse.c:100

◆ wsp_unpack_date_value()

Octstr* wsp_unpack_date_value ( ParseContext context)

Definition at line 492 of file wsp_headers.c.

References date_format_http(), parse_get_char(), unpack_multi_octet_integer(), and warning().

Referenced by unpack_retry_after(), and wsp_unpack_well_known_field().

493 {
494  unsigned long timeval;
495  int length;
496 
497  length = parse_get_char(context);
498  if (length > 30) {
499  warning(0, "WSP headers: bad date-value.");
500  return NULL;
501  }
502 
503  timeval = unpack_multi_octet_integer(context, length);
504  if (timeval < 0) {
505  warning(0, "WSP headers: cannot unpack date-value.");
506  return NULL;
507  }
508 
509  return date_format_http(timeval);
510 }
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
static long unpack_multi_octet_integer(ParseContext *context, long len)
Definition: wsp_headers.c:151
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * date_format_http(unsigned long unixtime)
Definition: date.c:89

◆ wsp_unpack_integer_value()

Octstr* wsp_unpack_integer_value ( ParseContext context)

Definition at line 214 of file wsp_headers.c.

References octstr_append_decimal(), octstr_create, parse_get_char(), unpack_multi_octet_integer(), and warning().

Referenced by unpack_cache_directive(), unpack_retry_after(), and unpack_warning_value().

215 {
216  Octstr *decoded;
217  unsigned long value;
218  int val;
219 
220  val = parse_get_char(context);
221  if (val < 31) {
222  value = unpack_multi_octet_integer(context, val);
223  } else if (val > 127) {
224  value = val - 128;
225  } else {
226  warning(0, "WSP headers: bad integer-value.");
227  return NULL;
228  }
229 
230  decoded = octstr_create("");
231  octstr_append_decimal(decoded, value);
232  return decoded;
233 }
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
static long unpack_multi_octet_integer(ParseContext *context, long len)
Definition: wsp_headers.c:151
void warning(int err, const char *fmt,...)
Definition: log.c:660
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_append_decimal(Octstr *ostr, long value)
Definition: octstr.c:1976
Definition: octstr.c:118

◆ wsp_unpack_version_value()

Octstr* wsp_unpack_version_value ( long  value)

Definition at line 291 of file wsp_headers.c.

References octstr_append_char(), octstr_append_decimal(), and octstr_create.

Referenced by unpack_encoding_version(), and unpack_parameter().

292 {
293  Octstr *result;
294  int major, minor;
295 
296  major = ((value >> 4) & 0x7);
297  minor = (value & 0xf);
298 
299  result = octstr_create("");
300  octstr_append_char(result, major + '0');
301  if (minor != 15) {
302  octstr_append_char(result, '.');
303  octstr_append_decimal(result, minor);
304  }
305 
306  return result;
307 }
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_append_decimal(Octstr *ostr, long value)
Definition: octstr.c:1976
Definition: octstr.c:118

◆ wsp_unpack_well_known_field()

void wsp_unpack_well_known_field ( List unpacked,
int  field_type,
ParseContext context 
)

Definition at line 1030 of file wsp_headers.c.

References http_header_add(), octstr_append_decimal(), octstr_binary_to_base64(), octstr_create, octstr_delete(), octstr_destroy(), octstr_get_cstr, octstr_len(), panic, parse_error(), parse_get_nul_string(), parse_get_octets(), parse_octets_left(), parse_pop_limit(), parse_skip(), parse_skip_to_limit(), proxy_unpack_credentials(), unpack_accept_language_general_form(), unpack_cache_directive(), unpack_challenge(), unpack_content_range(), unpack_credentials(), unpack_disposition(), unpack_encoding_version(), unpack_multi_octet_integer(), unpack_parameter(), unpack_range_value(), unpack_retry_after(), unpack_warning_value(), warning(), wsp_field_value(), WSP_FIELD_VALUE_DATA, WSP_FIELD_VALUE_ENCODED, WSP_FIELD_VALUE_NUL_STRING, wsp_unpack_accept_charset_general_form(), wsp_unpack_accept_general_form(), and wsp_unpack_date_value().

Referenced by wsp_headers_unpack().

1032 {
1033  int val, ret;
1034  unsigned char *headername = NULL;
1035  unsigned char *ch = NULL;
1036  Octstr *decoded = NULL;
1037 
1038  ret = wsp_field_value(context, &val);
1039  if (parse_error(context)) {
1040  warning(0, "Faulty header, skipping remaining headers.");
1042  return;
1043  }
1044 
1045  headername = wsp_header_to_cstr(field_type);
1046  /* headername can still be NULL. This is checked after parsing
1047  * the field value. We want to parse the value before exiting,
1048  * so that we are ready for the next header. */
1049 
1050  /* The following code must set "ch" or "decoded" to a non-NULL
1051  * value if the header is valid. */
1052 
1053  if (ret == WSP_FIELD_VALUE_NUL_STRING) {
1054  /* We allow any header to have a text value, even if that
1055  * is not defined in the grammar. Be generous in what
1056  * you accept, etc. */
1057  /* This covers Text-string, Token-Text, and Uri-value rules */
1058  decoded = parse_get_nul_string(context);
1059  } else if (ret == WSP_FIELD_VALUE_ENCODED) {
1060  switch (field_type) {
1061  case WSP_HEADER_ACCEPT:
1062  case WSP_HEADER_CONTENT_TYPE:
1063  ch = wsp_content_type_to_cstr(val);
1064  if (!ch)
1065  warning(0, "Unknown content type 0x%02x.", val);
1066  break;
1067 
1068  case WSP_HEADER_ACCEPT_CHARSET:
1069  ch = wsp_charset_to_cstr(val);
1070  if (!ch)
1071  warning(0, "Unknown charset 0x%02x.", val);
1072  break;
1073 
1074  case WSP_HEADER_ACCEPT_ENCODING:
1075  case WSP_HEADER_CONTENT_ENCODING:
1076  ch = wsp_encoding_to_cstr(val);
1077  if (!ch)
1078  warning(0, "Unknown encoding 0x%02x.", val);
1079  break;
1080 
1081  case WSP_HEADER_ACCEPT_LANGUAGE:
1082  case WSP_HEADER_CONTENT_LANGUAGE:
1083  ch = wsp_language_to_cstr(val);
1084  if (!ch)
1085  warning(0, "Unknown language 0x%02x.", val);
1086  break;
1087 
1088  case WSP_HEADER_ACCEPT_RANGES:
1089  ch = wsp_ranges_to_cstr(val);
1090  if (!ch)
1091  warning(0, "Unknown ranges value 0x%02x.", val);
1092  break;
1093 
1094  case WSP_HEADER_AGE:
1095  case WSP_HEADER_CONTENT_LENGTH:
1096  case WSP_HEADER_MAX_FORWARDS:
1097  /* Short-integer version of Integer-value */
1098  decoded = octstr_create("");
1099  octstr_append_decimal(decoded, val);
1100  break;
1101 
1102  case WSP_HEADER_ALLOW:
1103  case WSP_HEADER_PUBLIC:
1104  ch = wsp_method_to_cstr(val);
1105  if (!ch) {
1106  /* FIXME Support extended methods */
1107  warning(0, "Unknown method 0x%02x.", val);
1108  }
1109  break;
1110 
1111  case WSP_HEADER_CACHE_CONTROL:
1112  case WSP_HEADER_CACHE_CONTROL_V13:
1113  case WSP_HEADER_CACHE_CONTROL_V14:
1114  ch = wsp_cache_control_to_cstr(val);
1115  if (!ch)
1116  warning(0, "Unknown cache-control value 0x%02x.", val);
1117  break;
1118 
1119  case WSP_HEADER_CONNECTION:
1120  ch = wsp_connection_to_cstr(val);
1121  if (!ch)
1122  warning(0, "Unknown connection value 0x%02x.", val);
1123  break;
1124 
1125 
1126  case WSP_HEADER_PRAGMA:
1127  if (val == 0)
1128  ch = (unsigned char *)"no-cache";
1129  else
1130  warning(0, "Unknown pragma value 0x%02x.", val);
1131  break;
1132 
1133  case WSP_HEADER_TRANSFER_ENCODING:
1134  ch = wsp_transfer_encoding_to_cstr(val);
1135  if (!ch)
1136  warning(0, "Unknown transfer encoding value 0x%02x.", val);
1137  break;
1138 
1139  case WSP_HEADER_VARY:
1140  ch = wsp_header_to_cstr(val);
1141  if (!ch)
1142  warning(0, "Unknown Vary field name 0x%02x.", val);
1143  break;
1144 
1145  case WSP_HEADER_WARNING:
1146  decoded = octstr_create("");
1147  octstr_append_decimal(decoded, val);
1148  break;
1149 
1150  case WSP_HEADER_BEARER_INDICATION:
1151  ch = wsp_bearer_indication_to_cstr(val);
1152  if (!ch)
1153  warning(0, "Unknown Bearer-Indication field name 0x%02x.", val);
1154  break;
1155 
1156  case WSP_HEADER_ACCEPT_APPLICATION:
1157  ch = wsp_application_id_to_cstr(val);
1158  if (!ch)
1159  warning(0, "Unknown Accept-Application field name 0x%02x.", val);
1160  break;
1161 
1162  default:
1163  if (headername) {
1164  warning(0, "Did not expect short-integer with "
1165  "'%s' header, skipping.", headername);
1166  }
1167  break;
1168  }
1169  } else if (ret == WSP_FIELD_VALUE_DATA) {
1170  switch (field_type) {
1171  case WSP_HEADER_ACCEPT:
1172  case WSP_HEADER_CONTENT_TYPE:
1173  /* Content-general-form and Accept-general-form
1174  * are defined separately in WSP, but their
1175  * definitions are equivalent. */
1177  break;
1178 
1179  case WSP_HEADER_ACCEPT_CHARSET:
1181  break;
1182 
1183  case WSP_HEADER_ACCEPT_LANGUAGE:
1185  break;
1186 
1187  case WSP_HEADER_AGE:
1188  case WSP_HEADER_CONTENT_LENGTH:
1189  case WSP_HEADER_MAX_FORWARDS:
1190  case WSP_HEADER_BEARER_INDICATION:
1191  case WSP_HEADER_ACCEPT_APPLICATION:
1192  /* Long-integer version of Integer-value */
1193  {
1196  decoded = octstr_create("");
1197  octstr_append_decimal(decoded, l);
1198  }
1199  break;
1200 
1201  case WSP_HEADER_AUTHORIZATION:
1202  decoded = unpack_credentials(context);
1203  break;
1204 
1205  case WSP_HEADER_PROXY_AUTHORIZATION:
1206  decoded = proxy_unpack_credentials(context);
1207  break;
1208 
1209  case WSP_HEADER_CACHE_CONTROL:
1210  decoded = unpack_cache_directive(context);
1211  break;
1212 
1213  case WSP_HEADER_CONTENT_MD5:
1214  decoded = parse_get_octets(context,
1216  octstr_binary_to_base64(decoded);
1217  /* Zap the CR LF sequence at the end */
1218  octstr_delete(decoded, octstr_len(decoded) - 2, 2);
1219  break;
1220 
1221  case WSP_HEADER_CONTENT_RANGE:
1222  decoded = unpack_content_range(context);
1223  break;
1224 
1225  case WSP_HEADER_DATE:
1226  case WSP_HEADER_EXPIRES:
1227  case WSP_HEADER_IF_MODIFIED_SINCE:
1228  case WSP_HEADER_IF_RANGE:
1229  case WSP_HEADER_IF_UNMODIFIED_SINCE:
1230  case WSP_HEADER_LAST_MODIFIED:
1231  /* Back up to get the length byte again */
1232  parse_skip(context, -1);
1233  decoded = wsp_unpack_date_value(context);
1234  break;
1235 
1236  case WSP_HEADER_PRAGMA:
1237  /* The value is a bare Parameter, without a preceding
1238  * header body. unpack_parameter wasn't really
1239  * designed for this. We work around it here. */
1240  decoded = octstr_create("");
1241  if (unpack_parameter(context, decoded) < 0) {
1242  octstr_destroy(decoded);
1243  decoded = NULL;
1244  } else {
1245  /* Remove the leading "; " */
1246  octstr_delete(decoded, 0, 2);
1247  }
1248  break;
1249 
1250  case WSP_HEADER_PROXY_AUTHENTICATE:
1251  case WSP_HEADER_WWW_AUTHENTICATE:
1252  decoded = unpack_challenge(context);
1253  break;
1254 
1255  case WSP_HEADER_RANGE:
1256  decoded = unpack_range_value(context);
1257  break;
1258 
1259  case WSP_HEADER_RETRY_AFTER:
1260  decoded = unpack_retry_after(context);
1261  break;
1262 
1263  case WSP_HEADER_WARNING:
1264  decoded = unpack_warning_value(context);
1265  break;
1266 
1267  case WSP_HEADER_CONTENT_DISPOSITION:
1268  decoded = unpack_disposition(context);
1269  break;
1270 
1271  case WSP_HEADER_ENCODING_VERSION:
1272  decoded = unpack_encoding_version(context);
1273  break;
1274 
1275  default:
1276  if (headername) {
1277  warning(0, "Did not expect value-length with "
1278  "'%s' header, skipping.", headername);
1279  }
1280  break;
1281  }
1282  if (headername && parse_octets_left(context) > 0) {
1283  warning(0, "WSP: %s: skipping %ld trailing octets.",
1284  headername, parse_octets_left(context));
1285  }
1288  } else {
1289  panic(0, "Unknown field-value type %d.", ret);
1290  }
1291 
1292  if (ch == NULL && decoded != NULL)
1293  ch = (unsigned char *)octstr_get_cstr(decoded);
1294  if (ch == NULL)
1295  goto value_error;
1296 
1297  if (!headername) {
1298  warning(0, "Unknown header number 0x%02x.", field_type);
1299  goto value_error;
1300  }
1301 
1302  http_header_add(unpacked, (char *)headername,(char *) ch);
1303  octstr_destroy(decoded);
1304  return;
1305 
1306 value_error:
1307  warning(0, "Skipping faulty header.");
1308  octstr_destroy(decoded);
1309 }
#define WSP_FIELD_VALUE_DATA
Definition: wsp_headers.h:70
static int unpack_parameter(ParseContext *context, Octstr *decoded)
Definition: wsp_headers.c:326
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
Definition: parse.c:65
static Octstr * unpack_credentials(ParseContext *context)
Definition: wsp_headers.c:625
static Octstr * unpack_encoding_version(ParseContext *context)
Definition: wsp_headers.c:309
static Octstr * unpack_accept_language_general_form(ParseContext *context)
Definition: wsp_headers.c:590
static Octstr * unpack_challenge(ParseContext *context)
Definition: wsp_headers.c:719
void octstr_binary_to_base64(Octstr *ostr)
Definition: octstr.c:542
Octstr * wsp_unpack_accept_general_form(ParseContext *context)
Definition: wsp_headers.c:513
static Octstr * unpack_warning_value(ParseContext *context)
Definition: wsp_headers.c:984
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void parse_skip_to_limit(ParseContext *context)
Definition: parse.c:180
static Octstr * unpack_content_range(ParseContext *context)
Definition: wsp_headers.c:759
static Octstr * unpack_retry_after(ParseContext *context)
Definition: wsp_headers.c:909
int parse_pop_limit(ParseContext *context)
Definition: parse.c:142
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
static long unpack_multi_octet_integer(ParseContext *context, long len)
Definition: wsp_headers.c:151
static Octstr * unpack_range_value(ParseContext *context)
Definition: wsp_headers.c:941
static Octstr * proxy_unpack_credentials(ParseContext *context)
Definition: wsp_headers.c:679
Octstr * parse_get_octets(ParseContext *context, long length)
Definition: parse.c:230
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
int wsp_field_value(ParseContext *context, int *well_known_value)
Definition: wsp_headers.c:107
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
void octstr_append_decimal(Octstr *ostr, long value)
Definition: octstr.c:1976
Definition: octstr.c:118
#define WSP_FIELD_VALUE_NUL_STRING
Definition: wsp_headers.h:68
#define panic
Definition: log.h:87
Octstr * wsp_unpack_date_value(ParseContext *context)
Definition: wsp_headers.c:492
Octstr * parse_get_nul_string(ParseContext *context)
Definition: parse.c:263
static Octstr * unpack_disposition(ParseContext *context)
Definition: wsp_headers.c:925
Octstr * wsp_unpack_accept_charset_general_form(ParseContext *context)
Definition: wsp_headers.c:557
int parse_error(ParseContext *context)
Definition: parse.c:100
#define WSP_FIELD_VALUE_ENCODED
Definition: wsp_headers.h:69
static Octstr * unpack_cache_directive(ParseContext *context)
Definition: wsp_headers.c:824
long parse_octets_left(ParseContext *context)
Definition: parse.c:159
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.