mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 19:02:48 +00:00

for compatibilty reasons automoc4 support is not removed but it shall be in the future. automoc4 has not been maintained for a while (last commit is from 2011) and the stable release is from 2009. CMake version >= 2.8.6 provides the functionality for mocking so I see no reason to not make use of it.
198 lines
6.7 KiB
C++
198 lines
6.7 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (c) 2008 Andreas Hartmetz <ahartmetz@gmail.com>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "httpheadertokenizetest.h"
|
|
|
|
#include <qtest_kde.h>
|
|
|
|
#include <QtCore/QByteArray>
|
|
#include <QtCore/QHash>
|
|
#include <kdebug.h>
|
|
|
|
#include <parsinghelpers.h>
|
|
|
|
#include "moc_httpheadertokenizetest.cpp"
|
|
|
|
#include <parsinghelpers.cpp>
|
|
|
|
QTEST_KDEMAIN(HeaderTokenizeTest, NoGUI)
|
|
|
|
/* some possible fields that can be used for test headers
|
|
{"accept-ranges", false},
|
|
{"cache-control", true},
|
|
{"connection", true},
|
|
{"content-disposition", false}, //is multi-valued in a way, but with ";" separator!
|
|
{"content-encoding", true},
|
|
{"content-language", true},
|
|
{"content-length", false},
|
|
{"content-location", false},
|
|
{"content-md5", false},
|
|
{"content-type", false},
|
|
{"date", false},
|
|
{"dav", true}, //RFC 2518
|
|
{"etag", false},
|
|
{"expires", false},
|
|
{"keep-alive", false}, //RFC 2068
|
|
{"last-modified", false},
|
|
{"link", false}, //RFC 2068, multi-valued with ";" separator
|
|
{"location", false},
|
|
*/
|
|
|
|
//no use testing many different headers, just a couple each of the multi-valued
|
|
//and the single-valued group to make sure that corner cases work both if there
|
|
//are already entries for the header and if there are no entries.
|
|
static const char messyHeader[] =
|
|
"\n"
|
|
"accept-ranges:foo\r\n"
|
|
"connection: one\r\n"
|
|
" t_\r\n"
|
|
" wo,\r\n"
|
|
"\tthree\r\n"
|
|
"accept-ranges:42\n"
|
|
"accept-Ranges:\tmaybe \r"
|
|
" or not\n"
|
|
"CoNNectIoN:four, , ,, , \r\n"
|
|
" :fi:ve\r\n"
|
|
":invalid stuff\r\n"
|
|
"\tinvalid: connection:close\t\r"
|
|
"connection: Six, seven ,, , eight\r" //one malformed newline...
|
|
"\n\r "; //two malformed newlines; end of header. also observe the trailing space.
|
|
|
|
//tab separates values, newline separates header lines. the first word is the key.
|
|
static const char messyResult[] =
|
|
"accept-ranges\tfoo\t42\tmaybe or not\n"
|
|
"connection\tone t_ wo\tthree\tfour\t:fi:ve\tSix\tseven\teight";
|
|
|
|
|
|
static const char redirectHeader[] =
|
|
//"HTTP/1.1 302 Moved Temporarily\r\n"
|
|
"Location: http://www.hertz.de/rentacar/index.jsp?bsc=t&targetPage=reservationOnHomepage.jsp\r\n"
|
|
"Connection:close\r\n"
|
|
"Cache-Control: no-cache\r\n"
|
|
"Pragma: no-cache\r\n"
|
|
"\r\n";
|
|
|
|
static const char redirectResult[] =
|
|
"cache-control\tno-cache\n"
|
|
"connection\tclose\n"
|
|
"location\thttp://www.hertz.de/rentacar/index.jsp?bsc=t&targetPage=reservationOnHomepage.jsp\n"
|
|
"pragma\tno-cache";
|
|
|
|
static const int bufSize = 4096;
|
|
char buffer[bufSize];
|
|
|
|
void HeaderTokenizeTest::testMessyHeader()
|
|
{
|
|
//Copy the header into a writable buffer
|
|
for (int i = 0; i < bufSize; i++) {
|
|
buffer[i] = 0;
|
|
}
|
|
strcpy(buffer, messyHeader);
|
|
|
|
HeaderTokenizer tokenizer(buffer);
|
|
int tokenizeEnd = tokenizer.tokenize(0, strlen(messyHeader));
|
|
QCOMPARE(tokenizeEnd, (int)(strlen(messyHeader) - 1));
|
|
|
|
// If the output of the tokenizer contains all the terms that should be there and
|
|
// exactly the number of terms that should be there then it's exactly correct.
|
|
// We are lax wrt trailing whitespace, by the way. It does neither explicitly matter
|
|
// nor not matter according to the standard. Internal whitespace similarly should not
|
|
// matter but we have to be exact because the tokenizer does not move strings around,
|
|
// it only overwrites \r and \n in case of line continuations.
|
|
|
|
typedef QPair<int, int> intPair; //foreach is a macro and does not like commas
|
|
|
|
int nValues = 0;
|
|
foreach (const QByteArray &ba, QByteArray(messyResult).split('\n')) {
|
|
QList<QByteArray> values = ba.split('\t');
|
|
QByteArray key = values.takeFirst();
|
|
nValues += values.count();
|
|
|
|
QList<QByteArray> comparisonValues;
|
|
foreach (const intPair &be, tokenizer.value(key).beginEnd) {
|
|
comparisonValues.append(QByteArray(buffer + be.first, be.second - be.first));
|
|
}
|
|
|
|
QCOMPARE(comparisonValues.count(), values.count());
|
|
for (int i = 0; i < values.count(); i++) {
|
|
QVERIFY(comparisonValues[i].startsWith(values[i]));
|
|
}
|
|
}
|
|
|
|
int nValues2 = 0;
|
|
HeaderTokenizer::ConstIterator it = tokenizer.constBegin();
|
|
for (; it != tokenizer.constEnd(); ++it) {
|
|
nValues2 += it.value().beginEnd.count();
|
|
}
|
|
QCOMPARE(nValues2, nValues);
|
|
|
|
return; //comment out for parsed header dump to stdout
|
|
|
|
it = tokenizer.constBegin();
|
|
for (; it != tokenizer.constEnd(); ++it) {
|
|
if (!it.value().beginEnd.isEmpty()) {
|
|
kDebug() << it.key() << ":";
|
|
}
|
|
foreach (const intPair &be, it.value().beginEnd) {
|
|
kDebug() << " " << QByteArray(buffer + be.first, be.second - be.first);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HeaderTokenizeTest::testRedirectHeader()
|
|
{
|
|
//Copy the header into a writable buffer
|
|
for (int i = 0; i < bufSize; i++) {
|
|
buffer[i] = 0;
|
|
}
|
|
strcpy(buffer, redirectHeader);
|
|
|
|
HeaderTokenizer tokenizer(buffer);
|
|
int tokenizeEnd = tokenizer.tokenize(0, strlen(redirectHeader));
|
|
QCOMPARE(tokenizeEnd, (int)strlen(redirectHeader));
|
|
|
|
typedef QPair<int, int> intPair;
|
|
|
|
int nValues = 0;
|
|
foreach (const QByteArray &ba, QByteArray(redirectResult).split('\n')) {
|
|
QList<QByteArray> values = ba.split('\t');
|
|
QByteArray key = values.takeFirst();
|
|
nValues += values.count();
|
|
|
|
QList<QByteArray> comparisonValues;
|
|
foreach (const intPair &be, tokenizer.value(key).beginEnd) {
|
|
comparisonValues.append(QByteArray(buffer + be.first, be.second - be.first));
|
|
}
|
|
|
|
QCOMPARE(comparisonValues.count(), values.count());
|
|
for (int i = 0; i < values.count(); i++) {
|
|
QVERIFY(comparisonValues[i].startsWith(values[i]));
|
|
}
|
|
}
|
|
|
|
int nValues2 = 0;
|
|
HeaderTokenizer::ConstIterator it = tokenizer.constBegin();
|
|
for (; it != tokenizer.constEnd(); ++it) {
|
|
nValues2 += it.value().beginEnd.count();
|
|
}
|
|
QCOMPARE(nValues2, nValues);
|
|
|
|
// Fix compiler warning
|
|
(void)contentDispositionParser;
|
|
}
|