]>
Commit | Line | Data |
---|---|---|
28204b3b FC |
1 | /* |
2 | * DEBUG: section 66 HTTP Header Tools | |
3 | * AUTHOR: Alex Rousskov | |
4 | * | |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
21 | * | |
22 | * This program is distributed in the hope that it will be useful, | |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26 | * | |
27 | * You should have received a copy of the GNU General Public License | |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
33 | #include "squid.h" | |
34 | #include "SquidString.h" | |
35 | #include "StrList.h" | |
36 | ||
37 | /** appends an item to the list */ | |
38 | void | |
39 | strListAdd(String * str, const char *item, char del) | |
40 | { | |
41 | assert(str && item); | |
42 | if (str->size()) { | |
43 | char buf[3]; | |
44 | buf[0] = del; | |
45 | buf[1] = ' '; | |
46 | buf[2] = '\0'; | |
47 | str->append(buf, 2); | |
48 | } | |
49 | str->append(item, strlen(item)); | |
50 | } | |
51 | ||
52 | /** returns true iff "m" is a member of the list */ | |
53 | int | |
54 | strListIsMember(const String * list, const char *m, char del) | |
55 | { | |
56 | const char *pos = NULL; | |
57 | const char *item; | |
58 | int ilen = 0; | |
59 | int mlen; | |
60 | ||
61 | assert(list && m); | |
62 | mlen = strlen(m); | |
63 | while (strListGetItem(list, del, &item, &ilen, &pos)) { | |
64 | if (mlen == ilen && !strncasecmp(item, m, ilen)) | |
65 | return 1; | |
66 | } | |
67 | return 0; | |
68 | } | |
69 | ||
70 | /** returns true iff "s" is a substring of a member of the list */ | |
71 | int | |
72 | strListIsSubstr(const String * list, const char *s, char del) | |
73 | { | |
74 | assert(list && del); | |
75 | return (list->find(s) != String::npos); | |
76 | ||
77 | /** \note | |
78 | * Note: the original code with a loop is broken because it uses strstr() | |
79 | * instead of strnstr(). If 's' contains a 'del', strListIsSubstr() may | |
80 | * return true when it should not. If 's' does not contain a 'del', the | |
81 | * implementaion is equavalent to strstr()! Thus, we replace the loop with | |
82 | * strstr() above until strnstr() is available. | |
83 | */ | |
84 | } | |
85 | ||
86 | /** | |
87 | * iterates through a 0-terminated string of items separated by 'del's. | |
88 | * white space around 'del' is considered to be a part of 'del' | |
89 | * like strtok, but preserves the source, and can iterate several strings at once | |
90 | * | |
91 | * returns true if next item is found. | |
92 | * init pos with NULL to start iteration. | |
93 | */ | |
94 | int | |
95 | strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos) | |
96 | { | |
97 | size_t len; | |
98 | /* ',' is always enabled as field delimiter as this is required for | |
99 | * processing merged header values properly, even if Cookie normally | |
100 | * uses ';' as delimiter. | |
101 | */ | |
102 | static char delim[3][8] = { | |
103 | "\"?,", | |
104 | "\"\\", | |
105 | " ?,\t\r\n" | |
106 | }; | |
107 | int quoted = 0; | |
108 | assert(str && item && pos); | |
109 | ||
110 | delim[0][1] = del; | |
111 | delim[2][1] = del; | |
112 | ||
113 | if (!*pos) { | |
114 | *pos = str->termedBuf(); | |
115 | ||
116 | if (!*pos) | |
117 | return 0; | |
118 | } | |
119 | ||
120 | /* skip leading whitespace and delimiters */ | |
121 | *pos += strspn(*pos, delim[2]); | |
122 | ||
123 | *item = *pos; /* remember item's start */ | |
124 | ||
125 | /* find next delimiter */ | |
126 | do { | |
127 | *pos += strcspn(*pos, delim[quoted]); | |
128 | if (**pos == '"') { | |
129 | quoted = !quoted; | |
130 | *pos += 1; | |
131 | } else if (quoted && **pos == '\\') { | |
132 | *pos += 1; | |
133 | if (**pos) | |
134 | *pos += 1; | |
135 | } else { | |
136 | break; /* Delimiter found, marking the end of this value */ | |
137 | } | |
138 | } while (**pos); | |
139 | ||
140 | len = *pos - *item; /* *pos points to del or '\0' */ | |
141 | ||
142 | /* rtrim */ | |
143 | while (len > 0 && xisspace((*item)[len - 1])) | |
144 | --len; | |
145 | ||
146 | if (ilen) | |
147 | *ilen = len; | |
148 | ||
149 | return len > 0; | |
150 | } | |
151 |