mirror of
https://github.com/xroche/httrack.git
synced 2026-07-18 14:50:32 +03:00
Compare commits
1 Commits
fix-630-pa
...
release-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd342a4fcf |
@@ -2368,28 +2368,30 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
|
||||
opt->errlog = stderr;
|
||||
} else if (httrack_logmode >= 2) {
|
||||
// deux fichiers log
|
||||
// path_log holds UTF-8 bytes (argv is UTF-8): the ANSI file calls would
|
||||
// read them as the codepage and drop the logs into a mangled twin (#630).
|
||||
structcheck_utf8(StringBuff(opt->path_log));
|
||||
if (fexist_utf8(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-log.txt")))
|
||||
UNLINK(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-log.txt"));
|
||||
if (fexist_utf8(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-err.txt")))
|
||||
UNLINK(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-err.txt"));
|
||||
structcheck(StringBuff(opt->path_log));
|
||||
if (fexist
|
||||
(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-log.txt")))
|
||||
remove(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-log.txt"));
|
||||
if (fexist
|
||||
(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-err.txt")))
|
||||
remove(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-err.txt"));
|
||||
|
||||
/* Check FS directory structure created */
|
||||
structcheck_utf8(StringBuff(opt->path_log));
|
||||
structcheck(StringBuff(opt->path_log));
|
||||
|
||||
opt->log = FOPEN(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-log.txt"),
|
||||
"w");
|
||||
opt->log =
|
||||
fopen(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-log.txt"),
|
||||
"w");
|
||||
if (httrack_logmode == 2)
|
||||
opt->errlog = FOPEN(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-err.txt"),
|
||||
"w");
|
||||
opt->errlog =
|
||||
fopen(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log), "hts-err.txt"),
|
||||
"w");
|
||||
else
|
||||
opt->errlog = opt->log;
|
||||
if (opt->log == NULL) {
|
||||
|
||||
@@ -1532,30 +1532,8 @@ int url_savename(lien_adrfilsave *const afs,
|
||||
// last segment
|
||||
wsave[j++] = '/';
|
||||
#define MAX_UTF8_SEQ_CHARS 4
|
||||
{
|
||||
// #623: the ".delayed" placeholder marker sits at the tail; cutting
|
||||
// through it drops IS_DELAYED_EXT, so the file is never renamed to its
|
||||
// final name. Reserve the trailing ".<id>.delayed" across the cut.
|
||||
size_t markStart = wsaveLen;
|
||||
if (IS_DELAYED_EXT(afs->save)) {
|
||||
const size_t extDot = wsaveLen - strlen("." DELAYED_EXT);
|
||||
size_t p = extDot; /* walk back over a dot-separated ".<hexid>" tag */
|
||||
|
||||
while (p > lastSeg && ((wsave[p - 1] >= '0' && wsave[p - 1] <= '9') ||
|
||||
(wsave[p - 1] >= 'a' && wsave[p - 1] <= 'f')))
|
||||
p--;
|
||||
// keep the tag only if truly ".<hexid>.delayed"; else the bare marker
|
||||
// (a wholly-hex base, e.g. a hashed #133 name, must not be absorbed)
|
||||
markStart = (p > lastSeg && p < extDot && wsave[p - 1] == '.')
|
||||
? p - 1
|
||||
: extDot;
|
||||
}
|
||||
// head, bounded so the marker still fits, then the marker itself
|
||||
for (i = lastSeg; i < markStart && j + (wsaveLen - markStart) < maxLen;
|
||||
i++)
|
||||
wsave[j++] = wsave[i];
|
||||
for (i = markStart; i < wsaveLen && j < maxLen; i++)
|
||||
wsave[j++] = wsave[i];
|
||||
for(i = lastSeg; wsave[i] != '\0' && j < maxLen; i++) {
|
||||
wsave[j++] = wsave[i];
|
||||
}
|
||||
// terminating \0
|
||||
wsave[j++] = '\0';
|
||||
|
||||
@@ -315,43 +315,6 @@ static void escape_url_parens(char *const s, const size_t size) {
|
||||
strlcpybuff(s, buff, size);
|
||||
}
|
||||
|
||||
/* Strip a default ":80" from lien's authority in place. Any spelling that
|
||||
range-parses to 80 (":80", ":080") is dropped by its matched length, not a
|
||||
hardcoded 3 chars; a value that merely wraps to 80 as an int (#614) stays. */
|
||||
void hts_strip_default_port(char *lien, size_t size) {
|
||||
char *a;
|
||||
|
||||
if (!link_has_authority(lien))
|
||||
return;
|
||||
a = strstr(lien, "//"); // "//" authority
|
||||
if (a)
|
||||
a += 2;
|
||||
else
|
||||
a = lien;
|
||||
a = jump_toport(a);
|
||||
if (a) { // port present
|
||||
char *b = a + 1;
|
||||
char saved;
|
||||
int port;
|
||||
hts_boolean is_default;
|
||||
|
||||
while (isdigit((unsigned char) *b))
|
||||
b++;
|
||||
saved = *b;
|
||||
*b = '\0';
|
||||
is_default = hts_parse_url_port(a + 1, &port) && port == 80;
|
||||
*b = saved;
|
||||
if (is_default) { // default port, strip it
|
||||
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
||||
|
||||
tempo[0] = '\0';
|
||||
strncatbuff(tempo, lien, a - lien);
|
||||
strcatbuff(tempo, b); // skip the whole matched :port
|
||||
strlcpybuff(lien, tempo, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Main parser */
|
||||
int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
@@ -2175,8 +2138,38 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
||||
} while((b != a) && (b));
|
||||
}
|
||||
}
|
||||
// drop a default :80 port from the authority
|
||||
hts_strip_default_port(lien, sizeof(lien));
|
||||
// éliminer les éventuels :80 (port par défaut!)
|
||||
if (link_has_authority(lien)) {
|
||||
char *a;
|
||||
|
||||
a = strstr(lien, "//"); // "//" authority
|
||||
if (a)
|
||||
a += 2;
|
||||
else
|
||||
a = lien;
|
||||
a = jump_toport(a);
|
||||
if (a) { // port
|
||||
int port = 0;
|
||||
int defport = 80;
|
||||
char *b = a + 1;
|
||||
|
||||
#if HTS_USEOPENSSL
|
||||
#endif
|
||||
while(isdigit((unsigned char) *b)) {
|
||||
port *= 10;
|
||||
port += (int) (*b - '0');
|
||||
b++;
|
||||
}
|
||||
if (port == defport) { // port 80, default - c'est débile
|
||||
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
||||
|
||||
tempo[0] = '\0';
|
||||
strncatbuff(tempo, lien, a - lien);
|
||||
strcatbuff(tempo, a + 3); // sauter :80
|
||||
strcpybuff(lien, tempo);
|
||||
}
|
||||
}
|
||||
}
|
||||
// filtrer les parazites (mailto & cie)
|
||||
/*
|
||||
if (strfield(lien,"mailto:")) { // ne pas traiter
|
||||
|
||||
@@ -106,10 +106,6 @@ struct htsmoduleStructExtended {
|
||||
*/
|
||||
int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre);
|
||||
|
||||
/* Strip a default ":80" (any spelling) from an absolute link's authority, in
|
||||
place into a buffer of the given size. */
|
||||
void hts_strip_default_port(char *lien, size_t size);
|
||||
|
||||
/*
|
||||
Check for 301,302.. errors ("moved") and handle them; re-isuue requests, make
|
||||
rediretc file, handle filters considerations..
|
||||
|
||||
@@ -1589,41 +1589,6 @@ static int st_identabs(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Default-port strip (#627): a genuine 80 (any spelling) is removed by its
|
||||
matched length, host preserved; a non-80 port or one that only wraps to 80 as
|
||||
a 32-bit int (#614) is left intact. Guards the old bug where ":080"/":0080"
|
||||
dropped a hardcoded 3 chars and glued the leftover digits onto the host. */
|
||||
static int st_stripport(httrackp *opt, int argc, char **argv) {
|
||||
static const struct {
|
||||
const char *in, *out;
|
||||
} cases[] = {
|
||||
{"http://127.0.0.1:80/x", "http://127.0.0.1/x"},
|
||||
{"http://127.0.0.1:080/x", "http://127.0.0.1/x"},
|
||||
{"http://127.0.0.1:0080/x", "http://127.0.0.1/x"},
|
||||
{"http://127.0.0.1:80", "http://127.0.0.1"},
|
||||
{"http://127.0.0.1:0081/x", "http://127.0.0.1:0081/x"},
|
||||
{"http://127.0.0.1:81/x", "http://127.0.0.1:81/x"},
|
||||
{"http://127.0.0.1:8080/x", "http://127.0.0.1:8080/x"},
|
||||
{"http://127.0.0.1:4294967376/x", "http://127.0.0.1:4294967376/x"},
|
||||
{"http://127.0.0.1/x", "http://127.0.0.1/x"},
|
||||
};
|
||||
|
||||
size_t k;
|
||||
|
||||
(void) opt;
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
for (k = 0; k < sizeof(cases) / sizeof(cases[0]); k++) {
|
||||
char BIGSTK buff[HTS_URLMAXSIZE * 2];
|
||||
|
||||
strcpybuff(buff, cases[k].in);
|
||||
hts_strip_default_port(buff, sizeof(buff));
|
||||
assertf(strcmp(buff, cases[k].out) == 0);
|
||||
}
|
||||
printf("stripport self-test OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extra args are key=value: adr= cdispo= statuscode= status= strip= urlhack=
|
||||
no-www= no-slash= no-query= n83= type=, plus repeatable prior=adr|fil|sav
|
||||
registering an already-crawled link (dedup/collision paths). */
|
||||
@@ -3224,8 +3189,6 @@ static const struct selftest_entry {
|
||||
st_socks5},
|
||||
{"identabs", "", "ident_url_absolute one-byte fil[] overflow self-test",
|
||||
st_identabs},
|
||||
{"stripport", "", "default :80 port strip preserves host (#627)",
|
||||
st_stripport},
|
||||
{"header", "<raw-header-line> ...", "response header-line parsing",
|
||||
st_header},
|
||||
{"headerlong", "[header-name:]",
|
||||
|
||||
@@ -9,23 +9,21 @@ set -euo pipefail
|
||||
# drives both refusal paths and the accept path.
|
||||
|
||||
out="$(httrack -O /dev/null -#test=xfread-limit)"
|
||||
# Match with here-strings, not `echo | grep -q`: under pipefail the early grep
|
||||
# exit SIGPIPEs echo and fails the pipeline even when the pattern matched.
|
||||
for case in bylen bygrow; do
|
||||
grep -q "${case}: refused=1 adr=null msg=In-memory content too large" <<<"$out" || {
|
||||
echo "$out" | grep -q "${case}: refused=1 adr=null msg=In-memory content too large" || {
|
||||
echo "FAIL ${case}: $out"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
# Exactly INT32_MAX must be refused too (the reallocs add 1).
|
||||
grep -q 'boundary: msg=In-memory content too large' <<<"$out" || {
|
||||
echo "$out" | grep -q 'boundary: msg=In-memory content too large' || {
|
||||
echo "FAIL boundary: $out"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# The guard must NOT fire for a legitimate small size.
|
||||
if grep -q 'accept: msg=In-memory content too large' <<<"$out"; then
|
||||
if echo "$out" | grep -q 'accept: msg=In-memory content too large'; then
|
||||
echo "FAIL accept (guard fired on a legit size): $out"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Stripping a default :80 from a crawled link used to skip a hardcoded 3 chars
|
||||
# (#627): ":080"/":0080" lost only ":80" and glued the rest onto the host
|
||||
# (127.0.0.1:080/x -> 127.0.0.10/x), and a value wrapping to 80 as a 32-bit int
|
||||
# (#614) was stripped as if it were the default. All assertions live in the
|
||||
# engine self-test.
|
||||
httrack -O /dev/null -#test=stripport | grep -q "stripport self-test OK"
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# #623: url_savename enforces the 236-char path ceiling by cutting the tail of
|
||||
# the last segment, where the mandatory ".delayed" placeholder marker lives. A
|
||||
# cut marker fails IS_DELAYED_EXT, so back_delayed_rename never renames the file
|
||||
# to its final name and the download is lost. The marker must survive the cut.
|
||||
|
||||
# statuscode=302 status=-1 = a redirect answer still downloading: no type is
|
||||
# resolved, so the name gets a ".<id>.delayed" placeholder (see 01_engine-savename).
|
||||
CEIL=236
|
||||
|
||||
httrack_bin=$(cd "$(dirname "$(command -v httrack)")" && pwd)/httrack
|
||||
scratch=$(mktemp -d)
|
||||
trap 'rm -rf "$scratch"' EXIT
|
||||
cd "$scratch"
|
||||
|
||||
run() {
|
||||
"$httrack_bin" -O /dev/null -#test=savename "$@" | sed -n 's/^savename: //p'
|
||||
}
|
||||
|
||||
# A deep path ending in a long segment that overruns the ceiling.
|
||||
deep="/d1$(printf 'a%.0s' {1..40})/d2$(printf 'b%.0s' {1..40})"
|
||||
deep="$deep/d3$(printf 'c%.0s' {1..40})/d4$(printf 'd%.0s' {1..40})"
|
||||
long="$deep/$(printf 'z%.0s' {1..90})"
|
||||
|
||||
out="$(run "$long" text/html statuscode=302 status=-1)"
|
||||
case "$out" in
|
||||
*.delayed) ;;
|
||||
*)
|
||||
echo "FAIL: delayed marker cut by truncation: '$out'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
test "${#out}" -le "$CEIL" || {
|
||||
echo "FAIL: truncated name ${#out} > $CEIL ceiling: '$out'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# #133-style hashed name: an all-hex last segment must keep the marker too (the
|
||||
# ".<id>." tag is not mistaken for part of the hash).
|
||||
hexseg=$(printf 'a1b2c3d4e5f60718%.0s' {1..8})
|
||||
hexpath="/d1$(printf 'x%.0s' {1..30})/d2$(printf 'y%.0s' {1..30})/$hexseg"
|
||||
out="$(run "$hexpath" text/html statuscode=302 status=-1)"
|
||||
case "$out" in
|
||||
*.delayed) ;;
|
||||
*)
|
||||
echo "FAIL: hashed-name marker cut by truncation: '$out'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
test "${#out}" -le "$CEIL" || {
|
||||
echo "FAIL: hashed name ${#out} > $CEIL ceiling: '$out'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# A non-delayed name of the same shape still truncates, with no marker to keep.
|
||||
out="$(run "$long.html" text/html)"
|
||||
test "${#out}" -le "$CEIL" || {
|
||||
echo "FAIL: non-delayed name ${#out} > $CEIL ceiling: '$out'"
|
||||
exit 1
|
||||
}
|
||||
case "$out" in
|
||||
*.delayed)
|
||||
echo "FAIL: non-delayed name grew a .delayed marker: '$out'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "delayed-truncate OK"
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# A single non-ASCII -O sets both path_html and path_log to "café" (#630). The
|
||||
# logs (hts-log.txt/hts-err.txt) must land there, not in an ANSI-mangled twin:
|
||||
# on Windows path_log holds UTF-8 bytes the raw file calls read as the codepage.
|
||||
# The --errors/--files/--log-found audits all grep logroot=café/hts-log.txt, so
|
||||
# a log written to the twin fails them. POSIX has no twin, so this bites on the
|
||||
# Windows CI leg (like test 64). The cache twin is a separate, larger fix.
|
||||
|
||||
: "${top_srcdir:=..}"
|
||||
|
||||
bash "$top_srcdir/tests/local-crawl.sh" --outdir-intl 'café' --errors 0 --files 5 \
|
||||
--found 'simple/basic.html' \
|
||||
--log-found 'mirror complete in' \
|
||||
httrack 'BASEURL/simple/basic.html'
|
||||
@@ -146,9 +146,6 @@ TESTS = \
|
||||
62_lang-integrity.test \
|
||||
63_webhttrack-home.test \
|
||||
64_local-intl-outdir.test \
|
||||
65_port-siblings.test \
|
||||
66_engine-port80-strip.test \
|
||||
67_engine-delayed-truncate.test \
|
||||
69_local-intl-logdir.test
|
||||
65_port-siblings.test
|
||||
|
||||
CLEANFILES = check-network_sh.cache
|
||||
|
||||
@@ -48,7 +48,6 @@ key="${testdir}/server.key"
|
||||
tls=
|
||||
verbose=
|
||||
html_subdir=
|
||||
outdir_intl=
|
||||
rerun=
|
||||
rerun_args=
|
||||
rerun_dead=
|
||||
@@ -141,13 +140,6 @@ while test "$pos" -lt "$nargs"; do
|
||||
pos=$((pos + 1))
|
||||
html_subdir="${args[$pos]}"
|
||||
;;
|
||||
--outdir-intl)
|
||||
# Single non-ASCII -O "$out/NAME": path_html AND path_log are NAME, so
|
||||
# the logs (and the harness reads of them) go through the non-ASCII path
|
||||
# (#630). Distinct from --html-subdir, which keeps path_log ASCII.
|
||||
pos=$((pos + 1))
|
||||
outdir_intl="${args[$pos]}"
|
||||
;;
|
||||
--errors | --errors-content | --files)
|
||||
audit+=("${args[$pos]}" "${args[$((pos + 1))]}")
|
||||
pos=$((pos + 1))
|
||||
@@ -224,18 +216,13 @@ test -n "$ver" || die "could not run httrack"
|
||||
out="${tmpdir}/crawl"
|
||||
mkdir "$out" || die "could not create $out"
|
||||
# path_html holds the mirror + index; path_log holds hts-cache/hts-log.txt.
|
||||
# Default: both are "$out". --html-subdir moves path_html to "$out/NAME" while
|
||||
# path_log (logroot) stays "$out"; --outdir-intl moves both to "$out/NAME".
|
||||
# Default: both are "$out". With --html-subdir, path_html becomes "$out/NAME"
|
||||
# (the mirror root the audits inspect) while path_log stays "$out".
|
||||
mirrorroot="$out"
|
||||
logroot="$out"
|
||||
odir="$out"
|
||||
if test -n "$html_subdir"; then
|
||||
mirrorroot="${out}/${html_subdir}"
|
||||
odir="${mirrorroot},${out}"
|
||||
elif test -n "$outdir_intl"; then
|
||||
mirrorroot="${out}/${outdir_intl}"
|
||||
logroot="$mirrorroot"
|
||||
odir="$mirrorroot"
|
||||
fi
|
||||
# Localhost is fast; disable the rate/bandwidth safety limits but keep a
|
||||
# max-time backstop so a hang cannot wedge the suite.
|
||||
@@ -254,7 +241,7 @@ test "$crawlres" -eq 0 || ! result "httrack exited $crawlres" || {
|
||||
exit 1
|
||||
}
|
||||
result "OK"
|
||||
grep -iE "^[0-9:]*[[:space:]]Error:" "${logroot}/hts-log.txt" >&2
|
||||
grep -iE "^[0-9:]*[[:space:]]Error:" "${out}/hts-log.txt" >&2
|
||||
|
||||
# --- optional second pass: re-mirror into the same dir (cache/update path) ----
|
||||
if test -n "$rerun"; then
|
||||
@@ -273,7 +260,7 @@ if test -n "$rerun"; then
|
||||
# The update summary reports "files updated"; a fresh crawl never does. Assert
|
||||
# it so a regression that bypasses the cache (re-crawls fresh) can't pass.
|
||||
info "checking update used the cache"
|
||||
if grep -aqE "mirror complete in .*files updated" "${logroot}/hts-log.txt"; then
|
||||
if grep -aqE "mirror complete in .*files updated" "${out}/hts-log.txt"; then
|
||||
result "OK"
|
||||
else
|
||||
result "update pass did not report cache activity"
|
||||
@@ -305,7 +292,7 @@ if test -n "$rerun_dead"; then
|
||||
zip="${out}/hts-cache/new.zip"
|
||||
test -s "$zip" || die "no cache was written by the first pass"
|
||||
cp "$zip" "${tmpdir}/cache-before.zip"
|
||||
cp "${logroot}/hts-log.txt" "${tmpdir}/log-before.txt"
|
||||
cp "${out}/hts-log.txt" "${tmpdir}/log-before.txt"
|
||||
stop_server "$serverpid"
|
||||
serverpid=
|
||||
info "re-running httrack against the stopped server"
|
||||
@@ -318,7 +305,7 @@ if test -n "$rerun_dead"; then
|
||||
# The dead pass must have gone through the no-data rollback, not bailed out
|
||||
# before the mirror loop (which would leave the cache trivially untouched).
|
||||
info "checking the dead pass hit the rollback"
|
||||
if grep -aq "No data seems to have been transferred" "${logroot}/hts-log.txt"; then
|
||||
if grep -aq "No data seems to have been transferred" "${out}/hts-log.txt"; then
|
||||
result "OK"
|
||||
else
|
||||
result "rollback notice not found in hts-log.txt"
|
||||
@@ -333,7 +320,7 @@ if test -n "$rerun_dead"; then
|
||||
exit 1
|
||||
fi
|
||||
# Audits below describe the healthy crawl, not the dead pass.
|
||||
cp "${tmpdir}/log-before.txt" "${logroot}/hts-log.txt"
|
||||
cp "${tmpdir}/log-before.txt" "${out}/hts-log.txt"
|
||||
fi
|
||||
|
||||
# --- discover the single host root (127.0.0.1_<port> or 127.0.0.1) -----------
|
||||
@@ -363,19 +350,19 @@ while test "$i" -lt "${#audit[@]}"; do
|
||||
--errors)
|
||||
i=$((i + 1))
|
||||
assert_equals "checking errors" "${audit[$i]}" \
|
||||
"$(grep -iEc "^[0-9:]*[[:space:]]Error:" "${logroot}/hts-log.txt")"
|
||||
"$(grep -iEc "^[0-9:]*[[:space:]]Error:" "${out}/hts-log.txt")"
|
||||
;;
|
||||
--errors-content)
|
||||
i=$((i + 1))
|
||||
total=$(grep -icE "^[0-9:]*[[:space:]]Error:" "${logroot}/hts-log.txt")
|
||||
total=$(grep -icE "^[0-9:]*[[:space:]]Error:" "${out}/hts-log.txt")
|
||||
# transient network failures (statuscode -2..-6) flake on busy loopback;
|
||||
# the code parens are followed by " at link" or " after N retries at link"
|
||||
transient=$(grep -cE '\(-[2-6]\) (at link|after )' "${logroot}/hts-log.txt" || true)
|
||||
transient=$(grep -cE '\(-[2-6]\) (at link|after )' "${out}/hts-log.txt" || true)
|
||||
assert_equals "checking content errors" "${audit[$i]}" "$((total - transient))"
|
||||
;;
|
||||
--files)
|
||||
i=$((i + 1))
|
||||
nFiles=$(grep -E "^HTTrack Website Copier/[^ ]* mirror complete in " "${logroot}/hts-log.txt" |
|
||||
nFiles=$(grep -E "^HTTrack Website Copier/[^ ]* mirror complete in " "${out}/hts-log.txt" |
|
||||
sed -e 's/.*[[:space:]]\([^ ]*\)[[:space:]]files written.*/\1/g')
|
||||
assert_equals "checking files" "${audit[$i]}" "$nFiles"
|
||||
;;
|
||||
@@ -406,7 +393,7 @@ while test "$i" -lt "${#audit[@]}"; do
|
||||
--log-found)
|
||||
i=$((i + 1))
|
||||
info "checking log matches ${audit[$i]}"
|
||||
if grep -aqE "${audit[$i]}" "${logroot}/hts-log.txt"; then result "OK"; else
|
||||
if grep -aqE "${audit[$i]}" "${out}/hts-log.txt"; then result "OK"; else
|
||||
result "not in log"
|
||||
exit 1
|
||||
fi
|
||||
@@ -414,7 +401,7 @@ while test "$i" -lt "${#audit[@]}"; do
|
||||
--log-not-found)
|
||||
i=$((i + 1))
|
||||
info "checking log lacks ${audit[$i]}"
|
||||
if grep -aqE "${audit[$i]}" "${logroot}/hts-log.txt"; then
|
||||
if grep -aqE "${audit[$i]}" "${out}/hts-log.txt"; then
|
||||
result "present in log"
|
||||
exit 1
|
||||
else result "OK"; fi
|
||||
|
||||
Reference in New Issue
Block a user