$(AUTH_LIBS) \
$(DISK_LIBS) \
acl/libapi.la \
+ http/libsquid-http.la \
+ parser/libsquid-parser.la \
base/libbase.la \
libsquid.la \
ip/libip.la \
anyp/libanyp.la \
comm/libcomm.la \
eui/libeui.la \
- http/libsquid-http.la \
icmp/libicmp.la icmp/libicmp-core.la \
log/liblog.la \
format/libformat.la \
$(ADAPTATION_LIBS) \
$(ESI_LIBS) \
$(SNMP_LIBS) \
- parser/libsquid-parser.la \
$(top_builddir)/lib/libmisccontainers.la \
$(top_builddir)/lib/libmiscencoding.la \
$(top_builddir)/lib/libmiscutil.la \
tests_testHttpReply_LDFLAGS = $(LIBADD_DL)
tests_testHttpReply_LDADD=\
http/libsquid-http.la \
+ parser/libsquid-parser.la \
acl/libacls.la \
acl/libapi.la \
acl/libstate.la \
$(TESTSOURCES)
tests_testACLMaxUserIP_LDADD= \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
# comm.cc only requires comm/libcomm.la until fdc_table is dead.
tests_testCacheManager_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
swap_log_op.cc
tests_testDiskIO_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
SquidConfig.o \
CommCalls.o \
DnsLookupDetails.o \
$(DISKIO_GEN_SOURCE)
tests_testEvent_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
$(DISKIO_GEN_SOURCE)
tests_testEventLoop_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
$(DISKIO_GEN_SOURCE)
tests_test_http_range_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
$(TESTSOURCES)
tests_testHttp1Parser_LDADD= \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
anyp/libanyp.la \
SquidConfig.o \
base/libbase.la \
fs/libfs.la \
$(SSL_LIBS) \
ipc/libipc.la \
+ http/libsquid-http.la \
+ parser/libsquid-parser.la \
base/libbase.la \
mgr/libmgr.la \
anyp/libanyp.la \
comm/libcomm.la \
log/liblog.la \
format/libformat.la \
- http/libsquid-http.la \
$(REPL_OBJS) \
$(ADAPTATION_LIBS) \
$(ESI_LIBS) \
tests_testStore_LDADD= \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
swap_log_op.cc
tests_testUfs_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
CommCalls.o \
DnsLookupDetails.o \
ident/libident.la \
$(TESTSOURCES)
tests_testRock_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
libsquid.la \
comm/libcomm.la \
anyp/libanyp.la \
$(BUILT_SOURCES)
tests_testURL_LDADD = \
http/libsquid-http.la \
+ parser/libsquid-parser.la \
anyp/libanyp.la \
ident/libident.la \
acl/libacls.la \
#include "squid.h"
#include "Debug.h"
#include "http/one/Parser.h"
+#include "parser/Tokenizer.h"
/// RFC 7230 section 2.6 - 7 magic octets
const SBuf Http::One::Parser::Http1magic("HTTP/1.");
// arbitrary maximum-length for headers which can be found by Http1Parser::getHeaderField()
#define GET_HDR_SZ 1024
+// BUG: returns only the first header line with given name,
+// ignores multi-line headers and obs-fold headers
char *
Http::One::Parser::getHeaderField(const char *name)
{
- LOCAL_ARRAY(char, header, GET_HDR_SZ);
- const char *p = NULL;
- char *q = NULL;
- char got = 0;
- const int namelen = name ? strlen(name) : 0;
-
if (!headerBlockSize() || !name)
return NULL;
+ LOCAL_ARRAY(char, header, GET_HDR_SZ);
+ const int namelen = name ? strlen(name) : 0;
+
debugs(25, 5, "looking for '" << name << "'");
- for (p = mimeHeader().c_str(); *p; p += strcspn(p, "\n\r")) {
- if (strcmp(p, "\r\n\r\n") == 0 || strcmp(p, "\n\n") == 0)
- return NULL;
+ ::Parser::Tokenizer tok(mimeHeaderBlock_);
+ SBuf p;
+ const SBuf crlf("\r\n");
- while (xisspace(*p))
- ++p;
+ // while we can find more LF in the SBuf
+ while (tok.prefix(p, CharacterSet::LF)) {
+ tok.skip(CharacterSet::LF); // move tokenizer past the LF
- if (strncasecmp(p, name, namelen))
+ // header lines must start with the name (case insensitive)
+ if (p.substr(0, namelen).caseCmp(name, namelen))
continue;
- if (!xisspace(p[namelen]) && p[namelen] != ':')
+ // then a COLON
+ if (p[namelen] != ':')
continue;
- int l = strcspn(p, "\n\r") + 1;
-
- if (l > GET_HDR_SZ)
- l = GET_HDR_SZ;
-
- xstrncpy(header, p, l);
-
- debugs(25, 5, "checking '" << header << "'");
-
- q = header;
+ // drop any trailing *CR sequence
+ p.trim(crlf, false, true);
- q += namelen;
+ debugs(25, 5, "checking " << p);
+ p.consume(namelen + 1);
- if (*q == ':') {
- ++q;
- got = 1;
- }
+ // TODO: optimize SBuf::trim to take CharacterSet directly
+ ::Parser::Tokenizer t(p);
+ t.skip(CharacterSet::WSP);
+ p = t.remaining();
- while (xisspace(*q)) {
- ++q;
- got = 1;
- }
+ // prevent buffer overrun on char header[];
+ p.chop(0, sizeof(header)-1);
- if (got) {
- debugs(25, 5, "returning '" << q << "'");
- return q;
- }
+ // return the header field-value
+ xstrncpy(header, p.rawContent(), p.length());
+ debugs(25, 5, "returning: " << header);
+ return header;
}
return NULL;