On 05/26/2011 07:42 AM, Amos Jeffries wrote:
On Wed, 25 May 2011 20:07:13 +0300, Tsantilas Christos wrote:
Here are two patches the first implements the (1) and the second the (3).
Attach?
oops!
Now attsached.
The second patch does not look slower, but maybe we do not want to be
strict for many reasons. One reason is that this function used to
"Configurable SSL error details messages" patch, to parse the "descr:"
and "detail:" fields :-)
The other reason is that it is usual to find web clients or servers
which uses a simple "\n" instead of the "\r\n"...
I'm thinking a copy process may be slower than a basic scan, due to new
memory allocations etc.
Not necessarily true, waiting to see those patches. :)
Amos
On 05/25/2011 02:51 PM, Amos Jeffries wrote:
On 25/05/11 22:44, Tsantilas Christos wrote:
The quoted string fields parsing done in squid3 using the
httpHeaderParseQuotedString function (HttpHeaderTools.cc file)
I found that we do not support multiline quoted string fields, but
according the rfc2616 multiline quoted string fields should supported:
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext = <any TEXT except <">>
TEXT = <any OCTET except CTLs,
but including LWS>
LWS = [CRLF] 1*( SP | HT
I am planning to fix the httpHeaderParseQuotedString function, using
one
of the following rules:
1) Just ignore any "\r" or "\n" character. This is the fastest and
simpler approach
3) Require "\r\n " or "\r\n\t" as line separator and just remove the
"\r\n"
3) Require "\r\n " or "\r\n\t" as line separator and replace it with a
space
4) Also support "\n\t" or "\n\n\t" as line separators.
(4) case #2 "\n\n\t" is also non-compliant.
Any comments or suggestions?
RFC states "A recipient MAY replace any linear white space with a single
SP".
So (1) and the second (3) {replace with 0x20} are the valid options.
It may be worth having two quoted-string parsers. One for each option.
The preference being (1) for its higher performance.
Amos
=== modified file 'src/HttpHeaderTools.cc'
--- src/HttpHeaderTools.cc 2010-11-02 00:12:43 +0000
+++ src/HttpHeaderTools.cc 2011-05-25 16:54:36 +0000
@@ -325,52 +325,56 @@
/**
* Parses a quoted-string field (RFC 2616 section 2.2), complains if
* something went wrong, returns non-zero on success.
* Un-escapes quoted-pair characters found within the string.
* start should point at the first double-quote.
*/
int
httpHeaderParseQuotedString(const char *start, const int len, String *val)
{
const char *end, *pos;
val->clean();
if (*start != '"') {
debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
return 0;
}
pos = start + 1;
while (*pos != '"' && len > (pos-start)) {
+
+ if (*pos == '\n' || *pos == '\r') pos++;
+
bool quoted = (*pos == '\\');
if (quoted)
pos++;
if (!*pos || (pos-start) > len) {
debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
val->clean();
return 0;
}
end = pos;
while (end <= (start+len) && *end != '\\' && *end != '\"' && *end > 0x1F && *end != 0x7F)
end++;
- if (*end <= 0x1F || *end == 0x7F) {
+ bool parse_error = (*end <= 0x1F && *end != '\r' && *end != '\n') || *end == 0x7F;
+ if (parse_error) {
debugs(66, 2, "failed to parse a quoted-string header field with CTL octet " << (start-pos)
<< " bytes into '" << start << "'");
val->clean();
return 0;
}
val->append(pos, end-pos);
pos = end;
}
/* Make sure it's defined even if empty "" */
if (!val->defined())
val->limitInit("", 0);
return 1;
}
/**
* Checks the anonymizer (header_access) configuration.
*
* \retval 0 Header is explicitly blocked for removal
* \retval 1 Header is explicitly allowed
* \retval 1 Header has been replaced, the current version can be used.
=== modified file 'src/HttpHeaderTools.cc'
--- src/HttpHeaderTools.cc 2010-11-02 00:12:43 +0000
+++ src/HttpHeaderTools.cc 2011-05-25 16:57:59 +0000
@@ -325,52 +325,64 @@
/**
* Parses a quoted-string field (RFC 2616 section 2.2), complains if
* something went wrong, returns non-zero on success.
* Un-escapes quoted-pair characters found within the string.
* start should point at the first double-quote.
*/
int
httpHeaderParseQuotedString(const char *start, const int len, String *val)
{
const char *end, *pos;
val->clean();
if (*start != '"') {
debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
return 0;
}
pos = start + 1;
while (*pos != '"' && len > (pos-start)) {
+
+ if (*pos =='\r') {
+ pos ++;
+ if (*(pos++) != '\n' || (*pos != ' ' && *pos != '\t')) {
+ debugs(66, 2, "failed to parse multiline quoted-string header field near '" << pos << "'");
+ val->clean();
+ return 0;
+ }
+ pos++; // (pos-start) here may exceed len but we do not care...
+ val->append(" "); //replace "\r\n " or "\r\n\t" with single space
+ }
+
bool quoted = (*pos == '\\');
if (quoted)
pos++;
if (!*pos || (pos-start) > len) {
debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
val->clean();
return 0;
}
end = pos;
while (end <= (start+len) && *end != '\\' && *end != '\"' && *end > 0x1F && *end != 0x7F)
end++;
- if (*end <= 0x1F || *end == 0x7F) {
+ if ((*end <= 0x1F && *end != '\r') || *end == 0x7F) {
debugs(66, 2, "failed to parse a quoted-string header field with CTL octet " << (start-pos)
<< " bytes into '" << start << "'");
val->clean();
return 0;
}
val->append(pos, end-pos);
pos = end;
}
/* Make sure it's defined even if empty "" */
if (!val->defined())
val->limitInit("", 0);
return 1;
}
/**
* Checks the anonymizer (header_access) configuration.
*
* \retval 0 Header is explicitly blocked for removal
* \retval 1 Header is explicitly allowed
* \retval 1 Header has been replaced, the current version can be used.