]> git.ipfire.org Git - thirdparty/squid.git/blob - src/mime_header.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / mime_header.cc
1 /*
2 * Copyright (C) 1996-2014 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\r")) {
40 if (strcmp(p, "\r\n\r\n") == 0 || strcmp(p, "\n\n") == 0)
41 return NULL;
42
43 while (xisspace(*p))
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 }