util.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #ifndef D_UTIL_H
  36. #define D_UTIL_H
  37. #include "common.h"
  38. #include <sys/time.h>
  39. #include <limits.h>
  40. #include <stdint.h>
  41. #include <cstdio>
  42. #include <cstring>
  43. #include <string>
  44. #include <utility>
  45. #include <iosfwd>
  46. #include <ostream>
  47. #include <numeric>
  48. #include <map>
  49. #include <iomanip>
  50. #include <algorithm>
  51. #include <vector>
  52. #include "SharedHandle.h"
  53. #include "a2time.h"
  54. #include "a2netcompat.h"
  55. #include "a2functional.h"
  56. #include "SegList.h"
  57. #include "a2iterator.h"
  58. #include "message.h"
  59. #include "DlAbortEx.h"
  60. #include "fmt.h"
  61. namespace aria2 {
  62. class Randomizer;
  63. class BitfieldMan;
  64. class BinaryStream;
  65. class FileEntry;
  66. class RequestGroup;
  67. class Option;
  68. struct Pref;
  69. #define STRTOLL(X) strtoll(X, reinterpret_cast<char**>(0), 10)
  70. #define STRTOULL(X) strtoull(X, reinterpret_cast<char**>(0), 10)
  71. #define START_INDEX(OFFSET, PIECE_LENGTH) ((OFFSET)/(PIECE_LENGTH))
  72. #define END_INDEX(OFFSET, LENGTH, PIECE_LENGTH) (((OFFSET)+(LENGTH)-1)/(PIECE_LENGTH))
  73. #define DIV_FLOOR(X,Y) ((X)/(Y)+((X)%(Y)? 1:0))
  74. #ifdef WORDS_BIGENDIAN
  75. inline uint64_t ntoh64(uint64_t x) { return x; }
  76. inline uint64_t hton64(uint64_t x) { return x; }
  77. #else // !WORDS_BIGENDIAN
  78. inline uint64_t byteswap64(uint64_t x) {
  79. uint64_t v1 = ntohl(x & 0x00000000ffffffffllu);
  80. uint64_t v2 = ntohl(x >> 32);
  81. return (v1 << 32)|v2;
  82. }
  83. inline uint64_t ntoh64(uint64_t x) { return byteswap64(x); }
  84. inline uint64_t hton64(uint64_t x) { return byteswap64(x); }
  85. #endif // !WORDS_BIGENDIAN
  86. #ifdef __MINGW32__
  87. std::wstring utf8ToWChar(const std::string& src);
  88. std::wstring utf8ToWChar(const char* str);
  89. std::string utf8ToNative(const std::string& src);
  90. std::string wCharToUtf8(const std::wstring& wsrc);
  91. std::string nativeToUtf8(const std::string& src);
  92. #else // !__MINGW32__
  93. # define utf8ToWChar(src) src
  94. # define utf8ToNative(src) src
  95. #endif // !__MINGW32__
  96. namespace util {
  97. extern const std::string DEFAULT_STRIP_CHARSET;
  98. template<typename InputIterator>
  99. std::pair<InputIterator, InputIterator> stripIter
  100. (InputIterator first, InputIterator last,
  101. const std::string& chars = DEFAULT_STRIP_CHARSET)
  102. {
  103. for(; first != last &&
  104. std::find(chars.begin(), chars.end(), *first) != chars.end(); ++first);
  105. if(first == last) {
  106. return std::make_pair(first, last);
  107. }
  108. InputIterator left = last-1;
  109. for(; left != first &&
  110. std::find(chars.begin(), chars.end(), *left) != chars.end(); --left);
  111. return std::make_pair(first, left+1);
  112. }
  113. template<typename InputIterator>
  114. InputIterator lstripIter
  115. (InputIterator first, InputIterator last, char ch)
  116. {
  117. for(; first != last && *first == ch; ++first);
  118. return first;
  119. }
  120. template<typename InputIterator, typename InputIterator2>
  121. InputIterator lstripIter
  122. (InputIterator first, InputIterator last,
  123. InputIterator2 cfirst, InputIterator2 clast)
  124. {
  125. for(; first != last && std::find(cfirst, clast, *first) != clast; ++first);
  126. return first;
  127. }
  128. template<typename InputIterator>
  129. InputIterator lstripIter
  130. (InputIterator first, InputIterator last)
  131. {
  132. return lstripIter(first, last,
  133. DEFAULT_STRIP_CHARSET.begin(), DEFAULT_STRIP_CHARSET.end());
  134. }
  135. std::string strip
  136. (const std::string& str, const std::string& chars = DEFAULT_STRIP_CHARSET);
  137. template<typename InputIterator>
  138. void divide
  139. (std::pair<std::pair<InputIterator, InputIterator>,
  140. std::pair<InputIterator, InputIterator> >& hp,
  141. InputIterator first,
  142. InputIterator last,
  143. char delim)
  144. {
  145. InputIterator dpos = std::find(first, last, delim);
  146. if(dpos == last) {
  147. hp.first = stripIter(first, last);
  148. hp.second.first = hp.second.second;
  149. } else {
  150. hp.first = stripIter(first, dpos);
  151. hp.second = stripIter(dpos+1, last);
  152. }
  153. }
  154. template<typename T>
  155. std::string uitos(T value, bool comma = false)
  156. {
  157. std::string str;
  158. if(value == 0) {
  159. str = "0";
  160. return str;
  161. }
  162. int count = 0;
  163. while(value) {
  164. ++count;
  165. char digit = value%10+'0';
  166. if(comma && count > 3 && count%3 == 1) {
  167. str += ",";
  168. }
  169. str += digit;
  170. value /= 10;
  171. }
  172. std::reverse(str.begin(), str.end());
  173. return str;
  174. }
  175. std::string itos(int64_t value, bool comma = false);
  176. /**
  177. * Computes difference in micro-seconds between tv1 and tv2,
  178. * assuming tv1 is newer than tv2.
  179. * If tv1 is older than tv2, then this method returns 0.
  180. */
  181. int64_t difftv(struct timeval tv1, struct timeval tv2);
  182. int32_t difftvsec(struct timeval tv1, struct timeval tv2);
  183. std::string replace(const std::string& target, const std::string& oldstr, const std::string& newstr);
  184. std::string percentEncode(const unsigned char* target, size_t len);
  185. std::string percentEncode(const std::string& target);
  186. std::string percentEncodeMini(const std::string& target);
  187. bool inRFC3986ReservedChars(const char c);
  188. bool inRFC3986UnreservedChars(const char c);
  189. bool isUtf8(const std::string& str);
  190. std::string percentDecode
  191. (std::string::const_iterator first, std::string::const_iterator last);
  192. std::string torrentPercentEncode(const unsigned char* target, size_t len);
  193. std::string torrentPercentEncode(const std::string& target);
  194. std::string toHex(const unsigned char* src, size_t len);
  195. std::string toHex(const char* src, size_t len);
  196. std::string toHex(const std::string& src);
  197. unsigned int hexCharToUInt(unsigned char ch);
  198. // Converts hexadecimal ascii characters in [first, last) into packed
  199. // binary form and return the result. If characters in given range is
  200. // not well formed, then empty string is returned.
  201. template<typename InputIterator>
  202. std::string fromHex(InputIterator first, InputIterator last)
  203. {
  204. std::string dest;
  205. size_t len = last-first;
  206. if(len%2) {
  207. return dest;
  208. }
  209. for(; first != last; first += 2) {
  210. unsigned char high = hexCharToUInt(*first);
  211. unsigned char low = hexCharToUInt(*(first+1));
  212. if(high == 255 || low == 255) {
  213. dest.clear();
  214. return dest;
  215. }
  216. dest += (high*16+low);
  217. }
  218. return dest;
  219. }
  220. FILE* openFile(const std::string& filename, const std::string& mode);
  221. bool isPowerOf(int num, int base);
  222. std::string secfmt(time_t sec);
  223. bool parseIntNoThrow(int32_t& res, const std::string& s, int base = 10);
  224. int32_t parseInt(const std::string& s, int base = 10);
  225. // Valid range: [0, INT32_MAX]
  226. bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
  227. uint32_t parseUInt(const std::string& s, int base = 10);
  228. bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
  229. int64_t parseLLInt(const std::string& s, int base = 10);
  230. void parseIntSegments(SegList<int>& sgl, const std::string& src);
  231. // Parses string which specifies the range of piece index for higher
  232. // priority and appends those indexes into result. The input string
  233. // src can contain 2 keywords "head" and "tail". To include both
  234. // keywords, they must be separated by comma. "head" means the pieces
  235. // where the first byte of each file sits. "tail" means the pieces
  236. // where the last byte of each file sits. These keywords can take one
  237. // parameter, SIZE. For example, if "head=SIZE" is specified, pieces
  238. // in the range of first SIZE bytes of each file get higher
  239. // priority. SIZE can include K or M(1K = 1024, 1M = 1024K).
  240. // If SIZE is omitted, SIZE=defaultSize is used.
  241. //
  242. // sample: head=512K,tail=512K
  243. void parsePrioritizePieceRange
  244. (std::vector<size_t>& result, const std::string& src,
  245. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  246. size_t pieceLength,
  247. off_t defaultSize = 1048576 /* 1MiB */);
  248. // Converts ISO/IEC 8859-1 string src to utf-8.
  249. std::string iso8859ToUtf8(const std::string& src);
  250. std::string getContentDispositionFilename(const std::string& header);
  251. std::string randomAlpha(size_t length,
  252. const SharedHandle<Randomizer>& randomizer);
  253. std::string toUpper(const std::string& src);
  254. std::string toLower(const std::string& src);
  255. void uppercase(std::string& s);
  256. void lowercase(std::string& s);
  257. bool isNumericHost(const std::string& name);
  258. void setGlobalSignalHandler(int signal, void (*handler)(int), int flags);
  259. std::string getHomeDir();
  260. int64_t getRealSize(const std::string& sizeWithUnit);
  261. std::string abbrevSize(int64_t size);
  262. template<typename InputIterator, typename Output>
  263. void toStream
  264. (InputIterator first, InputIterator last, Output& os)
  265. {
  266. os.printf("%s\n"
  267. "idx|path/length\n"
  268. "===+===========================================================================\n", _("Files:"));
  269. int32_t count = 1;
  270. for(; first != last; ++first, ++count) {
  271. os.printf("%3d|%s\n"
  272. " |%sB (%s)\n"
  273. "---+---------------------------------------------------------------------------\n",
  274. count,
  275. (*first)->getPath().c_str(),
  276. util::abbrevSize((*first)->getLength()).c_str(),
  277. util::uitos((*first)->getLength(), true).c_str());
  278. }
  279. }
  280. void sleep(long seconds);
  281. void usleep(long microseconds);
  282. template<typename InputIterator>
  283. bool isNumber(InputIterator first, InputIterator last)
  284. {
  285. if(first == last) {
  286. return false;
  287. }
  288. for(; first != last; ++first) {
  289. if('0' > *first || *first > '9') {
  290. return false;
  291. }
  292. }
  293. return true;
  294. }
  295. bool isAlpha(const char c);
  296. bool isDigit(const char c);
  297. bool isHexDigit(const char c);
  298. bool isHexDigit(const std::string& s);
  299. template<typename InputIterator>
  300. bool isLowercase(InputIterator first, InputIterator last)
  301. {
  302. if(first == last) {
  303. return false;
  304. }
  305. for(; first != last; ++first) {
  306. if('a' > *first || *first > 'z') {
  307. return false;
  308. }
  309. }
  310. return true;
  311. }
  312. template<typename InputIterator>
  313. bool isUppercase(InputIterator first, InputIterator last)
  314. {
  315. if(first == last) {
  316. return false;
  317. }
  318. for(; first != last; ++first) {
  319. if('A' > *first || *first > 'Z') {
  320. return false;
  321. }
  322. }
  323. return true;
  324. }
  325. /**
  326. * Converts alphabets to unsigned int, assuming alphabets as a base 26
  327. * integer and 'a' or 'A' is 0.
  328. * This function assumes alphabets includes only a-z.
  329. * Upper case are allowed but all letters must be upper case.
  330. * If overflow occurs, returns 0.
  331. */
  332. unsigned int alphaToNum(const std::string& alphabets);
  333. void mkdirs(const std::string& dirpath);
  334. void convertBitfield(BitfieldMan* dest, const BitfieldMan* src);
  335. // binaryStream has to be opened before calling this function.
  336. std::string toString(const SharedHandle<BinaryStream>& binaryStream);
  337. #ifdef HAVE_POSIX_MEMALIGN
  338. void* allocateAlignedMemory(size_t alignment, size_t size);
  339. #endif // HAVE_POSIX_MEMALIGN
  340. std::pair<std::string, uint16_t>
  341. getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len);
  342. std::string htmlEscape(const std::string& src);
  343. // Joins path element specified in [first, last). If ".." is found,
  344. // it eats the previous element if it exists. If "." is found, it
  345. // is just ignored and it is not appeared in the result.
  346. template<typename InputIterator>
  347. std::string joinPath(InputIterator first, InputIterator last)
  348. {
  349. std::vector<std::string> elements;
  350. for(;first != last; ++first) {
  351. if(*first == "..") {
  352. if(!elements.empty()) {
  353. elements.pop_back();
  354. }
  355. } else if(*first == ".") {
  356. // do nothing
  357. } else {
  358. elements.push_back(*first);
  359. }
  360. }
  361. return strjoin(elements.begin(), elements.end(), "/");
  362. }
  363. // Parses INDEX=PATH format string. INDEX must be an unsigned
  364. // integer.
  365. std::pair<size_t, std::string>
  366. parseIndexPath(const std::string& line);
  367. std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i);
  368. /**
  369. * Take a string [first, last) which is a delimited list and add its
  370. * elements into result as iterator pair. result is stored in out.
  371. */
  372. template<typename InputIterator, typename OutputIterator>
  373. OutputIterator splitIter
  374. (InputIterator first,
  375. InputIterator last,
  376. OutputIterator out,
  377. char delim,
  378. bool doStrip = false,
  379. bool allowEmpty = false)
  380. {
  381. for(InputIterator i = first; i != last;) {
  382. InputIterator j = std::find(i, last, delim);
  383. std::pair<InputIterator, InputIterator> p(i, j);
  384. if(doStrip) {
  385. p = stripIter(i, j);
  386. }
  387. if(allowEmpty || p.first != p.second) {
  388. *out++ = p;
  389. }
  390. i = j;
  391. if(j != last) {
  392. ++i;
  393. }
  394. }
  395. if(allowEmpty &&
  396. (first == last || *(last-1) == delim)) {
  397. *out++ = std::make_pair(last, last);
  398. }
  399. return out;
  400. }
  401. template<typename InputIterator, typename OutputIterator>
  402. OutputIterator splitIterM
  403. (InputIterator first,
  404. InputIterator last,
  405. OutputIterator out,
  406. const char* delims,
  407. bool doStrip = false,
  408. bool allowEmpty = false)
  409. {
  410. size_t numDelims = strlen(delims);
  411. const char* dlast = delims+numDelims;
  412. for(InputIterator i = first; i != last;) {
  413. InputIterator j = i;
  414. for(; j != last && std::find(delims, dlast, *j) == dlast; ++j);
  415. std::pair<InputIterator, InputIterator> p(i, j);
  416. if(doStrip) {
  417. p = stripIter(i, j);
  418. }
  419. if(allowEmpty || p.first != p.second) {
  420. *out++ = p;
  421. }
  422. i = j;
  423. if(j != last) {
  424. ++i;
  425. }
  426. }
  427. if(allowEmpty &&
  428. (first == last ||
  429. std::find(delims, dlast, *(last-1)) != dlast)) {
  430. *out++ = std::make_pair(last, last);
  431. }
  432. return out;
  433. }
  434. template<typename InputIterator, typename OutputIterator>
  435. OutputIterator split
  436. (InputIterator first,
  437. InputIterator last,
  438. OutputIterator out,
  439. char delim,
  440. bool doStrip = false,
  441. bool allowEmpty = false)
  442. {
  443. for(InputIterator i = first; i != last;) {
  444. InputIterator j = std::find(i, last, delim);
  445. std::pair<InputIterator, InputIterator> p(i, j);
  446. if(doStrip) {
  447. p = stripIter(i, j);
  448. }
  449. if(allowEmpty || p.first != p.second) {
  450. *out++ = std::string(p.first, p.second);
  451. }
  452. i = j;
  453. if(j != last) {
  454. ++i;
  455. }
  456. }
  457. if(allowEmpty &&
  458. (first == last || *(last-1) == delim)) {
  459. *out++ = std::string(last, last);
  460. }
  461. return out;
  462. }
  463. template<typename InputIterator1, typename InputIterator2>
  464. bool streq
  465. (InputIterator1 first1,
  466. InputIterator1 last1,
  467. InputIterator2 first2,
  468. InputIterator2 last2)
  469. {
  470. if(last1-first1 != last2-first2) {
  471. return false;
  472. }
  473. return std::equal(first1, last1, first2);
  474. }
  475. template<typename InputIterator>
  476. bool streq(InputIterator first, InputIterator last, const char* b)
  477. {
  478. for(; first != last && *b != '\0'; ++first, ++b) {
  479. if(*first != *b) {
  480. return false;
  481. }
  482. }
  483. return first == last && *b == '\0';
  484. }
  485. struct CaseCmp {
  486. bool operator()(char lhs, char rhs) const
  487. {
  488. if('A' <= lhs && lhs <= 'Z') {
  489. lhs += 'a'-'A';
  490. }
  491. if('A' <= rhs && rhs <= 'Z') {
  492. rhs += 'a'-'A';
  493. }
  494. return lhs == rhs;
  495. }
  496. };
  497. template<typename InputIterator1, typename InputIterator2>
  498. InputIterator1 strifind
  499. (InputIterator1 first1,
  500. InputIterator1 last1,
  501. InputIterator2 first2,
  502. InputIterator2 last2)
  503. {
  504. return std::search(first1, last1, first2, last2, CaseCmp());
  505. }
  506. template<typename InputIterator1, typename InputIterator2>
  507. bool strieq
  508. (InputIterator1 first1,
  509. InputIterator1 last1,
  510. InputIterator2 first2,
  511. InputIterator2 last2)
  512. {
  513. if(last1-first1 != last2-first2) {
  514. return false;
  515. }
  516. return std::equal(first1, last1, first2, CaseCmp());
  517. }
  518. template<typename InputIterator>
  519. bool strieq(InputIterator first, InputIterator last, const char* b)
  520. {
  521. CaseCmp cmp;
  522. for(; first != last && *b != '\0'; ++first, ++b) {
  523. if(!cmp(*first, *b)) {
  524. return false;
  525. }
  526. }
  527. return first == last && *b == '\0';
  528. }
  529. template<typename InputIterator1, typename InputIterator2>
  530. bool startsWith
  531. (InputIterator1 first1,
  532. InputIterator1 last1,
  533. InputIterator2 first2,
  534. InputIterator2 last2)
  535. {
  536. if(last1-first1 < last2-first2) {
  537. return false;
  538. }
  539. return std::equal(first2, last2, first1);
  540. }
  541. template<typename InputIterator>
  542. bool startsWith(InputIterator first, InputIterator last, const char* b)
  543. {
  544. for(; first != last && *b != '\0'; ++first, ++b) {
  545. if(*first != *b) {
  546. return false;
  547. }
  548. }
  549. return *b == '\0';
  550. }
  551. bool startsWith(const std::string& a, const char* b);
  552. bool startsWith(const std::string& a, const std::string& b);
  553. template<typename InputIterator1, typename InputIterator2>
  554. bool istartsWith
  555. (InputIterator1 first1,
  556. InputIterator1 last1,
  557. InputIterator2 first2,
  558. InputIterator2 last2)
  559. {
  560. if(last1-first1 < last2-first2) {
  561. return false;
  562. }
  563. return std::equal(first2, last2, first1, CaseCmp());
  564. }
  565. template<typename InputIterator>
  566. bool istartsWith(InputIterator first, InputIterator last, const char* b)
  567. {
  568. CaseCmp cmp;
  569. for(; first != last && *b != '\0'; ++first, ++b) {
  570. if(!cmp(*first, *b)) {
  571. return false;
  572. }
  573. }
  574. return *b == '\0';
  575. }
  576. bool istartsWith(const std::string& a, const char* b);
  577. template<typename InputIterator1, typename InputIterator2>
  578. bool endsWith
  579. (InputIterator1 first1,
  580. InputIterator1 last1,
  581. InputIterator2 first2,
  582. InputIterator2 last2)
  583. {
  584. if(last1-first1 < last2-first2) {
  585. return false;
  586. }
  587. return std::equal(first2, last2, last1-(last2-first2));
  588. }
  589. bool endsWith(const std::string& a, const char* b);
  590. bool endsWith(const std::string& a, const std::string& b);
  591. template<typename InputIterator1, typename InputIterator2>
  592. bool iendsWith
  593. (InputIterator1 first1,
  594. InputIterator1 last1,
  595. InputIterator2 first2,
  596. InputIterator2 last2)
  597. {
  598. if(last1-first1 < last2-first2) {
  599. return false;
  600. }
  601. return std::equal(first2, last2, last1-(last2-first2), CaseCmp());
  602. }
  603. bool iendsWith(const std::string& a, const char* b);
  604. bool iendsWith(const std::string& a, const std::string& b);
  605. void generateRandomData(unsigned char* data, size_t length);
  606. // Saves data to file whose name is filename. If overwrite is true,
  607. // existing file is overwritten. Otherwise, this function doesn't do
  608. // nothing. If data is saved successfully, return true. Otherwise
  609. // returns false.
  610. bool saveAs
  611. (const std::string& filename, const std::string& data, bool overwrite=false);
  612. // Prepend dir to relPath. If dir is empty, it prepends "." to relPath.
  613. //
  614. // dir = "/dir", relPath = "foo" => "/dir/foo"
  615. // dir = "", relPath = "foo" => "./foo"
  616. // dir = "/", relPath = "foo" => "/foo"
  617. std::string applyDir(const std::string& dir, const std::string& relPath);
  618. // In HTTP/FTP, file name is file component in URI. In HTTP, filename
  619. // may be a value of Content-Disposition header. They are likely
  620. // percent encoded. If they contains, for example, %2F, when decoded,
  621. // basename contains dir component. This should be avoided. This
  622. // function is created to fix these issues. This function expects src
  623. // should be non-percent-encoded basename. Currently, this function
  624. // replaces '/' with '_' and result string is passed to escapePath()
  625. // function and its result is returned.
  626. std::string fixTaintedBasename(const std::string& src);
  627. // Generates 20 bytes random key and store it to the address pointed
  628. // by key. Caller must allocate at least 20 bytes for generated key.
  629. void generateRandomKey(unsigned char* key);
  630. // Returns true is given numeric ipv4addr is in Private Address Space.
  631. bool inPrivateAddress(const std::string& ipv4addr);
  632. // Returns true if s contains directory traversal path component such
  633. // as '..' or it contains null or control character which may fool
  634. // user.
  635. bool detectDirTraversal(const std::string& s);
  636. // Replaces null(0x00) and control character(0x01-0x1f) with '_'. If
  637. // __MINGW32__ is defined, following characters are also replaced with
  638. // '_': '"', '*', ':', '<', '>', '?', '\', '|'.
  639. std::string escapePath(const std::string& s);
  640. // Returns true if ip1 and ip2 are in the same CIDR block. ip1 and
  641. // ip2 must be numeric IPv4 or IPv6 address. If either of them or both
  642. // of them is not valid numeric address, then returns false. bits is
  643. // prefix bits. If bits is out of range, then bits is set to the
  644. // length of binary representation of the address*8.
  645. bool inSameCidrBlock
  646. (const std::string& ip1, const std::string& ip2, size_t bits);
  647. void removeMetalinkContentTypes(const SharedHandle<RequestGroup>& group);
  648. void removeMetalinkContentTypes(RequestGroup* group);
  649. // No throw
  650. void executeHookByOptName
  651. (const SharedHandle<RequestGroup>& group, const Option* option,
  652. const Pref* pref);
  653. // No throw
  654. void executeHookByOptName
  655. (const RequestGroup* group, const Option* option, const Pref* pref);
  656. std::string createSafePath(const std::string& dir, const std::string& filename);
  657. std::string encodeNonUtf8(const std::string& s);
  658. // Create string safely. If str is NULL, returns empty string.
  659. // Otherwise, returns std::string(str).
  660. std::string makeString(const char* str);
  661. // This function is basically the same with strerror(errNum) but when
  662. // strerror returns NULL, this function returns empty string.
  663. std::string safeStrerror(int errNum);
  664. // Parses sequence [first, last) and find name=value pair delimited by
  665. // delim character. If name(and optionally value) is found, returns
  666. // pair of iterator which can use as first parameter of next call of
  667. // this function, and true. If no name is found, returns the pair of
  668. // last and false.
  669. template<typename Iterator>
  670. std::pair<Iterator, bool>
  671. nextParam
  672. (std::string& name,
  673. std::string& value,
  674. Iterator first,
  675. Iterator last,
  676. char delim)
  677. {
  678. Iterator end = last;
  679. while(first != end) {
  680. last = first;
  681. Iterator parmnameFirst = first;
  682. Iterator parmnameLast = first;
  683. bool eqFound = false;
  684. for(; last != end; ++last) {
  685. if(*last == delim) {
  686. break;
  687. } else if(!eqFound && *last == '=') {
  688. eqFound = true;
  689. parmnameFirst = first;
  690. parmnameLast = last;
  691. }
  692. }
  693. std::pair<std::string::const_iterator,
  694. std::string::const_iterator> namep;
  695. std::pair<std::string::const_iterator,
  696. std::string::const_iterator> valuep;
  697. if(parmnameFirst == parmnameLast) {
  698. if(!eqFound) {
  699. parmnameFirst = first;
  700. parmnameLast = last;
  701. namep = stripIter(parmnameFirst, parmnameLast);
  702. }
  703. } else {
  704. first = parmnameLast+1;
  705. namep = stripIter(parmnameFirst, parmnameLast);
  706. valuep = stripIter(first, last);
  707. }
  708. if(last != end) {
  709. ++last;
  710. }
  711. if(namep.first != namep.second) {
  712. name.assign(namep.first, namep.second);
  713. value.assign(valuep.first, valuep.second);
  714. return std::make_pair(last, true);
  715. }
  716. first = last;
  717. }
  718. return std::make_pair(end, false);
  719. }
  720. template<typename T>
  721. SharedHandle<T> copy(const SharedHandle<T>& a)
  722. {
  723. return SharedHandle<T>(new T(*a.get()));
  724. }
  725. // This is a bit different from cookie_helper::domainMatch(). If
  726. // hostname is numeric host, then returns true if domain == hostname.
  727. // That is if domain starts with ".", then returns true if domain is a
  728. // suffix of hostname. If domain does not start with ".", then
  729. // returns true if domain == hostname. Otherwise returns true.
  730. // For example,
  731. //
  732. // * noProxyDomainMatch("aria2.sf.net", ".sf.net") returns true.
  733. // * noProxyDomainMatch("sf.net", ".sf.net") returns false.
  734. bool noProxyDomainMatch(const std::string& hostname, const std::string& domain);
  735. // Checks hostname matches pattern as described in RFC 2818.
  736. //
  737. // Quoted from RFC 2818 section 3.1. Server Identity:
  738. //
  739. // Matching is performed using the matching rules specified by
  740. // [RFC2459]. If more than one identity of a given type is present in
  741. // the certificate (e.g., more than one dNSName name, a match in any
  742. // one of the set is considered acceptable.) Names may contain the
  743. // wildcard character * which is considered to match any single domain
  744. // name component or component fragment. E.g., *.a.com matches
  745. // foo.a.com but not bar.foo.a.com. f*.com matches foo.com but not
  746. // bar.com.
  747. //
  748. // If pattern contains multiple '*', this function considers left most
  749. // '*' as a wildcard character and other '*'s are considered just
  750. // character literals.
  751. bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname);
  752. } // namespace util
  753. } // namespace aria2
  754. #endif // D_UTIL_H