Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wsp_headers.h File Reference

#include "gwlib/gwlib.h"

Include dependency graph for wsp_headers.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  parameter
struct  headerinfo

Defines

#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
#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 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)


Define Documentation

#define ABSOLUTE_TIME   128
 

Definition at line 81 of file wsp_headers.h.

Referenced by wsp_pack_retry_after().

#define BASIC_AUTHENTICATION   128
 

Definition at line 80 of file wsp_headers.h.

Referenced by pack_challenge(), and pack_credentials().

#define BROKEN_LIST   2
 

Definition at line 100 of file wsp_headers.h.

#define BYTE_RANGE   128
 

Definition at line 83 of file wsp_headers.h.

Referenced by pack_range_value().

#define LIST   1
 

Definition at line 94 of file wsp_headers.h.

#define LONG_AGO_VALUE   100000
 

Definition at line 90 of file wsp_headers.h.

Referenced by pack_expires().

#define MAX_SHORT_INTEGER   127
 

Definition at line 77 of file wsp_headers.h.

Referenced by wsp_pack_short_integer().

#define RELATIVE_TIME   129
 

Definition at line 82 of file wsp_headers.h.

Referenced by wsp_pack_retry_after().

#define SUFFIX_BYTE_RANGE   129
 

Definition at line 84 of file wsp_headers.h.

Referenced by pack_range_value().

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

Definition at line 102 of file wsp_headers.h.

Referenced by pack_known_header().

#define WSP_FIELD_VALUE_DATA   3
 

Definition at line 70 of file wsp_headers.h.

#define WSP_FIELD_VALUE_ENCODED   2
 

Definition at line 69 of file wsp_headers.h.

#define WSP_FIELD_VALUE_NONE   4
 

Definition at line 71 of file wsp_headers.h.

#define WSP_FIELD_VALUE_NUL_STRING   1
 

Definition at line 68 of file wsp_headers.h.

Referenced by unpack_parameter().

#define WSP_QUOTE   127
 

Definition at line 74 of file wsp_headers.h.

Referenced by wsp_field_value(), and wsp_pack_text().


Typedef Documentation

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

Definition at line 111 of file wsp_headers.h.

typedef struct parameter Parameter
 

Definition at line 109 of file wsp_headers.h.

Referenced by get_qvalue(), pack_cache_control(), pack_challenge(), pack_parameter(), pack_pragma(), parm_create(), parm_destroy(), parm_parse(), and wsp_pack_parameters().


Function Documentation

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().

01516 {
01517     parm_destroy(parm);
01518 }

Here is the call graph for this function:

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(), ParseContext, and WSP_QUOTE.

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

00108 {
00109     int val;
00110     unsigned long len;
00111 
00112     val = parse_get_char(context);
00113     if (val > 0 && val < 31) {
00114         *well_known_value = -1;
00115         parse_limit(context, val);
00116         return WSP_FIELD_VALUE_DATA;
00117     } else if (val == 31) {
00118         *well_known_value = -1;
00119         len = parse_get_uintvar(context);
00120         parse_limit(context, len);
00121         return WSP_FIELD_VALUE_DATA;
00122     } else if (val > 127) {
00123         *well_known_value = val - 128;
00124         return WSP_FIELD_VALUE_ENCODED;
00125     } else if (val == WSP_QUOTE || val == '"') {  /* 127 */
00126         *well_known_value = -1;
00127         /* We already consumed the Quote */
00128         return WSP_FIELD_VALUE_NUL_STRING;
00129     } else {    /* implicite val == 0 */ 
00130         *well_known_value = -1;
00131         /* Un-parse the character we just read */
00132         parse_skip(context, -1);
00133         return WSP_FIELD_VALUE_NUL_STRING;
00134     }
00135 }

Here is the call graph for this function:

Octstr* wsp_headers_pack List headers,
int  separate_content_type,
int  wsp_version
 

Definition at line 2955 of file wsp_headers.c.

References 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().

02956 {
02957     Octstr *packed;
02958     long i, len;
02959     int errors;
02960 
02961     packed = octstr_create("");
02962     if (separate_content_type)
02963         wsp_pack_separate_content_type(packed, headers);
02964 
02965     len = gwlist_len(headers);
02966     for (i = 0; i < len; i++) {
02967         Octstr *fieldname;
02968         Octstr *value;
02969         long fieldnum;
02970 
02971         http_header_get(headers, i, &fieldname, &value);
02972         /* XXX we need to obey which WSP encoding-version to use */
02973         /* fieldnum = wsp_string_to_header(fieldname); */
02974         fieldnum = wsp_string_to_versioned_header(fieldname, wsp_version);
02975 
02976         errors = 0;
02977 
02978         if (separate_content_type && fieldnum == WSP_HEADER_CONTENT_TYPE) {
02979         /* already handled */
02980         } else if (fieldnum < 0) {
02981             if (wsp_pack_application_header(packed, fieldname, value) < 0)
02982                 errors = 1;
02983         } else {
02984             if (pack_known_header(packed, fieldnum, value) < 0)
02985                 errors = 1;
02986         }
02987 
02988         if (errors)
02989             warning(0, "Skipping header: %s: %s",
02990                     octstr_get_cstr(fieldname),
02991                     octstr_get_cstr(value));
02992 
02993         octstr_destroy(fieldname);
02994         octstr_destroy(value);
02995     }
02996 
02997     /*
02998     http_header_dump(headers);
02999     octstr_dump(packed, 0);
03000     */
03001 
03002     return packed;
03003 }

Here is the call graph for this function:

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(), ParseContext, 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().

01332 {
01333     ParseContext *context;
01334     int byte;
01335     List *unpacked;
01336     int code_page;
01337 
01338     unpacked = http_create_empty_headers();
01339     context = parse_context_create(headers);
01340 
01341     if (octstr_len(headers) > 0) {
01342         debug("wsp", 0, "WSP: decoding headers:");
01343         octstr_dump(headers, 0);
01344     }
01345 
01346     if (content_type_present)
01347         wsp_unpack_well_known_field(unpacked,
01348                                     WSP_HEADER_CONTENT_TYPE, context);
01349 
01350     code_page = 1;   /* default */
01351 
01352     while (parse_octets_left(context) > 0 && !parse_error(context)) {
01353         byte = parse_get_char(context);
01354 
01355         if (byte == 127 || (byte >= 1 && byte <= 31)) {
01356             if (byte == 127)
01357                 code_page = parse_get_char(context);
01358             else
01359                 code_page = byte;
01360             if (code_page == 1)
01361                 info(0, "Returning to code page 1 (default).");
01362             else {
01363                 warning(0, "Shift to unknown code page %d.",
01364                         code_page);
01365                 warning(0, "Will try to skip headers until "
01366                         "next known code page.");
01367             }
01368         } else if (byte >= 128) {  /* well-known-header */
01369             if (code_page == 1)
01370                 wsp_unpack_well_known_field(unpacked, byte - 128, context);
01371             else {
01372                 debug("wsp", 0, "Skipping field 0x%02x.", byte);
01373                 wsp_skip_field_value(context);
01374             }
01375         } else if (byte > 31 && byte < 127) {
01376             /* Un-parse the character we just read */
01377             parse_skip(context, -1);
01378             wsp_unpack_app_header(unpacked, context);
01379         } else {
01380             warning(0, "Unsupported token or header (start 0x%x)", byte);
01381             break;
01382         }
01383     }
01384 
01385     if (gwlist_len(unpacked) > 0) {
01386         long i;
01387 
01388         debug("wsp", 0, "WSP: decoded headers:");
01389         for (i = 0; i < gwlist_len(unpacked); i++) {
01390             Octstr *header = gwlist_get(unpacked, i);
01391             debug("wsp", 0, "%s", octstr_get_cstr(header));
01392         }
01393         debug("wsp", 0, "WSP: End of decoded headers.");
01394     }
01395 
01396     parse_context_destroy(context);
01397     return unpacked;
01398 }

Here is the call graph for this function:

int wsp_pack_application_header Octstr packed,
Octstr fieldname,
Octstr value
 

Definition at line 2930 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().

02932 {
02933     if (!is_token(fieldname)) {
02934         warning(0, "WSP headers: `%s' is not a valid HTTP token.",
02935                 octstr_get_cstr(fieldname));
02936         return -1;
02937     }
02938 
02939     /* We have to deal specially with the X-WAP.TOD header, because it
02940      * is the only case of a text-format header defined with a non-text
02941      * field value. */
02942     /* Normally this should be a case-insensitive comparison, but this
02943      * header will only be present if we generated it ourselves in the
02944      * application layer. */
02945     if (octstr_str_compare(fieldname, "X-WAP.TOD") == 0) {
02946         wsp_pack_text(packed, fieldname);
02947         return wsp_pack_date(packed, value);
02948     }
02949 
02950     wsp_pack_text(packed, fieldname);
02951     wsp_pack_text(packed, value);
02952     return 0;
02953 }

Here is the call graph for this function:

int wsp_pack_constrained_value Octstr packed,
Octstr text,
long  value
 

Definition at line 1873 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().

01874 {
01875     if (value >= 0)
01876         wsp_pack_short_integer(packed, value);
01877     else
01878         wsp_pack_text(packed, text);
01879     return 0;
01880 }

Here is the call graph for this function:

int wsp_pack_content_type Octstr packet,
Octstr value
 

Definition at line 2620 of file wsp_headers.c.

References pack_accept().

Referenced by wsp_pack_separate_content_type().

02621 {
02622     /* The expansion of Content-type-value works out to be
02623      * equivalent to Accept-value. */ 
02624     return pack_accept(packed, value);
02625 }

Here is the call graph for this function:

int wsp_pack_date Octstr packet,
Octstr value
 

Definition at line 2180 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().

02181 {
02182     long timeval;
02183 
02184     /* If we get a negative timeval here, this means either
02185      * we're beyond the time_t 32 bit int positive border for the 
02186      * timestamp or we're really handling time before epoch. */
02187     timeval = date_parse_http(value);
02188     if (timeval == -1) {
02189         warning(0, "WSP headers: cannot decode date '%s'",
02190                 octstr_get_cstr(value));
02191         return -1;
02192     }
02193 
02194     /* We'll assume that we don't package time before epoch. */
02195     wsp_pack_long_integer(packed, (unsigned long) timeval);
02196     return 0;
02197 }

Here is the call graph for this function:

int wsp_pack_integer_string Octstr packet,
Octstr value
 

Definition at line 1815 of file wsp_headers.c.

References 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().

01816 {
01817     unsigned long integer;
01818     long pos;
01819     int c;
01820     int digit;
01821 
01822     integer = 0;
01823     for (pos = 0; pos < octstr_len(value); pos++) {
01824         c = octstr_get_char(value, pos);
01825         if (!isdigit(c))
01826             break;
01827         digit = c - '0';
01828         if (integer > ULONG_MAX / 10)
01829             goto overflow;
01830         integer *= 10;
01831         if (integer > ULONG_MAX - digit)
01832             goto overflow;
01833         integer += digit;
01834     }
01835 
01836     wsp_pack_integer_value(packed, integer);
01837     return 0;
01838 
01839 overflow:
01840     warning(0, "WSP: Number too large to handle: '%s'.",
01841             octstr_get_cstr(value));
01842     return -1;
01843 }

Here is the call graph for this function:

void wsp_pack_integer_value Octstr packed,
unsigned long  integer
 

Definition at line 1807 of file wsp_headers.c.

References 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().

01808 {
01809     if (integer <= MAX_SHORT_INTEGER)
01810         wsp_pack_short_integer(packed, integer);
01811     else
01812         wsp_pack_long_integer(packed, integer);
01813 }

Here is the call graph for this function:

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

Definition at line 2863 of file wsp_headers.c.

References headerinfo::func, gwlist_consume(), headerinfo, octstr_delete(), octstr_destroy(), octstr_len(), and wsp_pack_short_integer().

Referenced by pack_known_header().

02864 {
02865     long startpos;
02866     Octstr *element;
02867 
02868     while ((element = gwlist_consume(elements))) {
02869         startpos = octstr_len(packed);
02870 
02871         wsp_pack_short_integer(packed, fieldnum);
02872         if (headerinfo[i].func(packed, element) < 0) {
02873             /* Remove whatever we added */
02874             octstr_delete(packed, startpos,
02875                           octstr_len(packed) - startpos);
02876             /* But continue processing elements */
02877         }
02878         octstr_destroy(element);
02879     }
02880     return 0;
02881 }

Here is the call graph for this function:

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().

01777 {
01778     long oldlen = octstr_len(packed);
01779     unsigned char octet;
01780     long len;
01781 
01782     if (integer == 0) {
01783     /* The Multi-octet-integer has to be at least 1 octet long. */
01784     octstr_append_char(packed, 1); /* length */
01785     octstr_append_char(packed, 0); /* value */
01786     return;
01787     }
01788 
01789     /* Encode it back-to-front, by repeatedly inserting
01790      * at the same position, because that's easier. */
01791     for (len = 0; integer != 0; integer >>= 8, len++) {
01792         octet = integer & 0xff;
01793         octstr_insert_data(packed, oldlen, (char *)&octet, 1);
01794     }
01795 
01796     octet = len;
01797     octstr_insert_data(packed, oldlen, (char *)&octet, 1);
01798 }

Here is the call graph for this function:

void wsp_pack_parameters Octstr packed,
List parms
 

Definition at line 1967 of file wsp_headers.c.

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

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

01968 {
01969     long i;
01970     Parameter *parm;
01971 
01972     for (i = 0; i < gwlist_len(parms); i++) {
01973         parm = gwlist_get(parms, i);
01974         pack_parameter(packed, parm);
01975     }
01976 }

Here is the call graph for this function:

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.

01628 {
01629      octstr_append_char(packed, '"');
01630      octstr_append(packed,text);
01631      octstr_append_char(packed,0);
01632      return 0;
01633 }

Here is the call graph for this function:

int wsp_pack_retry_after Octstr packet,
Octstr value
 

Definition at line 2721 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().

02722 {
02723     Octstr *encoded = NULL;
02724 
02725     encoded = octstr_create("");
02726     if (isdigit(octstr_get_char(value, 0))) {
02727         octstr_append_char(encoded, RELATIVE_TIME);
02728         if (wsp_pack_integer_string(encoded, value) < 0)
02729             goto error;
02730     } else {
02731         octstr_append_char(encoded, ABSOLUTE_TIME);
02732         if (wsp_pack_date(encoded, value) < 0)
02733             goto error;
02734     }
02735     wsp_pack_value(packed, encoded);
02736 
02737     octstr_destroy(encoded);
02738     return 0;
02739 
02740 error:
02741     octstr_destroy(encoded);
02742     return -1;
02743 }

Here is the call graph for this function:

void wsp_pack_separate_content_type Octstr packed,
List headers
 

Definition at line 2845 of file wsp_headers.c.

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

Referenced by wsp_headers_pack().

02846 {
02847     Octstr *content_type;
02848 
02849     /* Can't use http_header_get_content_type because it
02850      * does not parse all possible parameters. */
02851     content_type = http_header_find_first(headers, "Content-Type");
02852 
02853     if (content_type == NULL) {
02854         warning(0, "WSP: Missing Content-Type header in "
02855                 "response, guessing application/octet-stream");
02856         content_type = octstr_create("application/octet-stream");
02857     }
02858     octstr_strip_blanks(content_type);
02859     wsp_pack_content_type(packed, content_type);
02860     octstr_destroy(content_type);
02861 }

Here is the call graph for this function:

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().

01801 {
01802     gw_assert(integer <= MAX_SHORT_INTEGER);
01803 
01804     octstr_append_char(packed, integer + 0x80);
01805 }

Here is the call graph for this function:

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_if_range(), pack_language(), pack_parameter(), pack_uri(), pack_warning(), wsp_pack_application_header(), wsp_pack_constrained_value(), and wsp_pack_version_value().

01616 {
01617     /* This check catches 0-length strings as well, because
01618      * octstr_get_char will return -1. */
01619     if (octstr_get_char(text, 0) >= 128 || octstr_get_char(text, 0) < 32)
01620         octstr_append_char(packed, WSP_QUOTE);
01621     octstr_append(packed, text);
01622     octstr_append_char(packed, 0);
01623     return 0;
01624 }

Here is the call graph for this function:

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().

01762 {
01763     long len;
01764 
01765     len = octstr_len(encoded);
01766     if (len <= 30)
01767         octstr_append_char(packed, len);
01768     else {
01769         octstr_append_char(packed, 31);
01770         octstr_append_uintvar(packed, len);
01771     }
01772 
01773     octstr_append(packed, encoded);
01774 }

Here is the call graph for this function:

int wsp_pack_version_value Octstr packet,
Octstr value
 

Definition at line 1846 of file wsp_headers.c.

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

Referenced by pack_parameter().

01847 {
01848     long major, minor;
01849     long pos;
01850 
01851     pos = octstr_parse_long(&major, version, 0, 10);
01852     if (pos < 0 || major < 1 || major > 7)
01853         goto usetext;
01854 
01855     if (pos == octstr_len(version))
01856         minor = 15;
01857     else {
01858         if (octstr_get_char(version, pos) != '.')
01859             goto usetext;
01860         pos = octstr_parse_long(&minor, version, pos + 1, 10);
01861         if (pos != octstr_len(version) || minor < 0 || minor > 14)
01862             goto usetext;
01863     }
01864 
01865     wsp_pack_short_integer(packed, major << 4 | minor);
01866     return 0;
01867 
01868 usetext:
01869     wsp_pack_text(packed, version);
01870     return 0;
01871 }

Here is the call graph for this function:

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(), ParseContext, result, and unpack_multi_octet_integer().

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

00184 {
00185     int val;
00186     long length;
00187 
00188     val = parse_get_char(context);
00189     if (val == 0) {
00190         *result = 0;
00191         return WSP_FIELD_VALUE_NONE;
00192     } else if (val > 0 && val < 31) {
00193         *result = unpack_multi_octet_integer(context, val);
00194         return WSP_FIELD_VALUE_ENCODED;
00195     } else if (val == 31) {
00196         length = parse_get_uintvar(context);
00197         *result = unpack_multi_octet_integer(context, length);
00198         return WSP_FIELD_VALUE_ENCODED;
00199     } else if (val > 127) {
00200         *result = val - 128;
00201         return WSP_FIELD_VALUE_ENCODED;
00202     } else if (val == WSP_QUOTE) {  /* 127 */
00203         *result = -1;
00204         return WSP_FIELD_VALUE_NUL_STRING;
00205     } else {
00206         *result = -1;
00207         /* Un-parse the character we just read */
00208         parse_skip(context, -1);
00209         return WSP_FIELD_VALUE_NUL_STRING;
00210     }
00211 }

Here is the call graph for this function:

void wsp_skip_field_value ParseContext context  ) 
 

Definition at line 138 of file wsp_headers.c.

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

Referenced by wsp_headers_unpack().

00139 {
00140     int val;
00141     int ret;
00142 
00143     ret = wsp_field_value(context, &val);
00144     if (ret == WSP_FIELD_VALUE_DATA) {
00145         parse_skip_to_limit(context);
00146         parse_pop_limit(context);
00147     }
00148 }

Here is the call graph for this function:

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().

01554 {
01555     long pos;
01556     long len;
01557     int c;
01558     long end;
01559     List *parms;
01560     long firstparm;
01561 
01562     len = octstr_len(value);
01563     /* Find the start of the first parameter. */
01564     for (pos = 0; pos < len; pos++) {
01565         c = octstr_get_char(value, pos);
01566         if (c == ';')
01567             break;
01568         else if (c == '"')
01569             pos += http_header_quoted_string_len(value, pos) - 1;
01570     }
01571 
01572     if (pos >= len)
01573         return NULL;   /* no parameters */
01574 
01575     parms = gwlist_create();
01576     firstparm = pos;
01577 
01578     for (pos++; pos > 0 && pos < len; pos++) {
01579         Octstr *key = NULL;
01580         Octstr *val = NULL;
01581 
01582         end = octstr_search_char(value, '=', pos);
01583         if (end < 0)
01584             end = octstr_search_char(value, ';', pos);
01585         if (end < 0)
01586             end = octstr_len(value);
01587         key = octstr_copy(value, pos, end - pos);
01588         octstr_strip_blanks(key);
01589         pos = end;
01590 
01591         if (octstr_get_char(value, pos) == '=') {
01592             pos++;
01593             while (isspace(octstr_get_char(value, pos)))
01594                 pos++;
01595             if (octstr_get_char(value, pos) == '"')
01596                 end = pos + http_header_quoted_string_len(value, pos);
01597             else
01598                 end = octstr_search_char(value, ';', pos);
01599             if (end < 0)
01600                 end = octstr_len(value);
01601             val = octstr_copy(value, pos, end - pos);
01602             octstr_strip_blanks(val);
01603             pos = end;
01604             pos = octstr_search_char(value, ';', pos);
01605         }
01606 
01607         gwlist_append(parms, parm_create(key, val));
01608     }
01609 
01610     octstr_delete(value, firstparm, octstr_len(value) - firstparm);
01611     octstr_strip_blanks(value);
01612     return parms;
01613 }

Here is the call graph for this function:

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(), ParseContext, unpack_optional_q_value(), warning(), and wsp_secondary_field_value().

Referenced by wsp_unpack_well_known_field().

00558 {
00559     Octstr *decoded = NULL;
00560     int ret;
00561     long val;
00562 
00563     ret = wsp_secondary_field_value(context, &val);
00564     if (parse_error(context) || ret == WSP_FIELD_VALUE_NONE) {
00565         warning(0, "Bad accept-charset-general-form");
00566         return NULL;
00567     }
00568 
00569     if (ret == WSP_FIELD_VALUE_ENCODED) {
00570         decoded = wsp_charset_to_string(val);
00571         if (!decoded) {
00572             warning(0, "Unknown character set %04lx.", val);
00573             return NULL;
00574         }
00575     } else if (ret == WSP_FIELD_VALUE_NUL_STRING) {
00576         decoded = parse_get_nul_string(context);
00577         if (!decoded) {
00578             warning(0, "Format error in accept-charset");
00579             return NULL;
00580         }
00581     } else {
00582         panic(0, "Unknown secondary field value type %d.", ret);
00583     }
00584 
00585     unpack_optional_q_value(context, decoded);
00586     return decoded;
00587 }

Here is the call graph for this function:

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(), ParseContext, warning(), wsp_secondary_field_value(), and wsp_unpack_all_parameters().

Referenced by wsp_unpack_well_known_field().

00514 {
00515     Octstr *decoded = NULL;
00516     int ret;
00517     long val;
00518 
00519     /* The definition for Accept-general-form looks quite complicated,
00520      * but the "Q-token Q-value" part fits the normal expansion of
00521      * Parameter, so it simplifies to:
00522      *  Value-length Media-range *(Parameter)
00523      * and we've already parsed Value-length.
00524      */
00525 
00526     /* We use this function to parse content-general-form too,
00527      * because its definition of Media-type is identical to Media-range.
00528      */
00529 
00530     ret = wsp_secondary_field_value(context, &val);
00531     if (parse_error(context) || ret == WSP_FIELD_VALUE_NONE) {
00532         warning(0, "bad media-range or media-type");
00533         return NULL;
00534     }
00535 
00536     if (ret == WSP_FIELD_VALUE_ENCODED) {
00537         decoded = wsp_content_type_to_string(val);
00538         if (!decoded) {
00539             warning(0, "Unknown content type 0x%02lx.", val);
00540             return NULL;
00541         }
00542     } else if (ret == WSP_FIELD_VALUE_NUL_STRING) {
00543         decoded = parse_get_nul_string(context);
00544         if (!decoded) {
00545             warning(0, "Format error in content type");
00546             return NULL;
00547         }
00548     } else {
00549         panic(0, "Unknown secondary field value type %d.", ret);
00550     }
00551 
00552     wsp_unpack_all_parameters(context, decoded);
00553     return decoded;
00554 }

Here is the call graph for this function:

void wsp_unpack_all_parameters ParseContext context,
Octstr decoded
 

Definition at line 443 of file wsp_headers.c.

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

Referenced by unpack_disposition(), and wsp_unpack_accept_general_form().

00444 {
00445     int ret = 0;
00446 
00447     while (ret >= 0 && !parse_error(context) &&
00448            parse_octets_left(context) > 0) {
00449         ret = unpack_parameter(context, decoded);
00450     }
00451 }

Here is the call graph for this function:

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(), ParseContext, and warning().

Referenced by wsp_headers_unpack().

01312 {
01313     Octstr *header = NULL;
01314     Octstr *value = NULL;
01315 
01316     header = parse_get_nul_string(context);
01317     value = parse_get_nul_string(context);
01318 
01319     if (header && value) {
01320         http_header_add(unpacked, octstr_get_cstr(header),
01321                         octstr_get_cstr(value));
01322     }
01323 
01324     if (parse_error(context))
01325         warning(0, "Error parsing application-header.");
01326 
01327     octstr_destroy(header);
01328     octstr_destroy(value);
01329 }

Here is the call graph for this function:

Octstr* wsp_unpack_date_value ParseContext context  ) 
 

Definition at line 492 of file wsp_headers.c.

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

Referenced by unpack_retry_after(), and wsp_unpack_well_known_field().

00493 {
00494     unsigned long timeval;
00495     int length;
00496 
00497     length = parse_get_char(context);
00498     if (length > 30) {
00499         warning(0, "WSP headers: bad date-value.");
00500         return NULL;
00501     }
00502 
00503     timeval = unpack_multi_octet_integer(context, length);
00504     if (timeval < 0) {
00505         warning(0, "WSP headers: cannot unpack date-value.");
00506         return NULL;
00507     }
00508 
00509     return date_format_http(timeval);
00510 }

Here is the call graph for this function:

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(), ParseContext, unpack_multi_octet_integer(), and warning().

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

00215 {
00216     Octstr *decoded;
00217     unsigned long value;
00218     int val;
00219 
00220     val = parse_get_char(context);
00221     if (val < 31) {
00222         value = unpack_multi_octet_integer(context, val);
00223     } else if (val > 127) {
00224         value = val - 128;
00225     } else {
00226         warning(0, "WSP headers: bad integer-value.");
00227         return NULL;
00228     }
00229 
00230     decoded = octstr_create("");
00231     octstr_append_decimal(decoded, value);
00232     return decoded;
00233 }

Here is the call graph for this function:

Octstr* wsp_unpack_version_value long  value  ) 
 

Definition at line 291 of file wsp_headers.c.

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

Referenced by unpack_encoding_version(), and unpack_parameter().

00292 {
00293     Octstr *result;
00294     int major, minor;
00295 
00296     major = ((value >> 4) & 0x7);
00297     minor = (value & 0xf);
00298 
00299     result = octstr_create("");
00300     octstr_append_char(result, major + '0');
00301     if (minor != 15) {
00302         octstr_append_char(result, '.');
00303         octstr_append_decimal(result, minor);
00304     }
00305 
00306     return result;
00307 }

Here is the call graph for this function:

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(), ParseContext, 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_unpack_accept_charset_general_form(), wsp_unpack_accept_general_form(), and wsp_unpack_date_value().

Referenced by wsp_headers_unpack().

01032 {
01033     int val, ret;
01034     unsigned char *headername = NULL;
01035     unsigned char *ch = NULL;
01036     Octstr *decoded = NULL;
01037 
01038     ret = wsp_field_value(context, &val);
01039     if (parse_error(context)) {
01040         warning(0, "Faulty header, skipping remaining headers.");
01041         parse_skip_to_limit(context);
01042         return;
01043     }
01044 
01045     headername = wsp_header_to_cstr(field_type);
01046     /* headername can still be NULL.  This is checked after parsing
01047      * the field value.  We want to parse the value before exiting,
01048      * so that we are ready for the next header. */
01049 
01050     /* The following code must set "ch" or "decoded" to a non-NULL
01051      * value if the header is valid. */
01052 
01053     if (ret == WSP_FIELD_VALUE_NUL_STRING) {
01054         /* We allow any header to have a text value, even if that
01055          * is not defined in the grammar.  Be generous in what
01056          * you accept, etc. */
01057         /* This covers Text-string, Token-Text, and Uri-value rules */
01058         decoded = parse_get_nul_string(context);
01059     } else if (ret == WSP_FIELD_VALUE_ENCODED) {
01060         switch (field_type) {
01061         case WSP_HEADER_ACCEPT:
01062         case WSP_HEADER_CONTENT_TYPE:
01063             ch = wsp_content_type_to_cstr(val);
01064             if (!ch)
01065                 warning(0, "Unknown content type 0x%02x.", val);
01066             break;
01067 
01068         case WSP_HEADER_ACCEPT_CHARSET:
01069             ch = wsp_charset_to_cstr(val);
01070             if (!ch)
01071                 warning(0, "Unknown charset 0x%02x.", val);
01072             break;
01073 
01074         case WSP_HEADER_ACCEPT_ENCODING:
01075         case WSP_HEADER_CONTENT_ENCODING:
01076             ch = wsp_encoding_to_cstr(val);
01077             if (!ch)
01078                 warning(0, "Unknown encoding 0x%02x.", val);
01079             break;
01080 
01081         case WSP_HEADER_ACCEPT_LANGUAGE:
01082         case WSP_HEADER_CONTENT_LANGUAGE:
01083             ch = wsp_language_to_cstr(val);
01084             if (!ch)
01085                 warning(0, "Unknown language 0x%02x.", val);
01086             break;
01087 
01088         case WSP_HEADER_ACCEPT_RANGES:
01089             ch = wsp_ranges_to_cstr(val);
01090             if (!ch)
01091                 warning(0, "Unknown ranges value 0x%02x.", val);
01092             break;
01093 
01094         case WSP_HEADER_AGE:
01095         case WSP_HEADER_CONTENT_LENGTH:
01096         case WSP_HEADER_MAX_FORWARDS:
01097             /* Short-integer version of Integer-value */
01098             decoded = octstr_create("");
01099             octstr_append_decimal(decoded, val);
01100             break;
01101 
01102         case WSP_HEADER_ALLOW:
01103         case WSP_HEADER_PUBLIC:
01104             ch = wsp_method_to_cstr(val);
01105             if (!ch) {
01106                 /* FIXME Support extended methods */
01107                 warning(0, "Unknown method 0x%02x.", val);
01108             }
01109             break;
01110 
01111         case WSP_HEADER_CACHE_CONTROL:
01112         case WSP_HEADER_CACHE_CONTROL_V13:
01113         case WSP_HEADER_CACHE_CONTROL_V14:
01114             ch = wsp_cache_control_to_cstr(val);
01115             if (!ch)
01116                 warning(0, "Unknown cache-control value 0x%02x.", val);
01117             break;
01118 
01119         case WSP_HEADER_CONNECTION:
01120             ch = wsp_connection_to_cstr(val);
01121             if (!ch)
01122                 warning(0, "Unknown connection value 0x%02x.", val);
01123             break;
01124 
01125 
01126         case WSP_HEADER_PRAGMA:
01127             if (val == 0)
01128                 ch = (unsigned char *)"no-cache";
01129             else
01130                 warning(0, "Unknown pragma value 0x%02x.", val);
01131             break;
01132 
01133         case WSP_HEADER_TRANSFER_ENCODING:
01134             ch = wsp_transfer_encoding_to_cstr(val);
01135             if (!ch)
01136                 warning(0, "Unknown transfer encoding value 0x%02x.", val);
01137             break;
01138 
01139         case WSP_HEADER_VARY:
01140             ch = wsp_header_to_cstr(val);
01141             if (!ch)
01142                 warning(0, "Unknown Vary field name 0x%02x.", val);
01143             break;
01144 
01145         case WSP_HEADER_WARNING:
01146             decoded = octstr_create("");
01147             octstr_append_decimal(decoded, val);
01148             break;
01149 
01150         case WSP_HEADER_BEARER_INDICATION:
01151              ch = wsp_bearer_indication_to_cstr(val);
01152              if (!ch)
01153                  warning(0, "Unknown Bearer-Indication field name 0x%02x.", val);
01154              break;
01155 
01156         case WSP_HEADER_ACCEPT_APPLICATION:
01157              ch = wsp_application_id_to_cstr(val);
01158              if (!ch)
01159                  warning(0, "Unknown Accept-Application field name 0x%02x.", val);
01160              break;
01161 
01162         default:
01163             if (headername) {
01164                 warning(0, "Did not expect short-integer with "
01165                         "'%s' header, skipping.", headername);
01166             }
01167             break;
01168         }
01169     } else if (ret == WSP_FIELD_VALUE_DATA) {
01170         switch (field_type) {
01171         case WSP_HEADER_ACCEPT:
01172         case WSP_HEADER_CONTENT_TYPE:
01173             /* Content-general-form and Accept-general-form
01174              * are defined separately in WSP, but their
01175              * definitions are equivalent. */
01176             decoded = wsp_unpack_accept_general_form(context);
01177             break;
01178 
01179         case WSP_HEADER_ACCEPT_CHARSET:
01180             decoded = wsp_unpack_accept_charset_general_form(context);
01181             break;
01182 
01183         case WSP_HEADER_ACCEPT_LANGUAGE:
01184             decoded = unpack_accept_language_general_form(context);
01185             break;
01186 
01187         case WSP_HEADER_AGE:
01188         case WSP_HEADER_CONTENT_LENGTH:
01189         case WSP_HEADER_MAX_FORWARDS:
01190         case WSP_HEADER_BEARER_INDICATION:
01191         case WSP_HEADER_ACCEPT_APPLICATION:
01192             /* Long-integer version of Integer-value */
01193             {
01194                 long l = unpack_multi_octet_integer(context,
01195                                                     parse_octets_left(context));
01196                 decoded = octstr_create("");
01197                 octstr_append_decimal(decoded, l);
01198             }
01199             break;
01200 
01201         case WSP_HEADER_AUTHORIZATION:
01202             decoded = unpack_credentials(context);
01203             break;
01204 
01205         case WSP_HEADER_PROXY_AUTHORIZATION:
01206             decoded = proxy_unpack_credentials(context);
01207             break;
01208 
01209         case WSP_HEADER_CACHE_CONTROL:
01210             decoded = unpack_cache_directive(context);
01211             break;
01212 
01213         case WSP_HEADER_CONTENT_MD5:
01214             decoded = parse_get_octets(context,
01215                                        parse_octets_left(context));
01216             octstr_binary_to_base64(decoded);
01217             /* Zap the CR LF sequence at the end */
01218             octstr_delete(decoded, octstr_len(decoded) - 2, 2);
01219             break;
01220 
01221         case WSP_HEADER_CONTENT_RANGE:
01222             decoded = unpack_content_range(context);
01223             break;
01224 
01225         case WSP_HEADER_DATE:
01226         case WSP_HEADER_EXPIRES:
01227         case WSP_HEADER_IF_MODIFIED_SINCE:
01228         case WSP_HEADER_IF_RANGE:
01229         case WSP_HEADER_IF_UNMODIFIED_SINCE:
01230         case WSP_HEADER_LAST_MODIFIED:
01231             /* Back up to get the length byte again */
01232             parse_skip(context, -1);
01233             decoded = wsp_unpack_date_value(context);
01234             break;
01235 
01236         case WSP_HEADER_PRAGMA:
01237             /* The value is a bare Parameter, without a preceding
01238              * header body.  unpack_parameter wasn't really
01239              * designed for this.  We work around it here. */
01240             decoded = octstr_create("");
01241             if (unpack_parameter(context, decoded) < 0) {
01242                 octstr_destroy(decoded);
01243                 decoded = NULL;
01244             } else {
01245                 /* Remove the leading "; " */
01246                 octstr_delete(decoded, 0, 2);
01247             }
01248             break;
01249 
01250         case WSP_HEADER_PROXY_AUTHENTICATE:
01251         case WSP_HEADER_WWW_AUTHENTICATE:
01252             decoded = unpack_challenge(context);
01253             break;
01254 
01255         case WSP_HEADER_RANGE:
01256             decoded = unpack_range_value(context);
01257             break;
01258 
01259         case WSP_HEADER_RETRY_AFTER:
01260             decoded = unpack_retry_after(context);
01261             break;
01262 
01263         case WSP_HEADER_WARNING:
01264             decoded = unpack_warning_value(context);
01265             break;
01266 
01267         case WSP_HEADER_CONTENT_DISPOSITION:
01268             decoded = unpack_disposition(context);
01269             break;
01270 
01271         case WSP_HEADER_ENCODING_VERSION:
01272             decoded = unpack_encoding_version(context);
01273             break;
01274 
01275         default:
01276             if (headername) {
01277                 warning(0, "Did not expect value-length with "
01278                         "'%s' header, skipping.", headername);
01279             }
01280             break;
01281         }
01282         if (headername && parse_octets_left(context) > 0) {
01283             warning(0, "WSP: %s: skipping %ld trailing octets.",
01284                     headername, parse_octets_left(context));
01285         }
01286         parse_skip_to_limit(context);
01287         parse_pop_limit(context);
01288     } else {
01289         panic(0, "Unknown field-value type %d.", ret);
01290     }
01291 
01292     if (ch == NULL && decoded != NULL)
01293         ch = (unsigned char *)octstr_get_cstr(decoded);
01294     if (ch == NULL)
01295         goto value_error;
01296 
01297     if (!headername) {
01298         warning(0, "Unknown header number 0x%02x.", field_type);
01299         goto value_error;
01300     }
01301 
01302     http_header_add(unpacked, (char *)headername,(char *) ch);
01303     octstr_destroy(decoded);
01304     return;
01305 
01306 value_error:
01307     warning(0, "Skipping faulty header.");
01308     octstr_destroy(decoded);
01309 }

Here is the call graph for this function:

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