1 | /* |
---|
2 | * Copyright (C) 1996-2015 The Squid Software Foundation and contributors |
---|
3 | * |
---|
4 | * Squid software is distributed under GPLv2+ license and includes |
---|
5 | * contributions from numerous individuals and organizations. |
---|
6 | * Please see the COPYING and CONTRIBUTORS files for details. |
---|
7 | */ |
---|
8 | |
---|
9 | /* DEBUG: section 25 MiME Header Parsing */ |
---|
10 | |
---|
11 | #include "squid.h" |
---|
12 | |
---|
13 | #define GET_HDR_SZ 1024 |
---|
14 | #include "Debug.h" |
---|
15 | #include "profiler/Profiler.h" |
---|
16 | |
---|
17 | /* |
---|
18 | * returns a pointer to a field-value of the first matching field-name where |
---|
19 | * field-value matches prefix if any |
---|
20 | */ |
---|
21 | char * |
---|
22 | mime_get_header_field(const char *mime, const char *name, const char *prefix) |
---|
23 | { |
---|
24 | LOCAL_ARRAY(char, header, GET_HDR_SZ); |
---|
25 | const char *p = NULL; |
---|
26 | char *q = NULL; |
---|
27 | char got = 0; |
---|
28 | const int namelen = name ? strlen(name) : 0; |
---|
29 | const int preflen = prefix ? strlen(prefix) : 0; |
---|
30 | int l; |
---|
31 | |
---|
32 | if (NULL == mime) |
---|
33 | return NULL; |
---|
34 | |
---|
35 | assert(NULL != name); |
---|
36 | |
---|
37 | debugs(25, 5, "mime_get_header: looking for '" << name << "'"); |
---|
38 | |
---|
39 | for (p = mime; *p; p += strcspn(p, "\n")) { |
---|
40 | if (strcmp(p, "\n\r\n") == 0 || strcmp(p, "\n\n") == 0) |
---|
41 | return NULL; |
---|
42 | |
---|
43 | if (*p == '\n') |
---|
44 | ++p; |
---|
45 | |
---|
46 | if (strncasecmp(p, name, namelen)) |
---|
47 | continue; |
---|
48 | |
---|
49 | if (!xisspace(p[namelen]) && p[namelen] != ':') |
---|
50 | continue; |
---|
51 | |
---|
52 | l = strcspn(p, "\n\r") + 1; |
---|
53 | |
---|
54 | if (l > GET_HDR_SZ) |
---|
55 | l = GET_HDR_SZ; |
---|
56 | |
---|
57 | xstrncpy(header, p, l); |
---|
58 | |
---|
59 | debugs(25, 5, "mime_get_header: checking '" << header << "'"); |
---|
60 | |
---|
61 | q = header; |
---|
62 | |
---|
63 | q += namelen; |
---|
64 | |
---|
65 | if (*q == ':') { |
---|
66 | ++q; |
---|
67 | got = 1; |
---|
68 | } |
---|
69 | |
---|
70 | while (xisspace(*q)) { |
---|
71 | ++q; |
---|
72 | got = 1; |
---|
73 | } |
---|
74 | |
---|
75 | if (got && prefix) { |
---|
76 | /* we could process list entries here if we had strcasestr(). */ |
---|
77 | /* make sure we did not match a part of another field-value */ |
---|
78 | got = !strncasecmp(q, prefix, preflen) && !xisalpha(q[preflen]); |
---|
79 | } |
---|
80 | |
---|
81 | if (got) { |
---|
82 | debugs(25, 5, "mime_get_header: returning '" << q << "'"); |
---|
83 | return q; |
---|
84 | } |
---|
85 | } |
---|
86 | |
---|
87 | return NULL; |
---|
88 | } |
---|
89 | |
---|
90 | /* returns a pointer to a field-value of the first matching field-name */ |
---|
91 | char * |
---|
92 | mime_get_header(const char *mime, const char *name) |
---|
93 | { |
---|
94 | return mime_get_header_field(mime, name, NULL); |
---|
95 | } |
---|
96 | |
---|
97 | size_t |
---|
98 | headersEnd(const char *mime, size_t l) |
---|
99 | { |
---|
100 | size_t e = 0; |
---|
101 | int state = 1; |
---|
102 | |
---|
103 | PROF_start(headersEnd); |
---|
104 | |
---|
105 | while (e < l && state < 3) { |
---|
106 | switch (state) { |
---|
107 | |
---|
108 | case 0: |
---|
109 | |
---|
110 | if ('\n' == mime[e]) |
---|
111 | state = 1; |
---|
112 | |
---|
113 | break; |
---|
114 | |
---|
115 | case 1: |
---|
116 | if ('\r' == mime[e]) |
---|
117 | state = 2; |
---|
118 | else if ('\n' == mime[e]) |
---|
119 | state = 3; |
---|
120 | else |
---|
121 | state = 0; |
---|
122 | |
---|
123 | break; |
---|
124 | |
---|
125 | case 2: |
---|
126 | if ('\n' == mime[e]) |
---|
127 | state = 3; |
---|
128 | else |
---|
129 | state = 0; |
---|
130 | |
---|
131 | break; |
---|
132 | |
---|
133 | default: |
---|
134 | break; |
---|
135 | } |
---|
136 | |
---|
137 | ++e; |
---|
138 | } |
---|
139 | PROF_stop(headersEnd); |
---|
140 | |
---|
141 | if (3 == state) |
---|
142 | return e; |
---|
143 | |
---|
144 | return 0; |
---|
145 | } |
---|
146 | |
---|