You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
7.2 KiB
C++
378 lines
7.2 KiB
C++
/*
|
|
KPF - Public fileserver for KDE
|
|
|
|
Copyright 2001 Rik Hemsley (rikkus) <rik@kde.org>
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to
|
|
deal in the Software without restriction, including without limitation the
|
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
sell copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include <climits> // For ULONG_MAX
|
|
|
|
#include <tqregexp.h>
|
|
#include <kurl.h>
|
|
|
|
#include "Defines.h"
|
|
#include "Utils.h"
|
|
#include "Request.h"
|
|
|
|
namespace KPF
|
|
{
|
|
Request::Request()
|
|
: protocolMajor_ (0),
|
|
protocolMinor_ (9),
|
|
method_ (Unsupported),
|
|
haveHost_ (false),
|
|
haveIfModifiedSince_ (false),
|
|
haveIfUnmodifiedSince_ (false),
|
|
expectContinue_ (false),
|
|
haveRange_ (false),
|
|
persist_ (false)
|
|
{
|
|
}
|
|
|
|
Request::~Request()
|
|
{
|
|
}
|
|
|
|
void
|
|
Request::parseHeaders(const TQStringList & buf)
|
|
{
|
|
for (TQStringList::ConstIterator it(buf.begin()); it != buf.end(); ++it)
|
|
{
|
|
TQString line(*it);
|
|
|
|
int colonPos = line.find(':');
|
|
|
|
if (-1 != colonPos)
|
|
{
|
|
TQString name(line.left(colonPos).stripWhiteSpace().lower());
|
|
TQString value(line.mid(colonPos + 1).stripWhiteSpace());
|
|
handleHeader(name, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
Request::handleHeader(const TQString & name, const TQString & value)
|
|
{
|
|
if ("host" == name)
|
|
{
|
|
setHost(value);
|
|
}
|
|
if ("range" == name)
|
|
{
|
|
setRange(value);
|
|
}
|
|
else if ("if-modified-since" == name)
|
|
{
|
|
TQDateTime dt;
|
|
|
|
if (parseDate(value, dt))
|
|
setIfModifiedSince(dt);
|
|
}
|
|
else if ("if-unmodified-since" == name)
|
|
{
|
|
TQDateTime dt;
|
|
|
|
if (parseDate(value, dt))
|
|
setIfUnmodifiedSince(dt);
|
|
}
|
|
else if ("connection" == name)
|
|
{
|
|
TQString v(value.lower());
|
|
|
|
if ("keep-alive" == v)
|
|
{
|
|
setPersist(true);
|
|
}
|
|
else if ("close" == v)
|
|
{
|
|
setPersist(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
Request::setProtocol(const TQString & _s)
|
|
{
|
|
TQString s(_s);
|
|
|
|
s.remove(0, 5);
|
|
|
|
int dotPos = s.find('.');
|
|
|
|
if (-1 != dotPos)
|
|
{
|
|
protocolMajor_ = s.left(dotPos).toUInt();
|
|
protocolMinor_ = s.mid(dotPos + 1).toUInt();
|
|
}
|
|
}
|
|
|
|
void
|
|
Request::setProtocol(uint major, uint minor)
|
|
{
|
|
protocolMajor_ = major;
|
|
protocolMinor_ = minor;
|
|
}
|
|
|
|
void
|
|
Request::setMethod(const TQString & s)
|
|
{
|
|
if ("GET" == s)
|
|
method_ = Get;
|
|
else if ("HEAD" == s)
|
|
method_ = Head;
|
|
else
|
|
method_ = Unsupported;
|
|
}
|
|
|
|
void
|
|
Request::setMethod(Method m)
|
|
{
|
|
method_ = m;
|
|
}
|
|
|
|
void
|
|
Request::setPath(const TQString & s)
|
|
{
|
|
KURL p(s);
|
|
path_ = clean(p.path());
|
|
|
|
#if 0
|
|
if ('/' == path_.at(path_.length() - 1))
|
|
{
|
|
path_.append("index.html");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
Request::setHost(const TQString & s)
|
|
{
|
|
host_ = s;
|
|
haveHost_ = true;
|
|
}
|
|
|
|
void
|
|
Request::setIfModifiedSince(const TQDateTime & dt)
|
|
{
|
|
ifModifiedSince_ = dt;
|
|
haveIfModifiedSince_ = true;
|
|
}
|
|
|
|
void
|
|
Request::setIfUnmodifiedSince(const TQDateTime & dt)
|
|
{
|
|
ifUnmodifiedSince_ = dt;
|
|
haveIfUnmodifiedSince_ = true;
|
|
}
|
|
|
|
uint
|
|
Request::protocolMajor() const
|
|
{
|
|
return protocolMajor_;
|
|
}
|
|
|
|
uint
|
|
Request::protocolMinor() const
|
|
{
|
|
return protocolMinor_;
|
|
}
|
|
|
|
float
|
|
Request::protocol() const
|
|
{
|
|
return (float(protocolMajor_) + float(protocolMinor_) / 10.0);
|
|
}
|
|
|
|
Request::Method
|
|
Request::method() const
|
|
{
|
|
return method_;
|
|
}
|
|
|
|
bool
|
|
Request::haveHost() const
|
|
{
|
|
return haveHost_;
|
|
}
|
|
|
|
bool
|
|
Request::haveIfModifiedSince() const
|
|
{
|
|
return haveIfModifiedSince_;
|
|
}
|
|
|
|
bool
|
|
Request::haveIfUnmodifiedSince() const
|
|
{
|
|
return haveIfUnmodifiedSince_;
|
|
}
|
|
|
|
TQString
|
|
Request::path() const
|
|
{
|
|
return path_;
|
|
}
|
|
|
|
TQString
|
|
Request::host() const
|
|
{
|
|
return host_;
|
|
}
|
|
|
|
TQDateTime
|
|
Request::ifModifiedSince() const
|
|
{
|
|
return ifModifiedSince_;
|
|
}
|
|
|
|
TQDateTime
|
|
Request::ifUnmodifiedSince() const
|
|
{
|
|
return ifUnmodifiedSince_;
|
|
}
|
|
|
|
TQCString
|
|
Request::protocolString() const
|
|
{
|
|
TQCString s("HTTP/");
|
|
s += TQCString().setNum(protocolMajor_);
|
|
s += '.';
|
|
s += TQCString().setNum(protocolMinor_);
|
|
return s;
|
|
}
|
|
|
|
void
|
|
Request::setExpectContinue(bool b)
|
|
{
|
|
expectContinue_ = b;
|
|
}
|
|
|
|
bool
|
|
Request::expectContinue() const
|
|
{
|
|
return expectContinue_;
|
|
}
|
|
|
|
void
|
|
Request::setRange(const TQString & s)
|
|
{
|
|
kpfDebug << "Request::setRange(`" << s << "')" << endl;
|
|
|
|
haveRange_ = true;
|
|
|
|
ByteRangeList l(s, protocol());
|
|
|
|
ulong first (ULONG_MAX);
|
|
ulong last (0L);
|
|
bool haveLast (false);
|
|
|
|
for (ByteRangeList::ConstIterator it(l.begin()); it != l.end(); ++it)
|
|
{
|
|
ByteRange r(*it);
|
|
first = min(r.first(), first);
|
|
|
|
if (r.haveLast())
|
|
{
|
|
haveLast = true;
|
|
last = max(r.last(), last);
|
|
}
|
|
}
|
|
|
|
kpfDebug << "Request::setRange(): first == " << first << "d" << endl;
|
|
|
|
range_.setFirst(first);
|
|
|
|
if (haveLast)
|
|
{
|
|
kpfDebug << "Request::setRange(): last == " << last << "d" << endl;
|
|
range_.setLast(last);
|
|
}
|
|
kpfDebug << "Request::setRange(): no last" << endl;
|
|
}
|
|
|
|
ByteRange
|
|
Request::range() const
|
|
{
|
|
return range_;
|
|
}
|
|
|
|
bool
|
|
Request::haveRange() const
|
|
{
|
|
return haveRange_;
|
|
}
|
|
|
|
void
|
|
Request::setPersist(bool b)
|
|
{
|
|
if (protocol() > 1.0) // Bad, but makes wget work.
|
|
{
|
|
persist_ = b;
|
|
}
|
|
}
|
|
|
|
bool
|
|
Request::persist() const
|
|
{
|
|
return persist_;
|
|
}
|
|
|
|
void
|
|
Request::clear()
|
|
{
|
|
protocolMajor_ = 0;
|
|
protocolMinor_ = 9;
|
|
method_ = Unsupported;
|
|
haveHost_ = false;
|
|
haveIfModifiedSince_ = false;
|
|
haveIfUnmodifiedSince_ = false;
|
|
expectContinue_ = false;
|
|
haveRange_ = false;
|
|
persist_ = false;
|
|
path_ = TQString();
|
|
host_ = TQString();
|
|
ifModifiedSince_ = TQDateTime();
|
|
ifUnmodifiedSince_ = TQDateTime();
|
|
range_.clear();
|
|
}
|
|
|
|
TQString
|
|
Request::clean(const TQString & _path) const
|
|
{
|
|
TQString s(_path);
|
|
|
|
while (s.endsWith("/./"))
|
|
s.truncate(s.length() - 2);
|
|
|
|
while (s.endsWith("/."))
|
|
s.truncate(s.length() - 1);
|
|
|
|
// Double slash -> slash.
|
|
|
|
TQRegExp r("\\/\\/+");
|
|
s.replace(r, "/");
|
|
|
|
return s;
|
|
}
|
|
|
|
} // End namespace KPF
|
|
|
|
// vim:ts=2:sw=2:tw=78:et
|