PPG fixes
Aarno Syvänen <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi List, Some new PPG fixes (see attachment). There are mostly about performance, removing some useless octstr_append_char. In addition, PPG now do not search optional headers from the message body. For doing this a new octstr function is supplied. And, yes, there is a small memory leak in msg.c and a strange debug in bearerbox.c Aarno
cvs.diff
(application/octet-stream, 17.8 KB)
Index: gw/bearerbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/bearerbox.c,v
retrieving revision 1.146
diff -u -B -b -r1.146 bearerbox.c
--- gw/bearerbox.c 30 Oct 2003 19:20:30 -0000 1.146
+++ gw/bearerbox.c 4 Nov 2003 14:02:31 -0000
@@ -542,7 +542,6 @@
/* debug("bb", 0, "Main Thread: woken up."); */
if (bb_todo == 0) {
- debug("bb", 0, "Main Thread: Nothing todo.");
continue;
}
Index: gw/msg.c
===================================================================
RCS file: /home/cvs/gateway/gw/msg.c,v
retrieving revision 1.29
diff -u -B -b -r1.29 msg.c
--- gw/msg.c 13 Oct 2003 20:52:18 -0000 1.29
+++ gw/msg.c 4 Nov 2003 14:02:31 -0000
@@ -163,6 +163,7 @@
error:
error(0, "Msg packet was invalid.");
+ msg_destroy(msg);
return NULL;
}
Index: gw/wap_push_pap_mime.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_pap_mime.c,v
retrieving revision 1.9
diff -u -B -b -r1.9 wap_push_pap_mime.c
--- gw/wap_push_pap_mime.c 6 Aug 2003 09:46:26 -0000 1.9
+++ gw/wap_push_pap_mime.c 4 Nov 2003 14:02:32 -0000
@@ -26,10 +26,10 @@
Octstr **push_data, List **content_headers,
Octstr **rdf_content);
static int check_control_headers(Octstr **body_part);
-static int check_control_content_type_header(Octstr **body_part);
-static int drop_optional_header(Octstr **body_part, char *name);
+static int check_control_content_type_header(Octstr **body_part, Octstr *boundary);
+static int drop_optional_header(Octstr **body_part, char *name, Octstr *boundary);
static int drop_header_true(Octstr **body_part, long content_pos);
-static int drop_extension_headers(Octstr **mime_content);
+static int drop_extension_headers(Octstr **mime_content, Octstr *boundary);
static long parse_field_value(Octstr *pap_content, long pos);
static long parse_field_name(Octstr *pap_content, long pos);
static void octstr_split_by_pos(Octstr **mime_content, Octstr **pap_content,
@@ -38,11 +38,10 @@
static Octstr *make_part_delimiter(Octstr *boundary);
static Octstr *make_start_delimiter(Octstr *dash_boundary);
static int pass_data_headers(Octstr **body_part, List **data_headers);
-static int check_data_content_type_header(Octstr **body_part,
- List **data_headers);
-static int pass_optional_header(Octstr **body_part, char *name,
- List **content_headers);
-static int pass_extension_headers(Octstr **body_part, List **data_headers);
+static int check_data_content_type_header(Octstr **body_part, List **data_headers, Octstr *boundary);
+static int pass_optional_header(Octstr **body_part, char *name, List **content_headers,
+ Octstr *boundary);
+static int pass_extension_headers(Octstr **body_part, List **data_headers, Octstr *boundary);
static long pass_field_name(Octstr **body_part, Octstr **content_header,
long pos);
static long pass_field_value(Octstr **body_part, Octstr **content_header,
@@ -249,7 +248,6 @@
boundary_pos = octstr_search(*multipart, part_delimiter, 0);
if (boundary_pos == close_delimiter_pos) {
- *body_part = octstr_create("");
octstr_split_by_pos(multipart, body_part, close_delimiter_pos);
if ((epilogue_pos =
parse_close_delimiter(close_delimiter, *multipart, 0)) < 0)
@@ -259,7 +257,6 @@
goto last_part;
}
- *body_part = octstr_create("");
octstr_split_by_pos(multipart, body_part, boundary_pos);
if (parse_tail(multipart, part_delimiter, 0, &next_part_pos) < 0) {
@@ -290,6 +287,9 @@
* entity (containing the push message). So we must have at least one body
* part here, and at most two (MIME grammar in rfc 2046, appendix A sets no
* limitations here).
+ * Input: mime content, part boundary
+ * Output: Push content, rdf content if present, content headers. In addi-
+ * tion, modified mime content (without parsed parts).
* Returns 1, if rdf content was present
* 0, if it was absent
* -1, when error
@@ -326,15 +326,8 @@
static void octstr_split_by_pos(Octstr **os1, Octstr **os2,
long boundary_pos)
{
- long i;
-
- for (i = 0; i < boundary_pos; i++) {
- octstr_format_append(*os2, "%c", octstr_get_char(*os1, i));
- }
-
- for (i = 0; i < boundary_pos; i++) {
- octstr_delete(*os1, 0, 1);
- }
+ *os2 = octstr_copy(*os1, 0, boundary_pos);
+ octstr_delete(*os1, 0, boundary_pos);
}
static Octstr *make_close_delimiter(Octstr *boundary)
@@ -351,10 +344,7 @@
{
Octstr *part_delimiter;
- part_delimiter = octstr_create("");
- octstr_format_append(part_delimiter, "%c", '\r');
- octstr_format_append(part_delimiter, "%c", '\n');
- octstr_format_append(part_delimiter, "%s", "--");
+ part_delimiter = octstr_create("\r\n--");
octstr_append(part_delimiter, dash_boundary);
return part_delimiter;
@@ -364,8 +354,7 @@
{
Octstr *start_delimiter;
- start_delimiter = octstr_create("");
- octstr_format_append(start_delimiter, "%s", "--");
+ start_delimiter = octstr_create("--");
octstr_append(start_delimiter, dash_boundary);
return start_delimiter;
@@ -376,31 +365,35 @@
* Rfc 2045, Appendix A does not specify the order of entity headers and states
* that all rfc 822 headers having a string "Content" in their field-name must
* be accepted. Rfc 822 grammar is capitulated in appendix D.
+ * Message starts after the first null line, so only something after it can be
+ * an extension header (or any header).
*/
static int check_control_headers(Octstr **body_part)
{
- if (check_control_content_type_header(body_part) == 0)
+ if (check_control_content_type_header(body_part, octstr_imm("\r\n\r\n")) == 0)
return 0;
- if (drop_optional_header(body_part, "Content-Transfer-Encoding:") == 0)
+ if (drop_optional_header(body_part, "Content-Transfer-Encoding:",
+ octstr_imm("\r\n\r\n")) == 0)
return 0;
- if (drop_optional_header(body_part, "Content-ID:") == 0)
+ if (drop_optional_header(body_part, "Content-ID:", octstr_imm("\r\n\r\n")) == 0)
return 0;
- if (drop_optional_header(body_part, "Content-Description:") == 0)
+ if (drop_optional_header(body_part, "Content-Description:", octstr_imm("\r\n\r\n")) == 0)
return 0;
- if (drop_extension_headers(body_part) == 0)
+ if (drop_extension_headers(body_part, octstr_imm("\r\n\r\n")) == 0)
return 0;
return 1;
}
-static int check_control_content_type_header(Octstr **body_part)
+static int check_control_content_type_header(Octstr **body_part, Octstr *boundary)
{
long content_pos;
+ long message_start_pos;
- if ((content_pos = octstr_case_search(*body_part,
- octstr_imm("Content-Type:"), 0)) < 0 ||
- octstr_case_search(*body_part,
- octstr_imm("application/xml"), 0) < 0) {
+ message_start_pos = octstr_search(*body_part, boundary, 0);
+ if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content-Type:"), 0,
+ message_start_pos)) < 0 ||
+ octstr_case_search(*body_part, octstr_imm("application/xml"), 0) < 0) {
return 0;
}
@@ -429,13 +422,15 @@
return 1;
}
-static int drop_optional_header(Octstr **body_part, char *name)
+static int drop_optional_header(Octstr **body_part, char *name, Octstr *boundary)
{
long content_pos;
+ long message_start_pos;
content_pos = -1;
- if ((content_pos = octstr_case_search(*body_part,
- octstr_imm(name), 0)) < 0)
+ message_start_pos = octstr_search(*body_part, boundary, 0);
+
+ if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm(name), 0, message_start_pos)) < 0)
return 1;
if (drop_header_true(body_part, content_pos) < 0)
@@ -447,16 +442,19 @@
/*
* Extension headers are defined in rfc 822, Appendix D, as fields. We must
* parse all rfc 822 headers containing a string "Content". These headers
- * are optional, too.
+ * are optional, too. For general definition of message parts see chapter 4.1.
+ * Specifically: "everything after first null line is message body".
*/
-static int drop_extension_headers(Octstr **body_part)
+static int drop_extension_headers(Octstr **body_part, Octstr *boundary)
{
long content_pos,
next_header_pos;
+ long next_content_part_pos;
+ next_content_part_pos = octstr_case_search(*body_part, boundary, 0);
do {
- if ((content_pos = octstr_case_search(*body_part,
- octstr_imm("Content"), 0)) < 0)
+ if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,
+ next_content_part_pos)) < 0)
return 1;
if ((next_header_pos = parse_field_name(*body_part, content_pos)) < 0)
return 0;
@@ -520,20 +518,20 @@
{
*data_headers = http_create_empty_headers();
- if (check_data_content_type_header(body_part, data_headers) == 0) {
+ if (check_data_content_type_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
warning(0, "MIME: pass_data_headers: Content-Type header missing");
return 0;
}
- if (pass_optional_header(body_part, "Content-Transfer-Encoding",
- data_headers) < 0)
+ if (pass_optional_header(body_part, "Content-Transfer-Encoding", data_headers,
+ octstr_imm("\r\n\r\n")) < 0)
goto operror;
- if (pass_optional_header(body_part, "Content-ID", data_headers) < 0)
+ if (pass_optional_header(body_part, "Content-ID", data_headers, octstr_imm("\r\n\r\n")) < 0)
goto operror;
- if (pass_optional_header(body_part, "Content-Description",
- data_headers) < 0)
+ if (pass_optional_header(body_part, "Content-Description", data_headers,
+ octstr_imm("\r\n\r\n")) < 0)
goto operror;
- if (pass_extension_headers(body_part, data_headers) == 0)
+ if (pass_extension_headers(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0)
goto operror;
return 1;
@@ -545,28 +543,30 @@
/*
* Checks if body_part contains a Content-Type header. Tranfers this header to
- * a list content_headers.
+ * a list content_headers. (Only part before 'boundary').
* Return 1, when Content-Type headers was found, 0 otherwise
*/
-static int check_data_content_type_header(Octstr **body_part,
- List **content_headers)
+static int check_data_content_type_header(Octstr **body_part, List **content_headers,
+ Octstr *boundary)
{
long header_pos,
next_header_pos;
Octstr *content_header;
+ long message_start_pos;
header_pos = next_header_pos = -1;
content_header = octstr_create("Content-Type");
+ message_start_pos = octstr_search(*body_part, boundary, 0);
- if ((header_pos = octstr_case_search(*body_part, content_header, 0)) < 0) {
+ if ((header_pos = octstr_case_nsearch(*body_part, content_header, 0,
+ message_start_pos)) < 0) {
goto error;
}
if ((next_header_pos = pass_field_value(body_part, &content_header,
header_pos + octstr_len(content_header))) < 0) {
goto error;
}
- if ((next_header_pos =
- parse_terminator(*body_part, next_header_pos)) < 0) {
+ if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) < 0) {
goto error;
}
@@ -584,20 +584,23 @@
/*
* We try to find an optional header, so a failure to find one is not an
* error. Return -1 when error, 0 when header name not found, 1 otherwise.
+ * Search only until 'boundary'.
*/
-static int pass_optional_header(Octstr **body_part, char *name,
- List **content_headers)
+static int pass_optional_header(Octstr **body_part, char *name, List **content_headers,
+ Octstr *boundary)
{
long content_pos,
next_header_pos;
Octstr *osname,
*osvalue;
+ long message_start_pos;
content_pos = next_header_pos = -1;
osname = octstr_create(name);
osvalue = octstr_create("");
+ message_start_pos = octstr_search(*body_part, boundary, 0);
- if ((content_pos = octstr_case_search(*body_part, osname, 0)) < 0)
+ if ((content_pos = octstr_case_nsearch(*body_part, osname, 0, message_start_pos)) < 0)
goto noheader;
if ((next_header_pos = pass_field_value(body_part, &osvalue,
content_pos + octstr_len(osname))) < 0)
@@ -656,23 +659,26 @@
/*
* Extension headers are optional, see Push Message, chapter 6.2. Field struc-
* ture is defined in rfc 822, chapter 3.2. Extension headers are defined in
- * rfc 2045, chapter 9, grammar in appendix A.
+ * rfc 2045, chapter 9, grammar in appendix A. (Only to the next null line).
* Return 0 when error, 1 otherwise.
*/
-static int pass_extension_headers(Octstr **body_part, List **content_headers)
+static int pass_extension_headers(Octstr **body_part, List **content_headers, Octstr *boundary)
{
long next_field_part_pos,
count;
Octstr *header_name,
*header_value;
+ long next_content_part_pos;
header_name = octstr_create("");
header_value = octstr_create("");
count = 0;
next_field_part_pos = 0;
+ next_content_part_pos = octstr_search(*body_part, boundary, 0);
do {
- if ((octstr_case_search(*body_part, octstr_imm("Content"), 0)) < 0)
+ if ((octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,
+ next_content_part_pos)) < 0)
goto end;
if ((next_field_part_pos = pass_field_name(body_part, &header_name,
next_field_part_pos)) < 0)
@@ -709,16 +715,23 @@
long pos)
{
int c;
+ long start;
+ Octstr *field = NULL;
+ start = pos;
while (!is_cr(c = octstr_get_char(*body_part, pos)) &&
pos < octstr_len(*body_part)) {
- octstr_format_append(*header, "%c", c);
++pos;
}
- if (pos == octstr_len(*body_part))
+ if (pos == octstr_len(*body_part)) {
return -1;
+ }
+
+ field = octstr_copy(*body_part, start, pos - start);
+ octstr_append(*header, field);
+ octstr_destroy(field);
return pos;
}
@@ -726,16 +739,23 @@
long pos)
{
int c;
+ long start;
+ Octstr *name = NULL;
+ start = pos;
while (((c = octstr_get_char(*body_part, pos)) != ':') &&
pos < octstr_len(*body_part)) {
- octstr_format_append(*field_part, "%c", c);
++pos;
}
- if (pos == octstr_len(*body_part))
+ if (pos == octstr_len(*body_part)) {
return -1;
+ }
+
+ name = octstr_copy(*body_part, start, pos - start);
+ octstr_append(*field_part, name);
+ octstr_destroy(name);
return pos;
}
Index: gw/wap_push_ppg.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_ppg.c,v
retrieving revision 1.60
diff -u -B -b -r1.60 wap_push_ppg.c
--- gw/wap_push_ppg.c 7 Oct 2003 22:58:42 -0000 1.60
+++ gw/wap_push_ppg.c 4 Nov 2003 14:02:32 -0000
@@ -2867,10 +2867,7 @@
if (octstr_case_search(content_header, osname, 0) >= 0)
return 1;
- quoted_type = octstr_create("");
- octstr_format_append(quoted_type, "%c", '\"');
- octstr_append(quoted_type, osname);
- octstr_format_append(quoted_type, "%c", '\"');
+ quoted_type = octstr_format("\"%S\"", osname);
if (octstr_case_search(content_header, quoted_type, 0) >= 0) {
octstr_destroy(quoted_type);
@@ -2891,6 +2888,7 @@
long pos;
Octstr *bos;
int c, quoted = 0;
+ long bstart;
pos = 0;
if ((pos = octstr_case_search(content_header,
@@ -2904,13 +2902,14 @@
++pos;
quoted = 1;
}
- *boundary = octstr_create("");
+
+ bstart = pos;
while ((c = octstr_get_char(content_header, pos)) != -1) {
if (c == ';' || (quoted && c == '"') || (!quoted && c == ' '))
break;
- octstr_format_append(*boundary, "%c", c);
++pos;
}
+ *boundary = octstr_copy(content_header, bstart, pos - bstart);
return 0;
}
Index: gwlib/octstr.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/octstr.c,v
retrieving revision 1.151
diff -u -B -b -r1.151 octstr.c
--- gwlib/octstr.c 9 Sep 2003 21:16:19 -0000 1.151
+++ gwlib/octstr.c 4 Nov 2003 14:02:33 -0000
@@ -941,6 +941,33 @@
return -1;
}
+int octstr_case_nsearch(Octstr *haystack, Octstr *needle, long pos, long n)
+{
+ long i, j;
+ int c1, c2;
+
+ seems_valid(haystack);
+ seems_valid(needle);
+ gw_assert(pos >= 0);
+
+ /* Always "find" an empty string */
+ if (needle->len == 0)
+ return 0;
+
+ for (i = pos; i <= haystack->len - needle->len && i < n; ++i) {
+ for (j = 0; j < needle->len && j < n; ++j) {
+ c1 = toupper(haystack->data[i + j]);
+ c2 = toupper(needle->data[j]);
+ if (c1 != c2)
+ break;
+ }
+ if (j == needle->len)
+ return i;
+ }
+
+ return -1;
+}
+
int octstr_print(FILE *f, Octstr *ostr)
{
Index: gwlib/octstr.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/octstr.h,v
retrieving revision 1.78
diff -u -B -b -r1.78 octstr.h
--- gwlib/octstr.h 20 Jul 2003 12:09:46 -0000 1.78
+++ gwlib/octstr.h 4 Nov 2003 14:02:33 -0000
@@ -307,6 +307,10 @@
*/
int octstr_case_search(Octstr *haystack, Octstr *needle, long pos);
+/*
+ * Like octstr_case_search, but searchs only first n octets.
+ */
+int octstr_case_nsearch(Octstr *haystack, Octstr *needle, long pos, long n);
/*
* Write contents of octet string to a file, in human readable form.