2006-02-17 13:35:04 +00:00
|
|
|
/* <!-- copyright */
|
|
|
|
/*
|
2006-09-21 15:31:24 +00:00
|
|
|
* aria2 - The high speed download utility
|
2006-02-17 13:35:04 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2010-01-05 16:01:46 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2006-09-21 15:31:24 +00:00
|
|
|
*
|
|
|
|
* In addition, as a special exception, the copyright holders give
|
|
|
|
* permission to link the code of portions of this program with the
|
|
|
|
* OpenSSL library under certain conditions as described in each
|
|
|
|
* individual source file, and distribute linked combinations
|
|
|
|
* including the two.
|
|
|
|
* You must obey the GNU General Public License in all respects
|
|
|
|
* for all of the code used other than OpenSSL. If you modify
|
|
|
|
* file(s) with this exception, you may extend this exception to your
|
|
|
|
* version of the file(s), but you are not obligated to do so. If you
|
|
|
|
* do not wish to do so, delete this exception statement from your
|
|
|
|
* version. If you delete this exception statement from all source
|
|
|
|
* files in the program, then also delete it here.
|
2006-02-17 13:35:04 +00:00
|
|
|
*/
|
|
|
|
/* copyright --> */
|
2010-10-31 07:23:53 +00:00
|
|
|
#ifndef D_UTIL_H
|
|
|
|
#define D_UTIL_H
|
2006-02-17 13:35:04 +00:00
|
|
|
|
2006-02-28 02:25:45 +00:00
|
|
|
#include "common.h"
|
2008-11-27 15:29:15 +00:00
|
|
|
|
2008-02-08 15:53:45 +00:00
|
|
|
#include <sys/time.h>
|
2011-11-03 09:51:31 +00:00
|
|
|
#include <limits.h>
|
|
|
|
#include <stdint.h>
|
2008-11-27 15:29:15 +00:00
|
|
|
|
2010-03-29 14:39:09 +00:00
|
|
|
#include <cstdio>
|
2012-01-10 16:03:38 +00:00
|
|
|
#include <cstring>
|
2008-02-08 15:53:45 +00:00
|
|
|
#include <string>
|
2006-02-17 13:35:04 +00:00
|
|
|
#include <utility>
|
2008-02-08 15:53:45 +00:00
|
|
|
#include <iosfwd>
|
2009-06-28 10:37:15 +00:00
|
|
|
#include <ostream>
|
2009-03-04 15:53:56 +00:00
|
|
|
#include <numeric>
|
2009-03-07 03:10:53 +00:00
|
|
|
#include <map>
|
2009-06-28 10:37:15 +00:00
|
|
|
#include <iomanip>
|
2009-11-12 15:17:28 +00:00
|
|
|
#include <algorithm>
|
2009-11-29 06:43:38 +00:00
|
|
|
#include <vector>
|
2008-02-08 15:53:45 +00:00
|
|
|
|
2008-11-27 15:29:15 +00:00
|
|
|
#include "SharedHandle.h"
|
|
|
|
#include "a2time.h"
|
|
|
|
#include "a2netcompat.h"
|
2009-03-04 15:53:56 +00:00
|
|
|
#include "a2functional.h"
|
2011-10-29 14:33:48 +00:00
|
|
|
#include "SegList.h"
|
2011-11-03 09:51:31 +00:00
|
|
|
#include "a2iterator.h"
|
|
|
|
#include "message.h"
|
|
|
|
#include "DlAbortEx.h"
|
|
|
|
#include "fmt.h"
|
2008-11-27 15:29:15 +00:00
|
|
|
|
2013-02-14 12:51:30 +00:00
|
|
|
#ifndef HAVE_SIGACTION
|
|
|
|
# define sigset_t int
|
|
|
|
#endif // HAVE_SIGACTION
|
|
|
|
|
2008-02-08 15:53:45 +00:00
|
|
|
namespace aria2 {
|
2006-02-17 13:35:04 +00:00
|
|
|
|
2007-11-04 12:26:12 +00:00
|
|
|
class Randomizer;
|
2007-11-13 10:10:11 +00:00
|
|
|
class BitfieldMan;
|
2007-11-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten to add content-type support.
* src/DownloadHandler.{h, cc}
* src/BtPostDownloadHandler.{h, cc}
* test/BtPostDownloadHandlerTest.cc
* src/MetalinkPostDownloadHandler.{h, cc}
* test/MetalinkPostDownloadHandlerTest.cc
* src/PostDownloadHandler.{h, cc}
* src/DownloadHandlerConstants.{h, cc}
* src/RequestGroup.cc
* src/HttpResponseCommand.cc
* src/FtpNegotiationCommand.cc
* src/SingleFileDownloadContext.{h, cc}
* src/RequestGroup.h
* src/RequestGroupCriteria.h
* src/ContentTypeRequestGroupCriteria.h
Added 'mem' option value for --follow-metalink,
--follow-torrent.
If it is give, metalink/torrent file is not written to the disk,
but
just is kept in memory. Parsing is occurred on memory.
* src/MetalinkHelper.{h, cc}
* src/MetalinkProcessor.h
* src/Xml2MetalinkProcessor.{h, cc}
* test/Xml2MetalinkProcessorTest.cc
* src/DownloadHandlerFactory.{h, cc}
* test/DownloadHandlerFactoryTest.cc
* src/PreDownloadHandler.{h, cc}
* src/OptionHandlerFactory.cc
* src/DefaultBtContext.{h, cc}
* test/DefaultBtContextTest.cc
* src/version_usage.cc
* src/Metalink2RequestGroup.{h, cc}
* src/RequestGroup.{h, cc}
* src/a2functional.h
* test/a2functionalTest.cc
* src/MemoryBufferPreDownloadHandler.{h, cc}
* src/OptionHandlerImpl.h
* src/prefs.h
* src/Util.{h, cc}
* test/UtilTest.cc
Keep DownloadResult rather than RequestGroup after downloads to
reduce
memory usage.
* src/RequestGroupMan.{h, cc}
* src/DownloadEngine.cc
* src/BtDependency.{h, cc}: Changed the type of dependee from
WeakHandle to SharedHandle because WeakHandle could be null.
* src/RequestGroup.{h, cc}
* src/DownloadEngineFactory.cc
* src/DownloadResult.h
Set totalLength after download finished
* src/UnknownLengthPieceStorage.{h, cc}
Keep torrent file specified in metalink in memory.
* src/Metalink2RequestGroup.cc
* src/BtDependency.cc
* src/TrueRequestGroupCriteria.h
Fixed the bug: seekg is used where seekp should be used.
* src/ByteArrayDiskWriter.cc
* test/ByteArraydiskWriterTest.cc
2007-11-27 12:27:10 +00:00
|
|
|
class BinaryStream;
|
2008-02-08 15:53:45 +00:00
|
|
|
class FileEntry;
|
2010-04-01 15:41:53 +00:00
|
|
|
class RequestGroup;
|
2010-07-16 14:22:57 +00:00
|
|
|
class Option;
|
2012-02-29 15:02:29 +00:00
|
|
|
struct Pref;
|
2007-11-04 12:26:12 +00:00
|
|
|
|
2009-11-15 12:55:50 +00:00
|
|
|
#define STRTOLL(X) strtoll(X, reinterpret_cast<char**>(0), 10)
|
|
|
|
#define STRTOULL(X) strtoull(X, reinterpret_cast<char**>(0), 10)
|
2007-10-23 16:29:37 +00:00
|
|
|
|
|
|
|
#define START_INDEX(OFFSET, PIECE_LENGTH) ((OFFSET)/(PIECE_LENGTH))
|
|
|
|
#define END_INDEX(OFFSET, LENGTH, PIECE_LENGTH) (((OFFSET)+(LENGTH)-1)/(PIECE_LENGTH))
|
2006-02-17 13:35:04 +00:00
|
|
|
|
2008-02-08 15:53:45 +00:00
|
|
|
#define DIV_FLOOR(X,Y) ((X)/(Y)+((X)%(Y)? 1:0))
|
|
|
|
|
2008-08-24 07:55:34 +00:00
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
inline uint64_t ntoh64(uint64_t x) { return x; }
|
|
|
|
inline uint64_t hton64(uint64_t x) { return x; }
|
|
|
|
#else // !WORDS_BIGENDIAN
|
|
|
|
inline uint64_t byteswap64(uint64_t x) {
|
2010-10-10 03:08:30 +00:00
|
|
|
uint64_t v1 = ntohl(x & 0x00000000ffffffffllu);
|
2008-08-24 07:55:34 +00:00
|
|
|
uint64_t v2 = ntohl(x >> 32);
|
|
|
|
return (v1 << 32)|v2;
|
|
|
|
}
|
|
|
|
inline uint64_t ntoh64(uint64_t x) { return byteswap64(x); }
|
|
|
|
inline uint64_t hton64(uint64_t x) { return byteswap64(x); }
|
|
|
|
#endif // !WORDS_BIGENDIAN
|
|
|
|
|
2011-08-04 12:43:02 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
std::wstring utf8ToWChar(const std::string& src);
|
|
|
|
|
2011-08-09 14:33:55 +00:00
|
|
|
std::wstring utf8ToWChar(const char* str);
|
|
|
|
|
2011-08-04 12:43:02 +00:00
|
|
|
std::string utf8ToNative(const std::string& src);
|
|
|
|
|
|
|
|
std::string wCharToUtf8(const std::wstring& wsrc);
|
|
|
|
|
|
|
|
std::string nativeToUtf8(const std::string& src);
|
|
|
|
#else // !__MINGW32__
|
|
|
|
# define utf8ToWChar(src) src
|
|
|
|
# define utf8ToNative(src) src
|
|
|
|
#endif // !__MINGW32__
|
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
namespace util {
|
|
|
|
|
2012-09-24 14:54:41 +00:00
|
|
|
extern const char DEFAULT_STRIP_CHARSET[];
|
2012-02-29 15:02:29 +00:00
|
|
|
|
|
|
|
template<typename InputIterator>
|
|
|
|
std::pair<InputIterator, InputIterator> stripIter
|
|
|
|
(InputIterator first, InputIterator last,
|
2012-09-24 14:54:41 +00:00
|
|
|
const char* chars = DEFAULT_STRIP_CHARSET)
|
2012-02-29 15:02:29 +00:00
|
|
|
{
|
2012-09-24 14:54:41 +00:00
|
|
|
for(; first != last && strchr(chars, *first) != 0; ++first);
|
2012-02-29 15:02:29 +00:00
|
|
|
if(first == last) {
|
|
|
|
return std::make_pair(first, last);
|
|
|
|
}
|
|
|
|
InputIterator left = last-1;
|
2012-09-24 14:54:41 +00:00
|
|
|
for(; left != first && strchr(chars, *left) != 0; --left);
|
2012-02-29 15:02:29 +00:00
|
|
|
return std::make_pair(first, left+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename InputIterator>
|
|
|
|
InputIterator lstripIter
|
|
|
|
(InputIterator first, InputIterator last, char ch)
|
|
|
|
{
|
|
|
|
for(; first != last && *first == ch; ++first);
|
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
2012-09-24 14:54:41 +00:00
|
|
|
template<typename InputIterator>
|
2012-02-29 15:02:29 +00:00
|
|
|
InputIterator lstripIter
|
2012-09-24 14:54:41 +00:00
|
|
|
(InputIterator first, InputIterator last, const char* chars)
|
2012-02-29 15:02:29 +00:00
|
|
|
{
|
2012-09-24 14:54:41 +00:00
|
|
|
for(; first != last && strchr(chars, *first) != 0; ++first);
|
2012-02-29 15:02:29 +00:00
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename InputIterator>
|
|
|
|
InputIterator lstripIter
|
|
|
|
(InputIterator first, InputIterator last)
|
|
|
|
{
|
2012-09-24 14:54:41 +00:00
|
|
|
return lstripIter(first, last, DEFAULT_STRIP_CHARSET);
|
2012-02-29 15:02:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string strip
|
2012-09-24 14:54:41 +00:00
|
|
|
(const std::string& str, const char* chars = DEFAULT_STRIP_CHARSET);
|
2012-02-29 15:02:29 +00:00
|
|
|
|
2011-11-03 14:09:03 +00:00
|
|
|
template<typename InputIterator>
|
2010-10-10 03:39:00 +00:00
|
|
|
void divide
|
2011-11-05 03:01:57 +00:00
|
|
|
(std::pair<std::pair<InputIterator, InputIterator>,
|
|
|
|
std::pair<InputIterator, InputIterator> >& hp,
|
2011-11-03 14:09:03 +00:00
|
|
|
InputIterator first,
|
|
|
|
InputIterator last,
|
|
|
|
char delim)
|
|
|
|
{
|
|
|
|
InputIterator dpos = std::find(first, last, delim);
|
|
|
|
if(dpos == last) {
|
|
|
|
hp.first = stripIter(first, last);
|
|
|
|
hp.second.first = hp.second.second;
|
|
|
|
} else {
|
|
|
|
hp.first = stripIter(first, dpos);
|
|
|
|
hp.second = stripIter(dpos+1, last);
|
|
|
|
}
|
|
|
|
}
|
2009-10-22 15:09:00 +00:00
|
|
|
|
|
|
|
template<typename T>
|
2013-01-16 14:30:02 +00:00
|
|
|
std::string uitos(T n, bool comma = false)
|
2009-10-22 15:09:00 +00:00
|
|
|
{
|
2013-01-16 14:30:02 +00:00
|
|
|
std::string res;
|
|
|
|
if(n == 0) {
|
|
|
|
res = "0";
|
|
|
|
return res;
|
2008-02-24 09:43:31 +00:00
|
|
|
}
|
2013-01-16 14:30:02 +00:00
|
|
|
int i = 0;
|
|
|
|
T t = n;
|
|
|
|
for(; t; t /= 10, ++i);
|
|
|
|
if(comma) {
|
|
|
|
i += (i-1)/3;
|
|
|
|
}
|
|
|
|
res.resize(i);
|
|
|
|
--i;
|
|
|
|
for(int j = 0; n; --i, ++j, n /= 10) {
|
|
|
|
res[i] = (n%10) + '0';
|
2013-04-29 14:53:23 +00:00
|
|
|
if(comma && i > 1 && (j+1)%3 == 0) {
|
2013-01-16 14:30:02 +00:00
|
|
|
res[--i] = ',';
|
2008-02-24 09:43:31 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-16 14:30:02 +00:00
|
|
|
return res;
|
2009-10-22 15:09:00 +00:00
|
|
|
}
|
|
|
|
|
2010-03-05 14:38:49 +00:00
|
|
|
std::string itos(int64_t value, bool comma = false);
|
2006-12-24 06:25:21 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
/**
|
|
|
|
* Computes difference in micro-seconds between tv1 and tv2,
|
|
|
|
* assuming tv1 is newer than tv2.
|
|
|
|
* If tv1 is older than tv2, then this method returns 0.
|
|
|
|
*/
|
|
|
|
int64_t difftv(struct timeval tv1, struct timeval tv2);
|
|
|
|
int32_t difftvsec(struct timeval tv1, struct timeval tv2);
|
2009-10-17 13:11:03 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string replace(const std::string& target, const std::string& oldstr, const std::string& newstr);
|
2006-03-21 14:12:51 +00:00
|
|
|
|
2010-03-07 14:24:21 +00:00
|
|
|
std::string percentEncode(const unsigned char* target, size_t len);
|
2006-03-21 14:12:51 +00:00
|
|
|
|
2010-03-07 14:24:21 +00:00
|
|
|
std::string percentEncode(const std::string& target);
|
2007-03-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To handle Segment as SegmentHandle:
* src/AbstractCommand.cc (execute): Rewritten.
* src/SegmentMan.h: Segment -> SegmentHandle
Introducded HttpResponse class, HttpRequest class to improve
code
extensiveness and make it clear:
* src/HttpDownloadCommand.cc: transfer encoders are now managed
by
HttpResponse class.
* src/HttpRequest.h, src/HttpRequest.cc: New class.
* src/HttpResponse.h, src/HttpResponse.cc: New class.
* src/HttpConnection.cc: Contruction of http request were moved
to
HttpRequest class.
* src/HttpResponseCommand.h, src/HttpResponseCommand.cc:
Refactored.
* src/HttpRequestCommand.cc (executeInternal): Rewritten.
* src/HttpAuthConfig.h: New class.
* src/Range.h: New class.
To make FtpTunnel{Request, Response}Command and
HttpProxy{Request, Response}Command derived from
AbstractProxy{Request, Response}Command:
* src/FtpTunnelResponseCommand.h,
src/FtpTunnelResponseCommand.cc:
Derived from AbstractProxyRequestCommand class.
* src/FtpTunnelRequestCommand.h, src/FtpTunnelRequestCommand.cc:
Derived from AbstractProxyResponseCommand class.
* src/HttpProxyRequestCommand.h, src/HttpProxyRequestCommand.cc:
Derived from AbstractProxyRequestCommand class.
* src/HttpProxyResponseCommand.h,
src/HttpProxyResponseCommand.cc:
Derived from AbstractProxyResponseCommand class.
* src/AbstractProxyRequestCommand.h,
src/AbstractProxyRequestCommand.cc
: New class.
* src/AbstractProxyResponseCommand.h,
src/AbstractProxyResponseCommand.cc: New class.
To add netrc support:
* src/Netrc.h, src/Netrc.cc: New class.
* src/Util.h, src/Util.cc (split): New function.
* src/HttpHeader.cc (getRange): Fixed so that it inspects
"Content-Range" header instead of "Range" header.
* src/HttpHeader.h
(getStatus): Removed.
(setStatus): Removed.
* src/Segment.h
(getPositionToWrite): New function.
2007-03-15 15:07:18 +00:00
|
|
|
|
2011-08-07 11:46:04 +00:00
|
|
|
std::string percentEncodeMini(const std::string& target);
|
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
bool inRFC3986ReservedChars(const char c);
|
2008-11-27 15:29:15 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
bool inRFC3986UnreservedChars(const char c);
|
2007-11-11 04:25:56 +00:00
|
|
|
|
2012-10-27 02:41:56 +00:00
|
|
|
bool inRFC2978MIMECharset(const char c);
|
|
|
|
|
|
|
|
bool inRFC2616HttpToken(const char c);
|
|
|
|
|
|
|
|
bool inRFC5987AttrChar(const char c);
|
|
|
|
|
|
|
|
// Returns true if |c| is in ISO/IEC 8859-1 character set.
|
|
|
|
bool isIso8859p1(unsigned char c);
|
|
|
|
|
2010-10-02 07:54:43 +00:00
|
|
|
bool isUtf8(const std::string& str);
|
|
|
|
|
2011-11-03 10:27:29 +00:00
|
|
|
std::string percentDecode
|
|
|
|
(std::string::const_iterator first, std::string::const_iterator last);
|
2006-08-28 12:40:41 +00:00
|
|
|
|
2010-03-07 14:24:21 +00:00
|
|
|
std::string torrentPercentEncode(const unsigned char* target, size_t len);
|
2006-08-14 11:38:28 +00:00
|
|
|
|
2010-03-07 14:24:21 +00:00
|
|
|
std::string torrentPercentEncode(const std::string& target);
|
2008-03-07 12:05:50 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string toHex(const unsigned char* src, size_t len);
|
2006-03-21 14:12:51 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string toHex(const char* src, size_t len);
|
2008-12-09 15:03:29 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string toHex(const std::string& src);
|
2008-02-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added DHT functionality, compatible with mainline.
DHT is disabled by default. To enable it, give --enable-dht to
aria2c.
You may need to specify entry point to DHT network using
--dht-entry-point. DHT uses UDP port to listen incoming message.
Use --dht-listen-port to specify port number. Make sure that
your
firewall configuration can pass through UDP traffic to the port.
The routing table is saved in $HOME/.aria2/dht.dat.
* src/DHT*
* src/BNode.{h, cc}
* src/PeerInteractionCommand.cc: enable DHT functionality for a
particular torrent.
* src/Data.cc: Rewritten ctor.
* src/OptionHandlerFactory.cc: Added --enable-dht,
--dht-listen-port,
--dht-entry-point.
* src/DefaultBtInteractive.cc: Send port message if dht is
enabled.
* src/RequestGroup.cc: Initialize DHT functionality. When
download
ends, remove BtContext from DHTPeerAnnounceStorage.
* src/BtPortMessage.{h, cc}: Rewritten.
* src/message.h
* src/OptionHandlerImpl.cc
* src/option_processing.cc: Added --enable-dht,
--dht-listen-port,
--dht-entry-point.
* src/Dictionary.{h, cc} (remove): New function.
* src/prefs.h
* src/DefaultBtMessageFactory.h
* src/BtHandshakeMessage.cc
* src/ActivePeerConnectionCommand.cc
* src/SocketCore.{h, cc}: Added datagram socket support.
* src/DefaultBtMessageFactory.cc
* src/BtSetup.cc: Add BtContext to DHTPeerAnnounceStorage here.
Create DHT commands.
* src/BtMessageFactory.h
* src/PeerMessageUtil.{h, cc}
2008-02-01 17:36:33 +00:00
|
|
|
|
2011-11-05 09:05:23 +00:00
|
|
|
unsigned int hexCharToUInt(unsigned char ch);
|
|
|
|
|
|
|
|
// Converts hexadecimal ascii characters in [first, last) into packed
|
|
|
|
// binary form and return the result. If characters in given range is
|
|
|
|
// not well formed, then empty string is returned.
|
|
|
|
template<typename InputIterator>
|
|
|
|
std::string fromHex(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
std::string dest;
|
|
|
|
size_t len = last-first;
|
|
|
|
if(len%2) {
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
for(; first != last; first += 2) {
|
|
|
|
unsigned char high = hexCharToUInt(*first);
|
|
|
|
unsigned char low = hexCharToUInt(*(first+1));
|
|
|
|
if(high == 255 || low == 255) {
|
|
|
|
dest.clear();
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
dest += (high*16+low);
|
|
|
|
}
|
|
|
|
return dest;
|
|
|
|
}
|
2009-11-22 14:30:51 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string secfmt(time_t sec);
|
2006-04-19 17:23:58 +00:00
|
|
|
|
2011-11-11 16:06:52 +00:00
|
|
|
bool parseIntNoThrow(int32_t& res, const std::string& s, int base = 10);
|
2007-11-21 16:14:40 +00:00
|
|
|
|
2011-11-11 16:06:52 +00:00
|
|
|
// Valid range: [0, INT32_MAX]
|
|
|
|
bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
|
2010-11-15 12:52:03 +00:00
|
|
|
|
2011-11-11 16:06:52 +00:00
|
|
|
bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
|
2009-11-12 15:34:55 +00:00
|
|
|
|
2011-10-29 14:33:48 +00:00
|
|
|
void parseIntSegments(SegList<int>& sgl, const std::string& src);
|
|
|
|
|
2009-11-29 06:43:38 +00:00
|
|
|
// Parses string which specifies the range of piece index for higher
|
|
|
|
// priority and appends those indexes into result. The input string
|
|
|
|
// src can contain 2 keywords "head" and "tail". To include both
|
|
|
|
// keywords, they must be separated by comma. "head" means the pieces
|
|
|
|
// where the first byte of each file sits. "tail" means the pieces
|
|
|
|
// where the last byte of each file sits. These keywords can take one
|
|
|
|
// parameter, SIZE. For example, if "head=SIZE" is specified, pieces
|
|
|
|
// in the range of first SIZE bytes of each file get higher
|
|
|
|
// priority. SIZE can include K or M(1K = 1024, 1M = 1024K).
|
2009-12-07 12:49:19 +00:00
|
|
|
// If SIZE is omitted, SIZE=defaultSize is used.
|
2009-11-29 06:43:38 +00:00
|
|
|
//
|
|
|
|
// sample: head=512K,tail=512K
|
|
|
|
void parsePrioritizePieceRange
|
|
|
|
(std::vector<size_t>& result, const std::string& src,
|
|
|
|
const std::vector<SharedHandle<FileEntry> >& fileEntries,
|
2009-12-07 12:49:19 +00:00
|
|
|
size_t pieceLength,
|
2012-06-25 14:35:24 +00:00
|
|
|
int64_t defaultSize = 1048576 /* 1MiB */);
|
2009-11-29 06:43:38 +00:00
|
|
|
|
2010-02-17 16:09:19 +00:00
|
|
|
// Converts ISO/IEC 8859-1 string src to utf-8.
|
2012-10-27 02:41:56 +00:00
|
|
|
std::string iso8859p1ToUtf8(const char* src, size_t len);
|
|
|
|
std::string iso8859p1ToUtf8(const std::string& src);
|
|
|
|
|
|
|
|
// Parses Content-Disposition header field value |in| with its length
|
|
|
|
// |len| in a manner conforming to RFC 6266 and extracts filename
|
|
|
|
// value and copies it to the region pointed by |dest|. The |destlen|
|
|
|
|
// specifies the capacity of the |dest|. This function does not store
|
|
|
|
// NUL character after filename in |dest|. This function does not
|
|
|
|
// support RFC 2231 Continuation. If the function sees RFC 2231/5987
|
|
|
|
// encoding and charset, it stores its first pointer to |*charsetp|
|
|
|
|
// and its length in |*charsetlenp|. Otherwise, they are NULL and 0
|
|
|
|
// respectively. In RFC 2231/5987 encoding, percent-encoded string
|
|
|
|
// will be decoded to original form and stored in |dest|.
|
|
|
|
//
|
|
|
|
// This function returns the number of written bytes in |dest| if it
|
|
|
|
// succeeds, or -1. If there is enough room to store filename in
|
|
|
|
// |dest|, this function returns -1. If this function returns -1, the
|
|
|
|
// |dest|, |*charsetp| and |*charsetlenp| are undefined.
|
2012-11-01 13:54:32 +00:00
|
|
|
ssize_t parse_content_disposition(char *dest, size_t destlen,
|
|
|
|
const char **charsetp, size_t *charsetlenp,
|
|
|
|
const char *in, size_t len);
|
2010-02-17 16:09:19 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string getContentDispositionFilename(const std::string& header);
|
2006-05-18 17:08:29 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string toUpper(const std::string& src);
|
2006-07-03 14:19:23 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string toLower(const std::string& src);
|
2006-08-11 12:29:55 +00:00
|
|
|
|
2010-10-10 02:51:38 +00:00
|
|
|
void uppercase(std::string& s);
|
|
|
|
|
|
|
|
void lowercase(std::string& s);
|
|
|
|
|
2012-03-30 15:06:55 +00:00
|
|
|
char toUpperChar(char c);
|
|
|
|
|
|
|
|
char toLowerChar(char c);
|
|
|
|
|
2010-01-28 14:25:16 +00:00
|
|
|
bool isNumericHost(const std::string& name);
|
2006-11-09 14:04:46 +00:00
|
|
|
|
2013-02-14 12:51:30 +00:00
|
|
|
void setGlobalSignalHandler(int signal, sigset_t* mask, void (*handler)(int),
|
|
|
|
int flags);
|
2007-01-23 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add chunk checksum validation:
* src/MetalinkEntry.h
(MetalinkChunkChecksum.h): New include.
(chunkChecksum): New variable.
* src/Request.h
(method): New variable.
(setMethod): New function.
(getMethod): New function.
(METHOD_GET): New static constant.
(METHOD_HEAD): New static constant.
* src/Xml2MetalinkProcessor.h
(getPieceHash): New function.
* src/PieceStorage.h
(markAllPiecesDone): New function.
(checkIntegrity): New function.
* src/FileAllocator.h
(NullFileAllocationMonitor.h): New include.
(FileAllocator): Initialize fileAllocationMonitor with new
NullFileAllocationMonitor().
* src/MultiDiskAdaptor.h
(messageDigest.h): Remove include.
(ctx): Removed.
(hashUpdate): Added ctx.
(MultiDiskAdaptor): Removed ctx.
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/UrlRequestInfo.h
(HeadResult): New class.
(digestAlgo): New variable.
(chunkChecksumLength): New variable.
(chunkChecksums): New variable.
(getHeadResult): New function.
(UrlRequestInfo): Added digestAlgo, chunkChecksumLength.
(setDigestAlgo): New function.
(setChunkChecksumLength): New function.
(setChunkChecksums): New function.
* src/DefaultPieceStorage.cc
(DiskAdaptorWriter.h): New include.
(ChunkChecksumValidator.h): New include.
(markAllPiecesDone): New function.
(checkIntegrity): New function.
* src/DefaultBtContext.h
(getPieceHashes): New function.
* src/TorrentRequestInfo.cc
(execute): Try to validate chunk checksum if file already exists
and
.aria2 file doesn't there and user allows aria2 to overwrite it.
* src/messageDigest.h
(~MessageDigestContext): Added digestFree().
* src/MetalinkRequestInfo.cc
(execute): Set digestAlgo, chunkChecksum, chunkChecksums to
reqInfo.
* src/DiskAdaptor.h
(messageDigest.h): New include.
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/DownloadCommand.h
(PeerStat.h): New include.
(maxDownloadSpeedLimit): New variable.
(startupIdleTime): New variable.
(lowestDownloadSpeedLimit): New variable.
(peerStat): New variable.
(setMaxDownloadSpeedLimit): New function.
(setStartupIdleTime): New function.
(setLowestDownloadSPeedLimit): New function.
* src/BtContext.h
(getPieceHashes): New function.
* src/main.cc
(main): Set PREF_REALTIME_CHUNK_CHECKSUM and
PREF_CHECK_INTEGRITY
option to true for testing purpose.
* src/BtPieceMessage.cc
(checkPieceHash): Use messageDigest
* src/DownloadEngine.cc
(SetDescriptor): Removed.
(AccumulateActiveCommand): Removed.
(waitData): Rewritten.
(updateFdSet): Rewritten.
* src/MultiDiskAdaptor.cc
(hashUpdate): Added ctx.
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/BitfieldMan.h
(isBitRangeSet): New function.
(unsetBitRange): New function.
* src/ByteArrayDiskWriter.h
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/ConsoleDownloadEngine.cc
(calculateStatistics): If nspeed < 0 then set nspeed to 0.
* src/DiskWriter.h
(messageDigest.h): New include.
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/ChunkChecksumValidator.h: New class.
* src/DiskAdaptorWriter.h: New class.
* src/prefs.h
(PREF_REALTIME_CHUNK_CHECKSUM): New definition.
(PREF_CHECK_INTEGRITY): New definition.
* src/HttpResponseCommand.cc
(handleDefaultEncoding): Added method "HEAD" handling.
Removed the call to
e->segmentMan->shouldCancelDownloadForSafety().
(handleOtherEncoding):
Added the call to
e->segmentMan->shouldCancelDownloadForSafety().
(createHttpDownloadCommand): Set maxDownloadSpeedLimit,
startupIdleTime, lowestDownloadSpeedLimit to command.
* src/SegmentMan.h
(getSegmentEntryByIndex): New function.
(getSegmentEntryByCuid): New function.
(getSegmentEntryIteratorByCuid): New function.
(diskWriter): DiskWriter -> DiskWriterHandle
(pieceHashes): New variable.
(chunkHashLength): New variable.
(digestAlgo): New variable.
(FindPeerStat): Removed.
(getPeerStat): Rewritten.
(markAllPiecesDone): New function.
(checkIntegrity): New function.
(tryChunkChecksumValidation): New function.
(isChunkChecksumValidationReady): New function.
* src/BitfieldMan.cc
(BitfieldMan): Initialized bitfieldLength, blocks to 0.
(BitfieldMan): Initialized blockLength, totalLength,
bitfieldLength,
blocks to 0.
(isBitRangeSet): New function.
(unsetBitRange): New function.
* src/FtpNegotiateCommand.cc
(executeInternal): Set maxDownloadSpeedLimit,
startupIdleTime, lowestDownloadSpeedLimit to command.
(recvSize): Added method "HEAD" handling.
Removed the call to
e->segmentMan->shouldCancelDownloadForSafety().
* src/AbstractSingleDiskAdaptor.cc
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/AbstractSingleDiskAdaptor.h
(sha1Sum): Renamed as messageDigest.
(messageDigest): New function.
* src/Util.h
(indexRange): New function.
* src/MetalinkEntry.cc
(MetalinkEntry): Initialized chunkChecksum to 0.
* src/ShaVisitor.cc
(~ShaVisitor): Removed the call to ctx.digestFree().
* src/SegmentMan.cc
(ChunkChecksumValidator.h): New include.
(SegmentMan): Initialized chunkHashLength to 0. Initialized
digestAlgo
to DIGEST_ALGO_SHA1.
(~SegmentMan): Removed diskWriter.
(FindSegmentEntryByIndex): Removed.
(FindSegmentEntryByCuid): Removed.
(checkoutSegment): Rewritten.
(findSlowerSegmentEntry): Rewritten.
(getSegment): Rewritten.
(updateSegment): Rewritten.
(completeSegment): Rewritten.
(markAllPiecesDone): New function.
(checkIntegrity): New function.
(isChunkChecksumValidationReady): New function.
(tryChunkChecksumValidation): New function.
* src/Xml2MetalinkProcessor.cc
(getEntry): Get size and set it to entry.
Get chunk checksum and set it to entry.
(getPieceHash): New function.
* src/Util.cc
(sha1Sum): Removed ctx.digestFree()
(fileChecksum): Removed ctx.digestFree()
(indexRange): New function.
* src/Request.cc
(METHOD_GET): New variable.
(METHOD_HEAD): New variable.
(Request): Added method.
* src/UrlRequestInfo.cc
(FatalException.h): New include.
(message.h): New include.
(operator<<): Added operator<< for class HeadResult.
(getHeadResult): New function.
(execute): Get filename and size in separate download engine.
* src/ChunkChecksumValidator.cc: New class.
* src/DownloadCommand.cc:
(DownloadCommand): Added peerStat.
(executeInternal): Use maxDownloadSpeedLimit member instead of
getting
the value from Option.
The buffer size is now 16KB.
Use peerStat member instead of getting it from SegmentMan.
Use startupIdleTime member instead of gettingit from Option.
Added chunk checksum validation.
* src/AbstractDiskWriter.cc
(AbstractDiskWriter): Removed ctx.
(~AbstractDiskWriter): Removed ctx.digestFree()
(writeDataInternal): Returns the return value of write.
(readDataInternal): Returns the return value of read.
(sha1Sum): Renamed as messageDigest
(messageDigest): New function.
* src/AbstractDiwkWriter.h
(messageDigest.h): Removed include.
(ctx): Removed.
(sha1Sum): Renamed as messageDigest
(messageDigest): New function.
* src/DefaultPieceStorage.h
(markAllPiecesDone): New function.
(checkIntegrity): New function.
* src/NullFileAllocationMonitor.h: New class.
2007-01-24 15:55:34 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string getHomeDir();
|
2007-03-26 12:16:57 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
int64_t getRealSize(const std::string& sizeWithUnit);
|
2007-06-05 11:37:25 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::string abbrevSize(int64_t size);
|
2007-06-10 07:55:43 +00:00
|
|
|
|
2011-08-09 14:33:55 +00:00
|
|
|
template<typename InputIterator, typename Output>
|
2009-10-22 15:09:00 +00:00
|
|
|
void toStream
|
2011-08-09 14:33:55 +00:00
|
|
|
(InputIterator first, InputIterator last, Output& os)
|
2009-10-22 15:09:00 +00:00
|
|
|
{
|
2011-08-09 14:33:55 +00:00
|
|
|
os.printf("%s\n"
|
|
|
|
"idx|path/length\n"
|
|
|
|
"===+===========================================================================\n", _("Files:"));
|
2009-10-22 15:09:00 +00:00
|
|
|
int32_t count = 1;
|
|
|
|
for(; first != last; ++first, ++count) {
|
2011-08-09 14:33:55 +00:00
|
|
|
os.printf("%3d|%s\n"
|
|
|
|
" |%sB (%s)\n"
|
|
|
|
"---+---------------------------------------------------------------------------\n",
|
|
|
|
count,
|
|
|
|
(*first)->getPath().c_str(),
|
|
|
|
util::abbrevSize((*first)->getLength()).c_str(),
|
|
|
|
util::uitos((*first)->getLength(), true).c_str());
|
2009-06-28 10:37:15 +00:00
|
|
|
}
|
2009-10-22 15:09:00 +00:00
|
|
|
}
|
2007-08-14 14:51:08 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
void sleep(long seconds);
|
2007-08-14 14:51:08 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
void usleep(long microseconds);
|
2011-11-06 07:37:02 +00:00
|
|
|
|
|
|
|
template<typename InputIterator>
|
|
|
|
bool isNumber(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
if(first == last) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for(; first != last; ++first) {
|
|
|
|
if('0' > *first || *first > '9') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2010-03-02 15:14:39 +00:00
|
|
|
|
2012-02-14 16:40:12 +00:00
|
|
|
bool isAlpha(const char c);
|
|
|
|
|
2010-03-20 09:10:23 +00:00
|
|
|
bool isDigit(const char c);
|
|
|
|
|
2010-03-02 15:14:39 +00:00
|
|
|
bool isHexDigit(const char c);
|
|
|
|
|
|
|
|
bool isHexDigit(const std::string& s);
|
2011-11-06 07:37:02 +00:00
|
|
|
|
2012-06-23 08:34:20 +00:00
|
|
|
bool isLws(const char c);
|
|
|
|
|
|
|
|
bool isCRLF(const char c);
|
|
|
|
|
2011-11-06 07:37:02 +00:00
|
|
|
template<typename InputIterator>
|
|
|
|
bool isLowercase(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
if(first == last) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for(; first != last; ++first) {
|
|
|
|
if('a' > *first || *first > 'z') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename InputIterator>
|
|
|
|
bool isUppercase(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
if(first == last) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for(; first != last; ++first) {
|
|
|
|
if('A' > *first || *first > 'Z') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2010-03-02 15:14:39 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
void mkdirs(const std::string& dirpath);
|
2007-11-13 10:10:11 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
void convertBitfield(BitfieldMan* dest, const BitfieldMan* src);
|
2007-11-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten to add content-type support.
* src/DownloadHandler.{h, cc}
* src/BtPostDownloadHandler.{h, cc}
* test/BtPostDownloadHandlerTest.cc
* src/MetalinkPostDownloadHandler.{h, cc}
* test/MetalinkPostDownloadHandlerTest.cc
* src/PostDownloadHandler.{h, cc}
* src/DownloadHandlerConstants.{h, cc}
* src/RequestGroup.cc
* src/HttpResponseCommand.cc
* src/FtpNegotiationCommand.cc
* src/SingleFileDownloadContext.{h, cc}
* src/RequestGroup.h
* src/RequestGroupCriteria.h
* src/ContentTypeRequestGroupCriteria.h
Added 'mem' option value for --follow-metalink,
--follow-torrent.
If it is give, metalink/torrent file is not written to the disk,
but
just is kept in memory. Parsing is occurred on memory.
* src/MetalinkHelper.{h, cc}
* src/MetalinkProcessor.h
* src/Xml2MetalinkProcessor.{h, cc}
* test/Xml2MetalinkProcessorTest.cc
* src/DownloadHandlerFactory.{h, cc}
* test/DownloadHandlerFactoryTest.cc
* src/PreDownloadHandler.{h, cc}
* src/OptionHandlerFactory.cc
* src/DefaultBtContext.{h, cc}
* test/DefaultBtContextTest.cc
* src/version_usage.cc
* src/Metalink2RequestGroup.{h, cc}
* src/RequestGroup.{h, cc}
* src/a2functional.h
* test/a2functionalTest.cc
* src/MemoryBufferPreDownloadHandler.{h, cc}
* src/OptionHandlerImpl.h
* src/prefs.h
* src/Util.{h, cc}
* test/UtilTest.cc
Keep DownloadResult rather than RequestGroup after downloads to
reduce
memory usage.
* src/RequestGroupMan.{h, cc}
* src/DownloadEngine.cc
* src/BtDependency.{h, cc}: Changed the type of dependee from
WeakHandle to SharedHandle because WeakHandle could be null.
* src/RequestGroup.{h, cc}
* src/DownloadEngineFactory.cc
* src/DownloadResult.h
Set totalLength after download finished
* src/UnknownLengthPieceStorage.{h, cc}
Keep torrent file specified in metalink in memory.
* src/Metalink2RequestGroup.cc
* src/BtDependency.cc
* src/TrueRequestGroupCriteria.h
Fixed the bug: seekg is used where seekp should be used.
* src/ByteArrayDiskWriter.cc
* test/ByteArraydiskWriterTest.cc
2007-11-27 12:27:10 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
// binaryStream has to be opened before calling this function.
|
|
|
|
std::string toString(const SharedHandle<BinaryStream>& binaryStream);
|
2007-11-28 14:22:28 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_POSIX_MEMALIGN
|
2009-10-22 15:09:00 +00:00
|
|
|
void* allocateAlignedMemory(size_t alignment, size_t size);
|
2007-11-28 14:22:28 +00:00
|
|
|
#endif // HAVE_POSIX_MEMALIGN
|
2008-05-08 11:18:36 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
std::pair<std::string, uint16_t>
|
|
|
|
getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len);
|
|
|
|
|
|
|
|
std::string htmlEscape(const std::string& src);
|
|
|
|
|
|
|
|
// Joins path element specified in [first, last). If ".." is found,
|
|
|
|
// it eats the previous element if it exists. If "." is found, it
|
|
|
|
// is just ignored and it is not appeared in the result.
|
|
|
|
template<typename InputIterator>
|
|
|
|
std::string joinPath(InputIterator first, InputIterator last)
|
|
|
|
{
|
2010-02-28 12:30:11 +00:00
|
|
|
std::vector<std::string> elements;
|
2009-10-22 15:09:00 +00:00
|
|
|
for(;first != last; ++first) {
|
|
|
|
if(*first == "..") {
|
|
|
|
if(!elements.empty()) {
|
2010-01-05 16:01:46 +00:00
|
|
|
elements.pop_back();
|
2009-03-04 15:53:56 +00:00
|
|
|
}
|
2009-10-22 15:09:00 +00:00
|
|
|
} else if(*first == ".") {
|
|
|
|
// do nothing
|
|
|
|
} else {
|
|
|
|
elements.push_back(*first);
|
2009-03-04 15:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-22 15:09:00 +00:00
|
|
|
return strjoin(elements.begin(), elements.end(), "/");
|
|
|
|
}
|
2009-03-07 03:10:53 +00:00
|
|
|
|
2009-10-22 15:09:00 +00:00
|
|
|
// Parses INDEX=PATH format string. INDEX must be an unsigned
|
|
|
|
// integer.
|
2011-11-01 15:18:39 +00:00
|
|
|
std::pair<size_t, std::string>
|
2009-10-22 15:09:00 +00:00
|
|
|
parseIndexPath(const std::string& line);
|
2009-03-07 03:10:53 +00:00
|
|
|
|
2011-11-01 15:18:39 +00:00
|
|
|
std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i);
|
2006-02-17 13:35:04 +00:00
|
|
|
|
2009-10-18 12:31:07 +00:00
|
|
|
/**
|
2011-11-04 13:27:58 +00:00
|
|
|
* Take a string [first, last) which is a delimited list and add its
|
|
|
|
* elements into result as iterator pair. result is stored in out.
|
2009-10-18 12:31:07 +00:00
|
|
|
*/
|
2011-11-04 13:27:58 +00:00
|
|
|
template<typename InputIterator, typename OutputIterator>
|
|
|
|
OutputIterator splitIter
|
|
|
|
(InputIterator first,
|
|
|
|
InputIterator last,
|
|
|
|
OutputIterator out,
|
|
|
|
char delim,
|
|
|
|
bool doStrip = false,
|
|
|
|
bool allowEmpty = false)
|
|
|
|
{
|
|
|
|
for(InputIterator i = first; i != last;) {
|
|
|
|
InputIterator j = std::find(i, last, delim);
|
|
|
|
std::pair<InputIterator, InputIterator> p(i, j);
|
|
|
|
if(doStrip) {
|
|
|
|
p = stripIter(i, j);
|
|
|
|
}
|
|
|
|
if(allowEmpty || p.first != p.second) {
|
|
|
|
*out++ = p;
|
|
|
|
}
|
|
|
|
i = j;
|
|
|
|
if(j != last) {
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(allowEmpty &&
|
|
|
|
(first == last || *(last-1) == delim)) {
|
|
|
|
*out++ = std::make_pair(last, last);
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
template<typename InputIterator, typename OutputIterator>
|
2011-11-04 13:27:58 +00:00
|
|
|
OutputIterator splitIterM
|
|
|
|
(InputIterator first,
|
|
|
|
InputIterator last,
|
|
|
|
OutputIterator out,
|
2012-01-10 16:03:38 +00:00
|
|
|
const char* delims,
|
2011-11-04 13:27:58 +00:00
|
|
|
bool doStrip = false,
|
|
|
|
bool allowEmpty = false)
|
|
|
|
{
|
2012-01-10 16:03:38 +00:00
|
|
|
size_t numDelims = strlen(delims);
|
|
|
|
const char* dlast = delims+numDelims;
|
2011-11-04 13:27:58 +00:00
|
|
|
for(InputIterator i = first; i != last;) {
|
|
|
|
InputIterator j = i;
|
2012-01-10 16:03:38 +00:00
|
|
|
for(; j != last && std::find(delims, dlast, *j) == dlast; ++j);
|
2011-11-04 13:27:58 +00:00
|
|
|
std::pair<InputIterator, InputIterator> p(i, j);
|
|
|
|
if(doStrip) {
|
|
|
|
p = stripIter(i, j);
|
|
|
|
}
|
|
|
|
if(allowEmpty || p.first != p.second) {
|
|
|
|
*out++ = p;
|
|
|
|
}
|
|
|
|
i = j;
|
|
|
|
if(j != last) {
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(allowEmpty &&
|
|
|
|
(first == last ||
|
2012-01-10 16:03:38 +00:00
|
|
|
std::find(delims, dlast, *(last-1)) != dlast)) {
|
2011-11-04 13:27:58 +00:00
|
|
|
*out++ = std::make_pair(last, last);
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename InputIterator, typename OutputIterator>
|
|
|
|
OutputIterator split
|
|
|
|
(InputIterator first,
|
|
|
|
InputIterator last,
|
|
|
|
OutputIterator out,
|
|
|
|
char delim,
|
|
|
|
bool doStrip = false,
|
|
|
|
bool allowEmpty = false)
|
2009-10-18 12:31:07 +00:00
|
|
|
{
|
2011-11-04 13:27:58 +00:00
|
|
|
for(InputIterator i = first; i != last;) {
|
|
|
|
InputIterator j = std::find(i, last, delim);
|
|
|
|
std::pair<InputIterator, InputIterator> p(i, j);
|
2011-11-03 07:19:21 +00:00
|
|
|
if(doStrip) {
|
|
|
|
p = stripIter(i, j);
|
|
|
|
}
|
|
|
|
if(allowEmpty || p.first != p.second) {
|
|
|
|
*out++ = std::string(p.first, p.second);
|
2009-10-18 12:31:07 +00:00
|
|
|
}
|
2010-10-10 06:58:31 +00:00
|
|
|
i = j;
|
|
|
|
if(j != last) {
|
|
|
|
++i;
|
2009-10-18 12:31:07 +00:00
|
|
|
}
|
|
|
|
}
|
2010-10-10 06:58:31 +00:00
|
|
|
if(allowEmpty &&
|
2011-11-04 13:27:58 +00:00
|
|
|
(first == last || *(last-1) == delim)) {
|
|
|
|
*out++ = std::string(last, last);
|
2010-10-10 06:58:31 +00:00
|
|
|
}
|
2009-10-18 12:31:07 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2011-11-04 13:27:58 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool streq
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 != last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return std::equal(first1, last1, first2);
|
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
template<typename InputIterator>
|
|
|
|
bool streq(InputIterator first, InputIterator last, const char* b)
|
|
|
|
{
|
2012-01-10 16:50:35 +00:00
|
|
|
for(; first != last && *b != '\0'; ++first, ++b) {
|
|
|
|
if(*first != *b) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return first == last && *b == '\0';
|
2012-01-10 16:03:38 +00:00
|
|
|
}
|
|
|
|
|
2011-11-08 14:27:23 +00:00
|
|
|
struct CaseCmp {
|
|
|
|
bool operator()(char lhs, char rhs) const
|
|
|
|
{
|
|
|
|
if('A' <= lhs && lhs <= 'Z') {
|
|
|
|
lhs += 'a'-'A';
|
|
|
|
}
|
|
|
|
if('A' <= rhs && rhs <= 'Z') {
|
|
|
|
rhs += 'a'-'A';
|
|
|
|
}
|
|
|
|
return lhs == rhs;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-11-11 13:50:18 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
InputIterator1 strifind
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
return std::search(first1, last1, first2, last2, CaseCmp());
|
|
|
|
}
|
|
|
|
|
2011-11-04 13:27:58 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool strieq
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 != last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
2011-11-08 14:27:23 +00:00
|
|
|
return std::equal(first1, last1, first2, CaseCmp());
|
2011-11-04 13:27:58 +00:00
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
template<typename InputIterator>
|
|
|
|
bool strieq(InputIterator first, InputIterator last, const char* b)
|
|
|
|
{
|
2012-01-10 16:50:35 +00:00
|
|
|
CaseCmp cmp;
|
|
|
|
for(; first != last && *b != '\0'; ++first, ++b) {
|
|
|
|
if(!cmp(*first, *b)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return first == last && *b == '\0';
|
2012-01-10 16:03:38 +00:00
|
|
|
}
|
|
|
|
|
2012-09-22 14:19:41 +00:00
|
|
|
bool strieq(const std::string& a, const char* b);
|
|
|
|
bool strieq(const std::string& a, const std::string& b);
|
|
|
|
|
2011-11-04 13:27:58 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool startsWith
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 < last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return std::equal(first2, last2, first1);
|
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
template<typename InputIterator>
|
|
|
|
bool startsWith(InputIterator first, InputIterator last, const char* b)
|
|
|
|
{
|
2012-01-10 16:50:35 +00:00
|
|
|
for(; first != last && *b != '\0'; ++first, ++b) {
|
|
|
|
if(*first != *b) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *b == '\0';
|
2012-01-10 16:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool startsWith(const std::string& a, const char* b);
|
2012-01-10 16:17:51 +00:00
|
|
|
bool startsWith(const std::string& a, const std::string& b);
|
2012-01-10 16:03:38 +00:00
|
|
|
|
2011-11-04 15:33:35 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool istartsWith
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 < last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
2011-11-08 14:27:23 +00:00
|
|
|
return std::equal(first2, last2, first1, CaseCmp());
|
2011-11-04 15:33:35 +00:00
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
template<typename InputIterator>
|
|
|
|
bool istartsWith(InputIterator first, InputIterator last, const char* b)
|
|
|
|
{
|
2012-01-10 16:50:35 +00:00
|
|
|
CaseCmp cmp;
|
|
|
|
for(; first != last && *b != '\0'; ++first, ++b) {
|
|
|
|
if(!cmp(*first, *b)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *b == '\0';
|
2012-01-10 16:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool istartsWith(const std::string& a, const char* b);
|
|
|
|
|
2011-11-04 13:27:58 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool endsWith
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 < last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return std::equal(first2, last2, last1-(last2-first2));
|
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
bool endsWith(const std::string& a, const char* b);
|
|
|
|
bool endsWith(const std::string& a, const std::string& b);
|
|
|
|
|
2011-11-04 15:25:24 +00:00
|
|
|
template<typename InputIterator1, typename InputIterator2>
|
|
|
|
bool iendsWith
|
|
|
|
(InputIterator1 first1,
|
|
|
|
InputIterator1 last1,
|
|
|
|
InputIterator2 first2,
|
|
|
|
InputIterator2 last2)
|
|
|
|
{
|
|
|
|
if(last1-first1 < last2-first2) {
|
|
|
|
return false;
|
|
|
|
}
|
2011-11-08 14:27:23 +00:00
|
|
|
return std::equal(first2, last2, last1-(last2-first2), CaseCmp());
|
2011-11-04 15:25:24 +00:00
|
|
|
}
|
|
|
|
|
2012-01-10 16:03:38 +00:00
|
|
|
bool iendsWith(const std::string& a, const char* b);
|
|
|
|
bool iendsWith(const std::string& a, const std::string& b);
|
|
|
|
|
2012-09-23 11:59:34 +00:00
|
|
|
// Returns true if strcmp(a, b) < 0
|
|
|
|
bool strless(const char* a, const char *b);
|
|
|
|
|
2009-10-22 14:43:42 +00:00
|
|
|
void generateRandomData(unsigned char* data, size_t length);
|
|
|
|
|
2009-12-23 13:16:57 +00:00
|
|
|
// Saves data to file whose name is filename. If overwrite is true,
|
|
|
|
// existing file is overwritten. Otherwise, this function doesn't do
|
|
|
|
// nothing. If data is saved successfully, return true. Otherwise
|
|
|
|
// returns false.
|
|
|
|
bool saveAs
|
|
|
|
(const std::string& filename, const std::string& data, bool overwrite=false);
|
|
|
|
|
2010-01-11 14:01:20 +00:00
|
|
|
// Prepend dir to relPath. If dir is empty, it prepends "." to relPath.
|
|
|
|
//
|
|
|
|
// dir = "/dir", relPath = "foo" => "/dir/foo"
|
|
|
|
// dir = "", relPath = "foo" => "./foo"
|
|
|
|
// dir = "/", relPath = "foo" => "/foo"
|
|
|
|
std::string applyDir(const std::string& dir, const std::string& relPath);
|
|
|
|
|
2010-01-11 14:32:20 +00:00
|
|
|
// In HTTP/FTP, file name is file component in URI. In HTTP, filename
|
|
|
|
// may be a value of Content-Disposition header. They are likely
|
|
|
|
// percent encoded. If they contains, for example, %2F, when decoded,
|
|
|
|
// basename contains dir component. This should be avoided. This
|
|
|
|
// function is created to fix these issues. This function expects src
|
|
|
|
// should be non-percent-encoded basename. Currently, this function
|
2010-02-27 10:06:40 +00:00
|
|
|
// replaces '/' with '_' and result string is passed to escapePath()
|
|
|
|
// function and its result is returned.
|
2010-01-11 14:32:20 +00:00
|
|
|
std::string fixTaintedBasename(const std::string& src);
|
|
|
|
|
2010-01-17 10:05:53 +00:00
|
|
|
// Generates 20 bytes random key and store it to the address pointed
|
|
|
|
// by key. Caller must allocate at least 20 bytes for generated key.
|
|
|
|
void generateRandomKey(unsigned char* key);
|
|
|
|
|
2010-02-20 14:23:25 +00:00
|
|
|
// Returns true is given numeric ipv4addr is in Private Address Space.
|
|
|
|
bool inPrivateAddress(const std::string& ipv4addr);
|
|
|
|
|
2010-02-25 14:40:18 +00:00
|
|
|
// Returns true if s contains directory traversal path component such
|
2010-02-27 10:06:40 +00:00
|
|
|
// as '..' or it contains null or control character which may fool
|
|
|
|
// user.
|
2010-02-25 14:40:18 +00:00
|
|
|
bool detectDirTraversal(const std::string& s);
|
|
|
|
|
2010-02-27 10:06:40 +00:00
|
|
|
// Replaces null(0x00) and control character(0x01-0x1f) with '_'. If
|
|
|
|
// __MINGW32__ is defined, following characters are also replaced with
|
|
|
|
// '_': '"', '*', ':', '<', '>', '?', '\', '|'.
|
|
|
|
std::string escapePath(const std::string& s);
|
|
|
|
|
2011-10-19 14:14:13 +00:00
|
|
|
// Returns true if ip1 and ip2 are in the same CIDR block. ip1 and
|
|
|
|
// ip2 must be numeric IPv4 or IPv6 address. If either of them or both
|
|
|
|
// of them is not valid numeric address, then returns false. bits is
|
|
|
|
// prefix bits. If bits is out of range, then bits is set to the
|
|
|
|
// length of binary representation of the address*8.
|
|
|
|
bool inSameCidrBlock
|
|
|
|
(const std::string& ip1, const std::string& ip2, size_t bits);
|
2010-03-19 08:56:17 +00:00
|
|
|
|
2010-11-29 12:06:00 +00:00
|
|
|
// No throw
|
2010-07-16 14:22:57 +00:00
|
|
|
void executeHookByOptName
|
|
|
|
(const SharedHandle<RequestGroup>& group, const Option* option,
|
2011-10-21 12:56:42 +00:00
|
|
|
const Pref* pref);
|
2010-07-16 14:22:57 +00:00
|
|
|
|
2010-11-29 12:06:00 +00:00
|
|
|
// No throw
|
2010-07-16 15:00:35 +00:00
|
|
|
void executeHookByOptName
|
2011-10-21 12:56:42 +00:00
|
|
|
(const RequestGroup* group, const Option* option, const Pref* pref);
|
2010-07-16 15:00:35 +00:00
|
|
|
|
2010-10-02 07:54:43 +00:00
|
|
|
std::string createSafePath(const std::string& dir, const std::string& filename);
|
|
|
|
|
|
|
|
std::string encodeNonUtf8(const std::string& s);
|
|
|
|
|
2010-11-09 14:43:47 +00:00
|
|
|
// Create string safely. If str is NULL, returns empty string.
|
|
|
|
// Otherwise, returns std::string(str).
|
|
|
|
std::string makeString(const char* str);
|
|
|
|
|
|
|
|
// This function is basically the same with strerror(errNum) but when
|
|
|
|
// strerror returns NULL, this function returns empty string.
|
|
|
|
std::string safeStrerror(int errNum);
|
|
|
|
|
2011-07-26 14:41:21 +00:00
|
|
|
// Parses sequence [first, last) and find name=value pair delimited by
|
|
|
|
// delim character. If name(and optionally value) is found, returns
|
|
|
|
// pair of iterator which can use as first parameter of next call of
|
|
|
|
// this function, and true. If no name is found, returns the pair of
|
|
|
|
// last and false.
|
|
|
|
template<typename Iterator>
|
|
|
|
std::pair<Iterator, bool>
|
|
|
|
nextParam
|
|
|
|
(std::string& name,
|
|
|
|
std::string& value,
|
|
|
|
Iterator first,
|
|
|
|
Iterator last,
|
|
|
|
char delim)
|
|
|
|
{
|
|
|
|
Iterator end = last;
|
|
|
|
while(first != end) {
|
|
|
|
last = first;
|
|
|
|
Iterator parmnameFirst = first;
|
|
|
|
Iterator parmnameLast = first;
|
|
|
|
bool eqFound = false;
|
|
|
|
for(; last != end; ++last) {
|
|
|
|
if(*last == delim) {
|
|
|
|
break;
|
|
|
|
} else if(!eqFound && *last == '=') {
|
|
|
|
eqFound = true;
|
|
|
|
parmnameFirst = first;
|
|
|
|
parmnameLast = last;
|
|
|
|
}
|
|
|
|
}
|
2011-11-03 07:19:21 +00:00
|
|
|
std::pair<std::string::const_iterator,
|
|
|
|
std::string::const_iterator> namep;
|
|
|
|
std::pair<std::string::const_iterator,
|
|
|
|
std::string::const_iterator> valuep;
|
2011-07-26 14:41:21 +00:00
|
|
|
if(parmnameFirst == parmnameLast) {
|
|
|
|
if(!eqFound) {
|
|
|
|
parmnameFirst = first;
|
|
|
|
parmnameLast = last;
|
2011-11-03 07:19:21 +00:00
|
|
|
namep = stripIter(parmnameFirst, parmnameLast);
|
2011-07-26 14:41:21 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
first = parmnameLast+1;
|
2011-11-03 07:19:21 +00:00
|
|
|
namep = stripIter(parmnameFirst, parmnameLast);
|
|
|
|
valuep = stripIter(first, last);
|
2011-07-26 14:41:21 +00:00
|
|
|
}
|
|
|
|
if(last != end) {
|
|
|
|
++last;
|
|
|
|
}
|
2011-11-03 07:19:21 +00:00
|
|
|
if(namep.first != namep.second) {
|
|
|
|
name.assign(namep.first, namep.second);
|
|
|
|
value.assign(valuep.first, valuep.second);
|
2011-07-26 14:41:21 +00:00
|
|
|
return std::make_pair(last, true);
|
|
|
|
}
|
|
|
|
first = last;
|
|
|
|
}
|
|
|
|
return std::make_pair(end, false);
|
|
|
|
}
|
|
|
|
|
2011-10-25 12:44:04 +00:00
|
|
|
template<typename T>
|
|
|
|
SharedHandle<T> copy(const SharedHandle<T>& a)
|
|
|
|
{
|
|
|
|
return SharedHandle<T>(new T(*a.get()));
|
|
|
|
}
|
|
|
|
|
2011-10-28 15:16:46 +00:00
|
|
|
// This is a bit different from cookie_helper::domainMatch(). If
|
|
|
|
// hostname is numeric host, then returns true if domain == hostname.
|
|
|
|
// That is if domain starts with ".", then returns true if domain is a
|
|
|
|
// suffix of hostname. If domain does not start with ".", then
|
|
|
|
// returns true if domain == hostname. Otherwise returns true.
|
|
|
|
// For example,
|
|
|
|
//
|
|
|
|
// * noProxyDomainMatch("aria2.sf.net", ".sf.net") returns true.
|
|
|
|
// * noProxyDomainMatch("sf.net", ".sf.net") returns false.
|
|
|
|
bool noProxyDomainMatch(const std::string& hostname, const std::string& domain);
|
|
|
|
|
2012-03-30 14:49:14 +00:00
|
|
|
// Checks hostname matches pattern as described in RFC 6125.
|
2012-03-28 14:28:22 +00:00
|
|
|
bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname);
|
|
|
|
|
2009-10-22 14:43:42 +00:00
|
|
|
} // namespace util
|
|
|
|
|
2008-02-08 15:53:45 +00:00
|
|
|
} // namespace aria2
|
|
|
|
|
2010-10-31 07:23:53 +00:00
|
|
|
#endif // D_UTIL_H
|