HTTP POST requests and responses, as well as most other HTTP-level data.Hoardy-WebIf you are reading this on GitHub, it’s highly recommended you switch to the version hosted on the author’s web site instead. This pages is written in org-mode markup language and it uses a lot of its advanced features, which GitHub does not implement, so this page is almost unreadable on GitHub.
Moreover, if you already have Hoardy-Web browser extension installed, then, instead of reading this document on GitHub or from author’s web site, it is highly recommended you refer to this document by clicking the “Help” button in the extension’s own popup UI. Doing that will make this document interactive: the settings popup will be displayed on the right on this page and hovering over or clicking references to configuration options on this page will highlight them in the settings popup. It will also have a nicely formatted “Table of Contents” section there. See screenshots if you want to get an idea of how it will look.
When you open this document by clicking the Help button in Hoardy-Web browser extension’s UI, this page has two parts: this help text, and an iframe with a completely unrolled popup UI in it. The whole page will switch between single- and two-column layouts depending on available viewport width (which depends on device width and zoom level). In single-column layout the popup UI is placed after the end of the help text. In two-column layout they are placed side-by-side.
In both layouts:
links that look like this are references to other parts of the same page;
clicking these links will scroll the page to the place they point to and then highlight the relevant part;
links that look like this are references to elements of the popup UI,
in single-column layout, clicking such a link will scroll the whole page to the corresponding element in the popup UI iframe and then highlight it;
in two-column layout, clicking or hovering over such a link will scroll only the popup UI iframe around to put the corresponding referenced element into view and then highlight it;
the highlighted element will stop being highlighted if you click anywhere else on the page;
links that look like this are references to internal pages of Hoardy-Web browser extension and other pages that it comes bundled with;
clicking them will navigate your browser there, but it doing that won’t generate any requests to the Internet;
finally, links like this are references to external URLs;
clicking them will also navigate your browser there and will generate new requests to the Internet.
In cases when clicking on a link scrolls a page around or navigates to another page, pressing the “Back” button of your browser will get you back to the exact link you clicked and then highlight it, making it easy to get back to reading from the exact place you left off.
Go forth and try it by clicking one or more of the above links.
The above conventions also apply on all other internal pages of Hoardy-Web browser extension and pages that it comes bundled with, e.g., Internal State and Changelog pages.
The Hoardy-Web software project has many parts and pieces, all of which are documented separately. This page documents the Hoardy-Web web browser extension (add-on) and only ever mentions the other parts and pieces in passing.
In this document, unless specified otherwise, “Hoardy-Web” refers to the Hoardy-Web extension, not the other parts of the Hoardy-Web software project.
The main purpose of Hoardy-Web is to help you passively, in background, capture and archive HTTP requests and responses your web browser does as you browse the Web. Which is to say, the main function of Hoardy-Web is to attach to your browser’s runtime and track progress of your browser’s HTTP requests and responses, capturing their HTTP headers and bodies at appropriate times in browser’s request and response processing pipeline, dumping the results of those captures to disk as they finish loading from the network.
However, Hoardy-Web does much more than that, implementing a bunch of other features relevant for web archival and replay.
Note that in Hoardy-Web you can check the description of each status line, button, and/or configuration option by hovering over it or by pressing a ? button that comes after it. However, many of those descriptions might make little sense without you first learning the general operation principles of Hoardy-Web and some of its quirks. This document exists to explain all of those.
A reqres (REQuest+RESponse) is an internal Hoardy-Web memory object representing a captured HTTP request and response pair, including their HTTP headers and bodies/data, tabId they originate from, their URL, document URL, state, etc.
Hoardy-Web archives captured reqres by dumping them into WRR (Web Request+Response) file format, which see for a longer data-format glossary, comparisons to other related file formats, and its complete formal definition.
The rest of this document is organized as follows:
Hoardy-Web configuration and usage.Hoardy-Web, which among many others, include:
hoardy-web serve archival and replay server, which greatly simplifies many workflows that involve replays of your previously archived data.Hoardy-Web implements.Hoardy-Web implements.Hoardy-Web supports.Hoardy-Web can generate.Hoardy-Web’s issues and all relevant web browser bugs.Hoardy-Web implements hierarchical per-browser/per-window/per-tab/per-source configurations. Which is to say that most capture-related settings of Hoardy-Web can be configured for newly created windows, for new tabs created in each window, for each tab specifically, for new tabs spawned from each specific tab, for each navigation to a certain type of URL (at the moment this is limited to a pre-defined set of URL types, but the generalized machinery will be implemented soon-ish), for background requests, and for requests generated by extensions.
For example, whether Hoardy-Web will track a given HTTP request depends on the per-whatever Track new requests toggles:
this one (tab) controls whether Hoardy-Web will generate and track new reqres for requests originating from the currently active tab;
this one (chld) controls whether the above option will be set in new tabs spawned from the currently active tab (a.k.a. “children tabs”, e.g., via middle mouse click, context menu, etc);
meanwhile, this one (win) controls whether the above two options will be set in new tabs opened from the currently active window via browser’s “New Tab” browser action (e.g., via the plus sign in the tab bar, Control+T, the corresponding menu item, etc);
then, this one (glob) controls whether the above three options will be set in the first empty tab when you open a new window via browser’s “New Window” browser action (e.g., via Control+N, the corresponding menu option, etc);
meanwhile, this one (bg) controls whether Hoardy-Web will track new background requests, which are requests without an associated tab;
while this one (ext) controls tracking of requests generated by extensions, which are background requests generated by installed browser add-ons.
The same logic applies to all other toggles that have per-browser (glob), per-window (win), per-tab (tab, chld), and/or per-source (bg, ext) instances.
However, importantly, note that New root windows/tabs (glob) options only get applied to new root windows/tabs. If you drag a tab into a new window, that new window’s per-window settings will be copied from that tab’s old window per-window settings instead of them being inherited from the (glob) settings. Similarly, if you open a link in a new window, e.g. via the context menu, its per-window settings will be copied from the opener window’s per-window settings too.
In general, the elements in the popup are sorted from less specific to more specific, with more specific settings taking precedence, when they are applicable.
For example, Navigations to special URLs options, when applicable, override the corresponding per-tab settings on each navigation to a matching URL.
Finally, Hoardy-Web applies the same idea to most of its internal actions and pages. Which is to say, most of those also have per-browser (glob), per-window (win), and per-tab (tab) instances.
For example, the replay-re-navigation (glob, win, tab) and limbo-manipulation (glob, win, tab) buttons come in such triples. Similarly, Hoardy-Web’s Internal State log pages (glob, win, tab) can be narrowed to data applicable to the whole browser, a specific window, or a specific tab, which also makes Hoardy-Web’s internal actions bound to the buttons there apply to the data displayed there.
As noted above, Hoardy-Web attaches to your browser’s runtime and tracks progress of HTTP requests and their responses. Whether Hoardy-Web will track a given HTTP request depends on the Track new requests toggles (glob, win, tab, chld, bg, ext) mentioned above.
Note, however, that disabling any of these toggles does not stop tracking of already initiated requests, it only stops new requests controlled by that toggle from being tracked.
In Hoardy-Web, reqres change their internal states according to the following state diagram:
(start) -> (request sent) -> (nIO) -> (headers received) -> (nIO) --> (body received)
| | | |
| v v v
| (no_response) (incomplete) (complete)
| | | |
| \ | |
|\---> (canceled) ----\ \ | |
| \ \ \ |
|\-> (incomplete_fc) ---\ \ \ v
| >------>---------------------------->-----> (finished)
|\--> (complete_fc) ----/ / |
| / / |
\----> (snapshot) ----/ /- (collected) <--------- (picked) <--/ |
/ ^ | |
(stashToLS?) <----------------/ | v v
| \- (in_limbo) <- (stashToLS?) <- (dropped)
v | |
(queued) <---- (unarchived) <- (stashToLS?) | |
| ^ \-----> (discarded) <-----/
/-\| /---> {U} -----------/ ^
^ | | \ |
| | | \--> (forgotten) ((-> (saved))) |
| | | |
{RE} | v {{!saving && !submitting}} |
|\----> (saveAs) -> (exported) -------------------------/|
| / |
| {U} <-\ /---------/ |
| v v {{!saving}} |
|\----> (srvIO) -> (submitted) -------------------------/|
| / |
| / {{delete}} |
| {U} <-\ /-----/ /-----------------------------/|
| \ / / |
| v v / {{re-archive}} |
|\---> (saveToLS) -> (saved) -------------------> {RE} |
| |
\--------------------------------------------------------/
A new reqres proceeds through the following networking states:
start: the starting state;
request sent, (response) headers received, (response) body recived: these are the normal stages of HTTP request and response tracking via webRequest sub-API of WebExtensions API;
nIO: normal network IO performed by the browser in between HTTP request stages;
canceled: the request was canceled before it was sent because
Stop button;uBlock Origin, global work offline mode of Firefox-based browsers, or this extension’s own per-whatever work offline mode blocked it;http:// URL to an https:// URL in HTTPS-only mode;unsent would have probably been a better name for this, but all browsers call it canceled internally, so Hoardy-Web follows that convention;
no_response: the request was sent, but no response was received because
Stop button before it got a response;incomplete: the request was sent, its response headers were received, but then the loading was interrupted before all of its response body was fetched;
incomplete_fc: only on Firefox-based browsers: the browser loaded the response data of this reqres directly from its cache, but did not give it to Hoardy-Web;
this is just how Firefox handles things sometimes; usually, this only happens for images;
this is a separate state, because usually this means this URL was successfully archived before; if it was not, reload the page with Control+F5;
complete: the reqres was completed successfully;
complete_fc: the reqres was completed successfully from browser’s cache;
snapshot: this reqres was produced by taking a DOM (Document Object Model) snapshot, i.e., by capturing a raw HTML or XML of the current state of the tab/frame, not by capturing a network request;
this can be done using DOM snapshot buttons (glob, win, tab) or similar keyboard shortcuts;
finished: the terminal state of this step, no new events for this reqres will come from the browser.
An in-flight reqres (glob, win, tab) is a reqres that did not reach the finished state yet, in the logs (glob, win, tab) such reqres will be shown to be in in_flight state.
These stats are represented as sums of sizes of three sets of reqres: flying reqres, finishing up reqres, and almost done reqres. The first two count reqres that haven’t reached the finished state yet, the latter counts reqres that reached but not yet exited the finished state. See below for more detailed technical definitions.
On Firefox, nothing should ever get stuck, if something seems to be stuck in in_flight state, it’s probably still loading (or it is a bug in this extension or the browser, both which do happen, rarely).
On Chromium, limitations of the Chromium’s debugging interface mean a request can get stuck among the reqres represented by the first two numbers above. If the first number is zero, however, then the second and third numbers should also rapidly become zero, at most after two times this many seconds.
If some reqres got stuck in one of the in_flight states, you can forcefully move them out of that state by pressing one of the relevant buttons on one of the “In flight” stat lines (glob, win, tab) or similar buttons in the logs (glob, win, tab).
A finished reqres is a reqres that reached the finished state.
A final networking state is the last state a reqres had before it finished: i.e. complete, incomplete, canceled, etc.
The following definitions won’t be referenced below, so you can skip them.
(“No! Let me see!”)
A flying reqres is a reqres that is still being tracked via webRequest and/or debugger APIs.
Meaning, it’s yet to reach the headers received state in webRequest-handling code and body recived state in debugger-handling code.
A finishing up reqres is a reqres that has captured all the metadata it can and is now waiting to be finished.
Meaning, it reached the headers received state but not the body recieved state in webRequest-handling code and/or waiting to be matched up with its webRequest counterpart in debugger-handling code.
An almost done reqres is a reqres that has finished being tracked but hasn’t yet been classified and dumped to WRR.
In principle, when a reqres reaches its finished state, the primary objective of Hoardy-Web with respect to that reqres is complete, so that reqres could be dumped to disk and forgotten about.
Unfortunately for Hoardy-Web, browsers do not allow their extensions to simply write files to user’s file system, and all existing browser APIs that do allow for persistence to disk in some way all have different limitations. Also, it is quite useful to have more states after the finished state to improve the UI and allow for various conditional workflows.
Which is why Hoardy-Web has quite a lot of states after the finished state on the above diagram. To give a simple overview of those, after Hoardy-Web produces a finished reqres, it proceeds as follows:
it applies classification rules to it to decide whether that reqres should end up in picked or dropped state, as well as if it should be marked with any special flags;
then, optionally, it can put that reqres away into limbo, until you manually decide if you want that reqres to be collected or discarded, or until you let some other event move that reqres out from in_limbo state automatically;
additionally, optionally, it can stash that reqres into browser’s local storage to minimize potential data loss in various unexpected situations, like if you leave that reqres in limbo and then your browser crashes;
then, it creates a new log record for collected and discarded reqres so that you could later inspect that record even if the actual reqres in question gets discarded from memory;
then, it queues collected reqres for archival while simply discarding discarded reqres from memory;
finally, it starts processing that queue in background to actually archive said reqres using one or more supported archiving methods.
The following subsections discuss these things in detail.
When a reqres reaches the finished state of the diagram, it gets classified by the computations described below.
Sometimes networking issues and/or browser bugs prevent complete collection of (parts of) reqres data or metadata. To provide indication of this, Hoardy-Web keeps track of such things and marks such reqres with flags that indicate that the reqres in question has
a partial request body, which is denoted by partial flag in the logs (glob, win, tab);
buggy request metadata or buggy response metadata, which is denoted by buggy_request and buggy_response flags in the logs (glob, win, tab);
an incomplete response body, denoted by incomplete flag in the logs (glob, win, tab);
this flag actually gets set in the tracking stage, so its presence also forces the reqres in question to stop in incomplete or incomplete_fc final networking state discussed above;
usually, this condition is caused by networking issues like a connection getting interrupted before the whole body was fetched, but it can be caused by browser bugs, like Chromium occasionally detaching its debugger at random.
Each new finished reqres advances either to the picked or the dropped state. Which of those two states gets selected is decided based on reqres’ final networking state, its partial, buggy, and incomplete flags discussed above, and the Pick reqres for archival when they finish options:
By default, all complete and complete_fc reqres get picked, regardless of their HTTP response status codes or any other errors reported by the browser.
After all, it appears that the data of those reqres was properly fetched, so they should be archived.
Similarly, reqres with partial request body flag set and reqres with one of the buggy * metadata flags set are also picked by default.
It is recommended you keep those toggles enabled as relevant flags are usually caused by browser bugs and are thus unfixable unless you run Hoardy-Web on a customly patched browser. Also, these issues usually don’t prevent replay of captured reqres. Thus, in these cases, archiving some data is usually better than archiving none.
In contrast, picking of reqres in canceled state, reqres in no_response state, and reqres with incomplete response body flag set is disabled by default because response-incomplete reqres are usually useless and can be easily fixed by reloading a page in question.
A reqres can also be classified as problematic, which shall be discussed in a much later section since the problematic flag is completely orthogonal to the current archiving-related discussion. But, technically speaking, this happens at this point in the Hoardy-Web’s processing pipeline too.
A picked reqres (glob, win, tab) is a finished reqres that satisfied the conditions controlled by Pick reqres for archival when they finish settings on entering the finished state.
A dropped reqres (glob, win, tab) is a finished reqres that did not satisfy the conditions controlled by Pick reqres for archival when they finish settings on entering the finished state.
On exit from the finished state of the diagram, after the classification performed there, each reqres gets split into
loggable, which is a hollow reqres structure without any request or response data, anddump, which is a WRR-formatted dump of the original reqres structure.(Since those tuples can be reconstructed back into the original reqres, the following will continue to refer to them as if nothing has changed when the fact they are now being internally represented by those tuples is not relevant.)
On entering collected or discarded state, loggable metadata of each reqres is copied into the recent reqres log (glob, win, tab) and is kept there until the size of the log reaches this many elements, at which point the older elements of the log start being elided automatically.
You can also ask Hoardy-Web to forget a subset or all of those log elements manually by opening an appropriate log page (glob, win, tab), setting some filters to produce a desired subset, and then pressing the Forget all button.
However, note that reqres still marked as problematic, can’t be automatically elided or manually dropped from the logs until they get unmarked.
Thus, normally:
picked reqres proceed to the collected state, get logged, and then get queued for archival;dropped reqres proceed to being logged and discarded then from memory.However, sometimes you might want to actually look at a web page before deciding if you want to archive it or not. The naive way to do it would be to load a page with capture disabled first, look at it, and then, if you want to save it, enable it, and reload the page again with browser’s cache disabled via Control+F5 (and it has to be Control+F5, not just F5, because otherwise some URLs, on Firefox, might produce reqres in incomplete_fc state, and on Chromium, their re-fetching could be silently skipped).
Obviously, this is both annoying and will force you to fetch everything twice.
Which is why Hoardy-Web implements limbo mode. With one of the limbo mode options (glob, win, tab, chld, bg, ext) enabled, Hoardy-Web will instead capture everything as normal, but then, instead of sending the corresponding newly captured reqres to collected or discarded state, it will put them into in_limbo state where they would linger until
Closed tabs options makes that decision semi-automatically for you;A picked reqres will be put into in_limbo state when its corresponding Pick into limbo setting (glob, win, tab, chld, bg, ext) is enabled. Similarly, a dropped reqres will be put into in_limbo state when its corresponding Drop into limbo setting (glob, win, tab, chld, bg, ext) is enabled. (The latter mainly exist for debugging.)
In combination with Closed tabs options you can use the in_limbo state to implement the following workflows:
If this option is enabled and there are more than this number reqres in_limbo or the total size of all dumps in_limbo is more than this size (in MiB), Hoardy-Web will complain to remind you to collect or discard some of them.
A collected reqres (glob, win, tab) is a reqres that was (automatically or manually) sent to the collected state.
A discarded reqres (glob, win, tab) is a reqres that was (automatically or manually) sent to the discarded state.
An in-limbo reqres (glob, win, tab) is a reqres that is being held in_limbo until you manually collect or discard it.
A queued reqres (the first number on the Queued/Failed line) is a collected reqres that is still queued for archival.
In most cases you would probably want to prevent loss of successfully captured but yet unarchived reqres when
Hoardy-Web crashes or gets reloaded/updated unexpectedlybefore you collected or discarded everything from in_limbo or Hoardy-Web has successfully archived everything from its archiving queue.
This is why Hoardy-Web implements the optional stashToLS? states of the diagram and a special stashed reqres status. The stashed status is, essentially, a flag that says this reqres was temporarily backed up into browser’s local storage. This process can be controlled using the following options:
When Archive 'collected' reqres option is disabled but Stash reqres into local storage option is enabled, instead of archiving newly queued reqres, Hoardy-Web will stash their (loggable, dump) tuples into browser’s local storage.
Similarly, when both Stash reqres into local storage option and one of the relevant per-whatever Stash 'in_limbo' reqres settings (glob, win, tab, chld, bg, ext) is enabled, then all newly generated in_limbo reqres from that source will also get immediately stashed into browser’s local storage.
Moreover, the following section will discuss how Hoardy-Web will try stashing unarchived reqres into browser’s local storage too.
Note however, that even with stashing enabled Hoardy-Web will skip disk IO whenever possible: e.g., if both Archive 'collected' reqres and Submit dumps via 'HTTP' options discussed below are enabled, Hoardy-Web will first try to archive each new collected reqres straight from memory to the archiving server and only if that process fails will it attempt stashing them to local storage instead.
Meaning that
in_limbo reqres is usually completely free and so you should probably keep that option always enabled;in_limbo reqres via one of the (glob, win, tab, chld, bg, ext) options is not free, so if you almost never archive from limbo then keeping those options enabled will waste disk IO, so you might want to disable at least some of them in that case.The above also implies that, technically, stashing is not a silver bullet against data loss. To try and make it such would mean unconditional immediate stashing of all captured data, which would waste a lot of disk IO on most Hoardy-Web configurations.
When both Stash reqres into local storage option and Archive 'collected' reqres option are disabled, then, after a new reqres gets queued, Hoardy-Web will generate a new notification complaining about it, unless that option is disabled too.
You can also forcefully stash all currently queued, in_limbo, and unarchived reqres by pressing this button. It stashes everything immediately and unconditionally, ignoring all other stashing settings. When reloading the extension via the Reload button or via Auto-reload on updates option, this action will be run automatically.
If this option is enabled and some reqres fail to stash, a new notification will be generated.
A stuck queued reqres is a queued reqres that got stuck in the archival queue, e.g., because it got queued while Archive 'collected' reqres option was disabled.
A stashed reqres (glob) is a reqres that was temporarily stashed (backed-up) into browser’s local storage while it is still being kept in Hoardy-Web’s memory. I.e., the stash is a persistent on-disk backup for in-memory reqres.
A failed to stash reqres (glob) is a reqres that failed to be stashed into browser’s local storage. Note that reqres for which stashing was not even attempted are not included in this set.
You can retry stashing these reqres by pressing this button.
Also, note that this number is also a part of the sum represented by the second number on the Queued/Failed line.
After a reqres reaches the queued state of the diagram, Hoardy-Web will attempt to persist it to disk.
When Archive 'collected' reqres toggle is enabled, Hoardy-Web will pop queued reqres from the archival queue one by one and then perform one or more of the following (in order they are listed):
if Export dumps via 'saveAs' option is enabled but bundling is disabled, Hoardy-Web will simply
dump, if enabled, andWRR file via browser’s saveAs mechanism (i.e., generate a fake-Download);if both Export dumps via 'saveAs' option and bundling are enabled, Hoardy-Web will
dump, as a byte string, to a (per-bucket, see below) WRR bundle,WRR bundle gets larger than this or after a delay controlled by this and that options,
WRR bundle via browser’s saveAs mechanism (i.e., generate a fake-Download);if Submit dumps via 'HTTP' option is enabled, Hoardy-Web will submit the dump to the archiving server at Server URL setting by making an HTTP POST request with the dump as request body (which is denoted by srvIO state on the diagram);
if any of the above fails Hoardy-Web will
move the reqres into the unarchived state,
if Stash reqres into local storage option is enabled, it will try stashing the (loggable, dump) tuple into browser’s local storage (which is denoted by stashToLS? states on the diagram) and record but ignore any errors produced while doing that, and
stop processing this reqres;
if Save reqres into local storage option is enabled, Hoardy-Web will
try saving the (loggable, dump) tuple into browser’s local storage (which is denoted by saveToLS state on the diagram),
if saving fails, move the reqres into the unarchived state instead,
if saving succeeds, discard the reqres from memory,
stop processing this reqres;
if Save reqres into local storage option is disabled, Hoardy-Web will simply discard the reqres from memory, as if saving succeeded.
When stashing and/or archiving to local storage, the dump’s get compressed if this option is enabled.
You can enable more than one archival method at the same time. For a given loggable, Hoardy-Web will remember and skip previously successful archival methods if the loggable ever returns to the archival pipeline, which can happen when
Hoardy-Web successfully auto-retries it later,Hoardy-Web to retry manually via this or that button, orSometimes you might want to semi-automatically split your collected archives into separate disjoint sets. Say, for instance, you want to split out archives generated by a select tab into a separate set you plan to share with somebody else. In Hoardy-Web such sets are called buckets. WARC-based tools sometimes call these “collections” instead.
To implement this, for each reqres in the archival queue, Hoardy-Web takes a bucket value from the corresponding “Bucket” setting (glob, win, tab, chld, bg, ext).
Evaluation of bucket is done just before each archival attempt, so if the queue is not yet empty, and you disable Archive 'collected' reqres, edit some of the “Bucket” settings, and enable it again, Hoardy-Web will start using the new setting immediately.
When exporting via saveAs, bucket value will be used in the file name of the generated fake-Download WRR bundle file (.wrrb) and the dumps will be split into separate fake-Download files by said bucket. I.e., internally, the WRR bundle discussed above is actually a set of per-bucket WRR bundle’s.
When submitting to an HTTP server, Hoardy-Web will specify bucket as a query parameter (named “profile”, for historical reasons) to each HTTP POST request, which will cause the configured archiving server to put those WRR files into a directory with the same name.
When stashing or saving to local storage, Hoardy-Web will record the value of bucket into each loggable before saving data to disk. If you restart your browser, thus starting a new Hoardy-Web session, Hoardy-Web will use the old stashed/saved bucket values for all new attempted archivals of old reqres generated by previous sessions.
So, for example, if you want to share a subset of your captures, you can
saveAs WRR bundle’s with “share” in their name and/or putting them into a separate archiving server directory named “share”, depending on archival methods.As noted above, if any of the archival methods fail, the reqres in question will be moved into the unarchived state.
Submissions via HTTP of reqres that are unarchived because of networking issues will be retried automatically every 60 seconds. Archivals of reqres rejected by the archiving server or those that failed to be saved to browser’s local storage will not be retried automatically as those usually happen when there is no space left on the device you are archiving to.
Additionally, when a submission via HTTP and/or writes to browser’s local storage fail, Hoardy-Web will assume that the following archivals/writes will fail with the same error too. Usually, this paranoid behaviour is both safer and more efficient, but it can prevent some extra reqres from archiving when only a small subset of all queued reqres are being rejected by the server or fail to be written to local storage. Thus, Hoardy-Web allows you to disable this behaviour by toggling this and/or that options. Though, when no archiving bugs are apparent, you should probably keep both of them enabled.
You can retry all archiving failures by pressing one of this or that buttons. You can also use them to nudge the archiving sub-process awake if something archival-related appears to be stuck.
If this option is enabled and a new reqres recently moved to the unarchived state, a new notification will be generated. If this option is enabled, a new notification will be generated when the archival queue gets empty the very first time or after previous failures.
A failed to archive reqres (glob) is a reqres that is currently in unarchived state, i.e., a reqres that failed to be archived by one of the enabled archival methods.
You can retry archiving these by pressing this button.
Also, note that this number is also a part of the sum represented by the second number on the Queued/Failed line.
An exported reqres (glob) is a reqres that was successfully exported by generating a fake-Download containing its dump.
A submitted reqres (glob) is a reqres that was successfully submitted via HTTP to the configured archiving server.
A saved reqres (glob) is a reqres that was successfully saved by being archived into browser’s local storage.
Note the difference between stashed and saved reqres:
An archived reqres is either exported, submitted, or saved reqres.
Hoardy-Web allows reqres saved in browser’s local storage to be re-archived a second, third, fourth, etc time. This feature uses the same archiving pipeline as above with three major differences:
Unlike archival, re-archival is not automatic.
You will have to manually press its popup UI action buttons, a similar button on the Saved in Local Storage page, or keyboard shortcuts.
Re-archival pipeline uses a separate data structure for recording reqres that end up in the unarchived state. The unarchived reqres of re-archival pipeline do not get retried, becoming forgotten instead.
After all, they are already archived in browser’s local storage, thus, if they fail to re-archive, Hoardy-Web can simply forget about them until they get re-loaded from local storage again.
For performance and safety reasons (to prevent possible race conditions between archival and re-archival), re-archival pipeline currently blocks the main thread of Hoardy-Web completely, until all re-archival actions finish.
The capture machinery and some UI updates will continue to work, but stashing, archival, and post-archival computations will not happen while re-archival is running.
Re-archival can be most useful in following use cases:
You want to collect and accumulate lots of reqres before re-archiving them by the means of Export via 'saveAs' to make the UI less annoying and to compress the resulting WRR bundle’s better.
You run Hoardy-Web under a Fenix-based mobile browser, where Export via saveAs does not work, you are unable to run an archiving server on the same device, because it’s an unrooted mobile phone, and you don’t want to submit your dumps over the Internet, because you are feeling paranoid.
By using this feature, you can delay re-archival to your archiving server until you get back to your home Wi-Fi network/USB tether, and re-archive everything all at once there.
You run Hoardy-Web under Tor Browser and you want your browsing/capture and archival/replay workflows completely isolated from each other.
The simplest way to re-archive old data is to configure the desired re-archival methods and then press Re-archive all button. This will simply re-archive everything stored in local storage unconditionally.
Since archival and re-archival use the same archiving pipeline, similarly to unarchived reqres, re-archival also remembers if a given reqres was previously (re-)archived using each archival method. Thus, enabling a re-archival method and then pressing Re-archive new button/shortcut (shortcut key of rearchiveAdjunctSaved) will skip re-archival of reqres that were previously archived or re-archived using that same method.
I.e., you can just configure the desired re-archival methods and then press Re-archive new button/shortcut (shortcut key of rearchiveAdjunctSaved) from time to time, with each new press re-archiving a new batch.
If you want more control over what gets re-archived, you can also
Saved in Local Storage page,saved reqres using the filtering options there, and thenRe-archive button there.In use cases
you can easily delete your previously successfully archived or re-archived reqres from your local storage by
Saved in Local Storage page, orDelete (re-)archived button.However, the first two options should be used with caution:
The behaviour of the Re-archive new button with deletion enabled can be surprising if you sometimes use both available re-archival methods and sometimes only one of them.
For example, if you have both re-archival methods enabled and some reqres fail to be archived with one of them, but then, later, you disable that method and run Re-archive new with deletion enabled again, those previously failed to re-archive reqres will be deleted too.
In other words, unlike with normal archival, re-archival failures don’t get recorded anywhere.
Re-archiving by the means of re-archival action buttons (or their Saved in Local Storage page equivalents) when both Export via 'saveAs' and deletion (or its Saved in Local Storage page equivalent) are enabled is unsafe because of browser API limitations.
The essence of the issue there is that if a new reqres gets captured and then saved into local storage via the normal Archive 'collected' reqres machinery right at the moment you press the Re-archive new button/shortcut (shortcut key of rearchiveAdjunctSaved) and the generated WRR bundle then silently fails to be saved to disk via saveAs, then that sneaky reqres will still get deleted, and, thus, permanently lost.
Thus, if you want to do this safely, you should:
Delete (re-)archived button without touching any re-archival method toggles.Alternatively, you can also do this:
Archive 'collected' reqres option;Re-archive new button/shortcut (shortcut key of rearchiveAdjunctSaved),The last button press should then produce a Re-archived and deleted <N> reqres invoking 0 archiving actions and <N> deletions from local storage. notification. I.e. it will just delete all of them, without actually performing any archivals.
Or, alternatively, as a last step, you can open Saved in Local Storage page, set Exported via 'saveAs' filter to true and then press Delete button there.
In short, re-archival actions with deletion set should be used with lots of care. This is why the rewrite and deletion options and their equivalents on Saved in Local Storage page are ephemeral and will be reset the next time you reopen the popup or that page.
Additionally, note that you can press re-archive and deletion buttons one after the other immediately, their actions will get queued for execution properly and won’t interfere with each other. Thus, if you are re-archiving via submission via HTTP it’s safe to mash them one after the other, you don’t need to sit there and wait for one action to finish before pressing the other button, since submission over HTTP reports errors properly.
However, note that re-archival by submission via HTTP with deletion enabled is safe to use too. On-the-fly deletion is much more efficient compared to re-archival step followed by a separate deletion step because updated reqres’ archival flags need not be written back into local storage. Thus, since submission via HTTP does report its errors properly, successfully re-archived reqres can be immediately and safely deleted from local storage in that case, which would save you a lot of time and disk writes if you are re-archiving a lot of stuff all at once.
problematic reqresConventional web browsers provide no explicit indication when a part of a web page fails to load properly. Apparently, you are expected to actually look at the page with your eyes, notice something looking broken, and reload it manually if so.
Obviously, this can be quite inconvenient when you want to be sure that the whole page with all of its resources was archived. Especially when parts of a dynamically loaded page might simply silently fail to be rendered by associated JavaScript because some of the HTTP requests that JavaScript did in background failed, or, on a static web page, layout and CSS might have made some of the incompletely loaded parts of the page invisible (by design or by accident).
So, to provide an explicit indicator for such situations, Hoardy-Web keeps track of reqres that fail to load properly and, in the classification step, marks them with a problematic flag which influences
toolbar button’s icon, badge, and title;
all of which depend on the numbers of currently problematic reqres;
the logs (glob, win, tab), which shows problematic reqres in a separate section;
and nothing else.
In other words, the problematic flag is a UI indicator, it does not influence archival in any way.
What gets marked as problematic is controlled by Mark reqres as 'problematic' when they finish options. By default, HTTP requests that failed to get a response, those that were fetched with buggy metadata or have incomplete response bodies, and those for which the browser reported potentially problematic errors but then Hoardy-Web picked them anyway, will be marked as problematic.
Potentially problematic errors are errors like
JavaScript function making it decided to cancel it when you moved your mouse cursor away from a video thumbnail it was needed for”,but not errors like
uBlock Origin”,In principle, Hoardy-Web could have been designed to never record the errors of the latter category in the first place, thus simplifying the above bit, but Hoardy-Web is designed to follow the philosophy of “collect everything as browser gives it, as raw as possible”. The raw error strings reported by the browser for each reqres can be seen in the logs (glob, win, tab).
When that option is not disabled, new notifications will be produced each time a new problematic reqres appears.
Mark reqres as 'problematic' when they finish settings.problematic reqresIn some situations some of the problematic flags on some of your reqres might become irrelevant as you fetch more data.
For example, say, you load a tab, some of its images fail to load completely and get marked as problematic, so you re-load that tab again, and then all reqres that failed to be fetched the first time get fetched properly the second time. Do you still care that some of those old reqres failed to fetch properly the first time? Probably not.
But to be absolutely pedantic in such a situation, you would actually need to carefully check that all of your old problematic reqres actually got re-fetched properly, just in case the browser decided to skip fetching some of them, which could happen with modern HTML lazy loading features or if the page in question is just awfully dynamic, and only then stop caring about them. Obviously, actually doing this manually each time would be incredibly annoying.
Which is why Hoardy-Web provides a bunch of configuration options that automatically unmark old problematic reqres in various situations. By default, those options are set in a way that produces least annoying and least surprising workflow, but you might want to tweak them if you need that process to be stricter.
In particular, note that the default value of Auto-unmark problematic reqres … regardless of its in_limbo state option produces slightly imprecise results when combined with picking into limbo (glob, win, tab, chld, bg, ext). Thus, if you are feeling pedantic, you might want to disable that option. Though, if you do that, the resulting behaviour of Hoardy-Web will probably feel rather counter-intuitive, at least at first.
Additionally, when that option is set to its right-most state, new notifications will be generated each time an old problematic reqres gets automatically unmarked.
problematic reqresIn most use cases, Hoardy-Web is entirely capable of automatically maintaining a relevant set of still problematic reqres, helping you figure out what still needs to be (re-)fetched to completely archive a given web page properly. However, in some situations, you might also want to manually unmark some of your problematic reqres. To do that you can:
unmark all currently problematic reqres via the appropriate buttons (glob, win, tab) and/or keyboard shortcuts;
unmark problematic reqres by using similar buttons in the logs (glob, win, tab), which allows for more granular control via the reqres filtering options available there.
problematic reqres annoy me!If you don’t care about the problematic flag in a select tab and those notifications annoy you, you can disable this per-tab option. If such notification annoy you in general, you can disable the global option instead.
Note, however, that you probably shouldn’t be disabling too many of Mark reqres as 'problematic' when they finish options. This way, even with notifications disabled, you would still be to able see the correct number of problematic reqres in extension’s toolbar button’s badge, popup (glob, win, tab), and the logs (glob, win, tab).
Hoardy-Web tracks both the number of in_flight reqres and the timestamp of the last network-fetched finished reqres for each tab and uses them to track when a tab’s content settles.
Which is to say, Hoardy-Web can delay some actions in a tab (currently, replays and snapshots) until all in-flight reqres in that tab become finished, then wait an additional configurable delay (glob, win, tab, chld) to allow that page’s JavaScript to process its fetched data (and, possibly, update its DOM and/or generate new requests), and then run the actual action only if the tab generates no new requests in the meantime.
If the tab does generate new requests, the process will repeat from the beginning up to configured number of times (glob, win, tab, chld) and produce an error notification if that number of retries gets exceeded.
Also, note that the network-fetched finished reqres bit above is important as reqres produced by the DOM snapshotting machinery are ignored by the tab settling machinery. If they were not, a DOM snapshot followed by a replay or another DOM snapshot would have to wait for the page to re-settle again, which would be annoying.
When a Hoardy-Web action affects multiple tabs, each tab settles, or fails to settle, independently from the others.
If you use hoardy-web serve or something similarly powerful as your archiving server and this option is not disabled, Hoardy-Web will enable its integration with replay over HTTP which enables the following Hoardy-Web features.
With server replays available and enabled, pressing one of the replay buttons (glob, win, tab) will make Hoardy-Web wait for the affected tabs to settle, collect all of their in-limbo reqres, and then re-navigate them to their replay pages. For the former two buttons, a tab can be excluded from the affected set by untoggling this per-tab setting.
Additionally, Hoardy-Web implements per-tab auto-replay mode (glob, win, tab, chld), which automatically redirects all navigations in a tab to their replay URLs.
This mode of operation is most useful when you want to open a replay of a previously bookmarked URL without editing it manually, nor first loading that page from the Internet and then replaying it the normal way (glob, win, tab).
If the archiving server does not support replay or when this option is disabled, auto-replay mode will cancel those requests and generate error notifications instead.
Currently auto-replay mode only works for top-level navigation requests and performs redirects regardless of your archiving server having an archive of the URL in question. (This will be improved in the future.)
DOM (Document Object Model) snapshotsIn principle, Hoardy-Web can capture everything your browser fetches from the network via HTTP as you browse the web. So, web pages that use simple JavaScript code to generate their content from those HTTP requests and/or use simple JavaScript to improve their UI will work fine when you start replaying them via hoardy-web serve over HTTP, via hoardy-web mirror statically, or some such.
However, unfortunately, in the most general case, “from scratch” replay of pages dynamically generated via JavaScript is not guaranteed. For example, consider a web page with a JavaScript code that generates a random number, then queries a remote server with that number, and then renders the result somehow. Obviously, such a web page can not be replayed “from scratch” since it will generate a new random number and your archive probably won’t have the corresponding server’s response for it.
Additionally, more and more dynamic web pages fetch data using WebSockets protocol, which Hoardy-Web can’t capture at the moment.
Moreover, even when a web page can be replayed, sometimes it’s desirable to have a simple HTML dump of its contents, e.g., for full-text indexing purposes.
Which is why, to support the above and related use cases, Hoardy-Web implements DOM snapshots.
Pressing one of DOM snapshot buttons (glob, win, tab) in the popup will capture snapshots of raw HTML’s or XML’s for each frame contained in each affected tab after said tab settles. For the former two buttons, a tab can be excluded from the affected set by untoggling this per-tab setting.
WRR-wise DOM snapshots are 200 OK responses, but with protocol set to SNAPSHOT and method set to DOM.
Sometimes, you might want to block a select tab from performing new HTTP requests.
Normally, when you replay your archived pages via hoardy-web serve, hoardy-web mirror, or some such, you would probably want the resulting generated pages to remap all their requisites (CSS, images, etc) to point to their local replay URLs and files. (Which is how hoardy-web tool does it by default. Though, it is configurable.)
Unfortunately, HTML5 specification is quite large, complex, and it gets updated all the time. Additionally, hoardy-web can have bugs in its remapping code. Moreover, interactions between remapped pages and some browser extensions can sometimes break things too. In other words, some of those replayed pages could end up referencing Internet resources when they should not.
In a similar vein, imagine a situation where, while looking at your logs (glob, win, tab), you discover that a web page originating from a certain domain is making an awful lot of tracking HTTP requests:
HTTP requests from its JavaScript event handlers, like when you switch to/from its tab, when you drag your mouse cursor around that page, and/or when you select text on that page;JavaScript disabled on that page, but as you scroll it around you notice that it starts generating suspicious HTTP requests because that page uses lazily loaded single-pixel HTML img tags to track you scrolling it anyway;JavaScript and lazy loading disabled, but then you notice that the font size on that page is deliberately too small, so you have to tweak that tab’s zoom level, which changes that tab’s viewport size, which then makes your browser generate new tracking HTTP requests because that page uses responsive CSS to track that;HTML standards are being exploited to archive similar results.Now, say that, after considering the above, you discover that you dislike the idea of “TVs that watch you back” from Orwell’s “1984” greatly, and you would rather ensure that
hoardy-web serve’ed or hoardy-web mirror’ed pages; andIn some cases you might even feel paranoid enough to want to prevent your browser from opening non-remapped jump-links (a href) on replay pages, even when you explicitly click them (by accident).
Desktop versions of Firefox-based browsers have a File > Work Offline option that can solve most of this, but it disables all new requests browser-wise, which is quite inconvenient and error-prone if you want to keep some of your tabs offline while not restricting others, and it will break replay over HTTP with hoardy-web serve. Chromium-based browsers do not appear to have such a feature at all.
To solve this issue, Hoardy-Web implements its own granular work offline mode which can be controlled via per-whatever Work offline toggles (glob, win, tab, chld, bg, ext).
Unlike the File > Work Offline option of Firefox, enabling any of these toggles:
does not break hoardy-web serve replay URLs;
does not break any requests that are already in flight;
does not prevent generation/capture of new canceled reqres when both of the corresponding Track new requests (glob, win, tab, chld, bg, ext) and ... including when 'Work offline' is set (glob, win, tab, chld, bg, ext) toggles are set;
this makes it possible to inspect the resulting canceled reqres in the logs (glob, win, tab);
though, note that those newly generated canceled reqres will be marked as problematic if that option is enabled.
Finally, there is also a bunch of options that automatically enable work offline mode in tabs with various classes of URLs. By default, work offline mode is enabled for file: and replay URLs to stop any pages generated by hoardy-web serve and hoardy-web mirror from accessing the Internet.
Note that if you spawn a bunch of tabs to fetch stuff in background with middle mouse click or some such and some of those fetches fail, you can easily loose track of where those newly generated problematic reqres you are seeing are coming from. Similarly, if you have picking into limbo enabled in a bunch of tabs you can easily loose track of which tabs have yet un-collected in_limbo reqres.
Thus, naively, if you see Hoardy-Web toolbar button’s badge show you a non-zero number and you don’t know where it’s coming from, you can:
start switching between your browser tabs with Control+Tab or similar and watching the changes to Hoardy-Web’s toolbar button to see if each particular tab needs you attention;
open the global log page, select a random reqres from the “Problematic” and/or “In Limbo” sections there, click one of the per-reqres buttons there to switch to its associated tab or a narrowed Internal State page, deal with the issue there, go back to the global log page, and do it all over again for the next reqres/tab.
Note, however, that both of the above methods are annoying in different ways.
Which is why Hoardy-Web implements a bunch of buttons and keyboard shortcuts that can switch between and/or highlight/select browser tabs in ways that take problematic, in_limbo, and last finished reqres of each tab into account. See their help strings for detailed descriptions of what those actions do.
Most notably, by using those buttons/shortcuts, the above use cases can be solved by pressing shortcut short of smartSwitchTabsLatest (shortcut key of smartSwitchTabsLatest), looking at the tab in question, pressing shortcut short of unmarkTabProblematic (shortcut key of unmarkTabProblematic), shortcut short of collectTabInLimbo (shortcut key of collectTabInLimbo), shortcut short of discardTabInLimbo (shortcut key of discardTabInLimbo), and/or shortcut short of closeTabThenDiscardInLimbo (shortcut key of closeTabThenDiscardInLimbo) buttons/shortcuts, and repeating until all problematic and/or in_limbo reqres dealt with.
Moreover, for the in_limbo use case, you can hit shortcut short of highlightTabsLatest (shortcut key of highlightTabsLatest), then drag-and-drop all those tabs to a new window, walk through them pressing shortcut short of discardTabInLimbo (shortcut key of discardTabInLimbo) or shortcut short of closeTabThenDiscardInLimbo (shortcut key of closeTabThenDiscardInLimbo) buttons/shortcuts in all the tabs you don’t want, and then press shortcut short of collectWindowInLimbo (shortcut key of collectWindowInLimbo) to collect everything else. Which you can then follow up by shortcut short of replayWindow (shortcut key of replayWindow) to confirm the results.
Hoardy-Web implements the following keyboard shortcuts:
| Description | Currently | Default |
|---|
The above table implements some rudimentary shortcut editing on the browsers that support it. Outside of that, you can view and edit all of your keyboard shortcuts via:
Extensions and themes (about:addons, Ctrl+Shift+A) -> the gear icon -> Manage Extension Shortcuts.Extensions -> Manage Extensions (chrome://extensions/) -> Keyboard shortcuts (on the left).Also, note a very relevant “FAQ” item below.
Hoardy-Web implements context menu actions to:
open a replay of a given link in a new tab;
i.e., to run shortcut short of spawnReplayTabBackward (shortcut key of spawnReplayTabBackward), but on a given link’s URL instead of the currently active tab’s URL;
open a given link in a new tab with currently active tab’s tracking in children tabs setting negated;
i.e.,
Hoardy-Web > Open Link in New Tracked/Untracked Tab menu item,is equivalent to
do either of the above, and then move that newly created tab into a new window;
in which case, the per-window config copying rules will apply.
Hoardy-Web with Fenix (Firefox on Android)Since Export dumps via 'saveAs' option and its re-archival variant do not work under Firefox on Android, you will have to use Submit dumps via 'HTTP' and/or its re-archival variant to extract your archives from Hoardy-Web. There are several ways you can do this:
--host 0.0.0.0 argument on your PC to allow non-localhost connections;Hoardy-Web to archive data via Submit dumps via 'HTTP';Server URL setting to your PC;Hoardy-Web work normally.sudo adb kill-server && sudo adb start-server && adb reverse tcp:3210 tcp:3210 on your PC, which would setup a reverse port forwarding from your Android device to your PC;Hoardy-Web to archive data via Submit dumps via 'HTTP';Server URL setting;Hoardy-Web work normally.Hoardy-Web to archive data via Save reqres into local storage, which is the default;HTTP;Server URL setting using one of the above ways;adb commands included), re-archive your archived data incrementally.Hoardy-Web with Tor BrowserWhen running Hoardy-Web under Tor Browser you’ll probably want to configure it in such a way so that all of the machinery of Hoardy-Web is completely invisible to web pages running under your Tor Browser, to prevent fingerprinting.
Thus, you can simply use Hoardy-Web extension configured to Save reqres into local storage, which is the default, and then export your dumps manually at the end of a browsing session via re-archival actions, which would take a couple of clicks, as discussed above.
Or, alternatively, you can switch to using Export dumps via 'saveAs' by default instead, disabling the other archiving methods. I expect this to work fine for 99.99% of the users 99.99% of the time, but, technically speaking, this is unsafe. Also, by default, browser’s UI will be slightly annoying, since Hoardy-Web will be generating new “Downloads” all the time, but that issue can be fixed with a small about:config change.
Using either of the above methods won’t allow you to replay archived captures, though.
In theory, running hoardy-web serve listening on a loopback IP address should prevent web pages from accessing it, since the browsers disallow cross-origin requests from non-localhost domains to localhost, thus making the normal Submit dumps via 'HTTP' mode with replay setup quite viable. However, Tor Browser is configured to proxy everything via the TOR network by default, so you need to configure it to exclude the requests to hoardy-web serve from being proxied.
A slightly more paranoid than normal way to do this is as follows:
hoardy-web serve --host 127.0.99.1 or similar.Server URL setting to the resulting URL (http://127.0.99.1:3210/ or similar).Submit dumps via 'HTTP' by default, disabling the other archiving methods.about:config in your Tor Browser and add 127.0.99.1 (or similar) to network.proxy.no_proxies_on.Why? When using Tor Browser, you probably don’t want to use 127.0.0.1 and 127.0.1.1 as those are normal loopback IP addresses used by most things, and you probably don’t want to allow any JavaScript code running in Tor Browser to (potentially, if there are any bugs) access to those. Yes, if there are any bugs in the cross-domain check code, with this setup a nefarious page’s JavaScript could discover you are using Hoardy-Web (and then, in the worst case, access all of your archived captures and DOS your system by flooding your disk with garbage dumps), but it won’t be able to touch the rest of your stuff listening on your other loopback addresses.
So, while this setup is not super-secure if your Tor Browser allows web pages to run arbitrary JavaScript (in which case, let’s be honest, no setup is secure), with JavaScript always disabled, to me, it looks like a completely reasonable thing to do.
One of
`Hoardy-Web` can't establish a connection to the archiving server at `<URL>`,The archiving server at `<URL>` appears to be unavailable,The archiving server at `<URL>` does not allow archiving, it appears to be a replay-only instance,... Failed to archive <N> items because this archiving server is unavailable,... Failed to archive <N> items because this archiving server does not support archiving,... Failed to archive <N> items because this archiving server appears to be defunct, or... Failed to archive <N> items because `Hoardy-Web` can't establish a connection to the archiving server: <reason>,Re-archival was aborted because the archiving server appears to be unavailable or defunct:Are you running the hoardy-web-sas archiving server script or a hoardy-web serve instance?
In the case of hoardy-web serve, does that server instance allow archiving? Is it replay-only, maybe?
If the archiving server is on another machine did you open the port it is listening to on your firewall or did you forward it via adb reverse?
If you fixed it and the error persists, press this button.
... Failed to archive <N> items because requests to the archiving server failed with: <STATUS> <REASON>: <RESPONSE>:
Your archiving sever is returning HTTP errors when Hoardy-Web is trying to archive data to it. See your archiving server’s console for more information.
Some common reasons it could be failing:
One of
... Failed to stash <N> items because <reason> or... Failed to archive <N> items because <reason>that are not the ones mentioned above:
Stashing or archiving failed for some other reason.
Some common reasons it could be failing:
Replay/Auto-replay is forbidden by the "Replay from the archiving server" option:
Enable this option.
Replay/Auto-replay is impossible because the archiving server at `<URL>` <reason>:
Are you running hoardy-web serve?
At the moment, that’s the only archiving server that supports this feature.
If you fixed it and the error persists, press this button.
Failed to open Hoardy-Web's database using `IndexedDB` API, but it appears that `IndexedDB` was previously used for stashing and/or archiving reqres. ...:
The most likely reason for this error is that you are running Hoardy-Web under a browser based on an older version of Firefox and you have recently enabled Always use private browsing mode setting in your browser’s config. Older versions of Firefox forbid the use of IndexedDB API when that setting is set.
To make archives currently saved in IndexedDB accessible to Hoardy-Web under Always use private browsing mode you need to:
Always use private browsing mode browser setting and restart the browser, thus allowing Hoardy-Web access to IndexedDB again.Prefer 'IndexedDB' API setting.Re-archive new button/shortcut (shortcut key of rearchiveAdjunctSaved),Always use private browsing mode browser setting and restart you browser again.All old data should be available at the Saved in Local Storage page now.
Bugged out: Failed to process <N> items because <reason>:
It’s a bug, open an issue on GitHub or get in touch otherwise.
Other error notifications should be completely self descriptive. If they are not, open an issue on GitHub or get in touch otherwise.
reqres, as seen in the logsMost error codes are produced by attaching one of the following prefixes to the raw error code given by the browser:
webRequest:: prefix is prepended to errors produced by the code working with webRequest API;
debugger:: prefix is prepended to errors produced by the code working with Chromium’s Debugger API;
filterResponseData:: prefix is prepended to errors produced by webRequest.filterResponseData API (these can usually be ignored, since Firefox generates normal webRequest:: codes for those reqres too, when it was an actual error; but Hoardy-Web still collects them, adhering to “collect everything as browser gives it, when possible” philosophy).
In particular, webRequest::NS_ prefix on Firefox, and webRequest::net:: and debugger::net:: prefixes on Chromium signify various issues produced by the networking stacks of those browsers. For instance:
webRequest::NS_ERROR_ABORT on Firefox and webRequest::net::ERR_ABORTED on Chromium signify that this request was aborted before it finished, e.g. because the originator tab was closed before it was fully loaded; Firefox also uses this code to mean what Chromium signifies with various BLOCKED codes;
webRequest::net::ERR_BLOCKED_BY_CLIENT on Chromium signifies that an extension blocked it;
debugger::net::ERR_BLOCKED:: is a prefix for other errors when the request was blocked, e.g. by CSP;
webRequest::NS_ERROR_NET prefix on Firefox and webRequest::net::ERR_FAILED error on Chromium signify various networking issues.
The exception to the above rule of keeping everything as raw as possible are webRequest::capture:: and debugger::capture:: prefixes which signify various errors produced by Hoardy-Web itself in its webRequest- or debugger-handling code, respectively. In particular:
webRequest::capture::EMIT_FORCED::BY_USER and debugger::capture::EMIT_FORCED::BY_USER are produced when you forcefully advance a reqres from in-flight state by pressing one of the relevant buttons (glob, win, tab);
debugger::capture::EMIT_FORCED::BY_DETACHED_DEBUGGER is produced when Chromium debugger gets detached from its tab while a reqres inside that tab is still in flight;
debugger::capture::EMIT_FORCED::BY_CLOSED_TAB is produced when a tab gets closed while a reqres inside of it is still in flight;
debugger::capture::NO_RESPONSE_BODY:: is a prefix for errors produced when getting request’s response body from Chromium’s debugger fails for various reasons;
webRequest::capture::CANCELED::NO_DEBUGGER is produced when a non-main-frame request is canceled by Hoardy-Web because no debugger is available to capture it;
in the case of a main frame request, Hoardy-Web will cancel the request and reload the tab, as discussed there, so this error will not be produced;
but it can happen if a page tries to load a sub-frame (like iframe) while the debugger for the tab (and, thus, the main frame) did not attach yet (which only happens for pages where Chromium disallows debugging, or when Hoardy-Web gets enabled after the page in question already started loading, e.g. the very first page after the browser starts);
also, this can happen when the debugger gets detached after the main frame was captured but its resources are still loading.
webRequest::capture::CANCELED::BY_WORK_OFFLINE is produced when the reqres was canceled as a result of one of the work offline toggles (glob, win, tab, chld, bg, ext) being set.
If you are reading this page outside of the extension’s UI be sure to read the very top of this page first.
Hoardy-Web’s own issuesHoardy-Web does not implement collection of WebSockets data on any of the supported browsers.
(Firefox does not support it. Chromium does support it, in theory, but I have not tried using that API, so I have no idea how well it works.)
This is low-priority issue since you can simply take a DOM snapshot instead of capturing and later replaying WebSocket messages to in-page JavaScript. Also, capturing and archiving a DOM snapshot will free you from needing to run any JavaScript at all when you decide to replay the archived page later, which is nice.
On Chromium, response data of background requests and requests made by other extensions does not get collected, since there’s no tab to attach a debugger to, and I have not figured out how to attach debugger to other things yet.
On Firefox, fetches that spawn new downloads will be marked as problematic by default, since Firefox’s implementation of webRequest.filterResponseData API does not provide their contents to the extension and I have not figured out how to distinguish them from other fetches yet.
When Hoardy-Web is reloaded without using the Reload button or Auto-reload on updates option, e.g. when Hoardy-Web is reloaded by clicking the “Reload” button in browser’s extension list, then all per-tab settings of all tabs will be reset to the values used by the newly spawned tabs.
This issue is not applicable in the case when the reload happens because the extension was updated, in that case the browser will notify Hoardy-Web about it and Hoardy-Web will handle it properly, see the help string of the Reload button for more info.
But in the case of browser’s Reload buttons, the browser does not ask the extension nicely, so all unsaved internal state will be lost.
If an HTTP server supplies the same header multiple times — which happens sometimes, most commonly with Set-Cookie headers — then the archived response headers will usually become weird, with multiple headers squished into a single value, separated by newline symbols.
This is just the way both Firefox (usually) and Chromium (always) supply those headers to extensions and Hoardy-Web does not try to undo it.
Browsers do not report a fake-Download file failing to be written to disk via saveAs API as an error.
This makes Export dumps via 'saveAs' archival and similar re-archival options technically unsafe.
On Firefox-based browsers, without the patch, the browser only supplies formData to webRequest.onBeforeRequest handlers, thus making impossible to recover the actual request body for a POST request.
Hoardy-Web will mark such requests as having a partial request body and try its best to recover the data from formData structure, but if a POST request was uploading files, they won’t be recoverable from formData (in fact, it is not even possible to tell if there were any files attached there), and so your archived request data will be incomplete even after Hoardy-Web did its best.
With the above patch applied, small POST requests will be archived completely and correctly. POST requests that upload large files and only those will be marked as having a partial request body.
If-Modified-Since and If-None-Match headers never get archived, because the browser never supplies them to the extensions. Thus, you can get 304 Not Modified reqres response to a seemingly normal GET request.
Reqres of already cached media files (images, audio, video, except for SVG and favicons) will end in incomplete_fc state because webRequest.filterResponseData API does not provide response bodies for such requests.
This toggle controls if such reqres should be picked. By default, Hoardy-Web will drop them. Usually this is not a problem since such media will be archived on first (non-cached) access. But if you want to force everything on the page to be archived, you can reload the page without the cache with Control+F5.
Firefox fails to run onstop method for webRequest.filterResponseData filter for the very first HTTP/2 request the browser makes after you start it, thus making the reqres of that request incomplete.
If this option is enabled, Hoardy-Web will transparently work around this bug by redirecting the very first navigation request to about:blank and then reloading the tab with its original URL.
Firefox-based browsers provide no API for archiving WebSockets data at the moment, unfortunately.
Firefox fails to provide response metadata when a request gets fulfilled by a service or shared worker after Firefox had already sent it to the server. Firefox interrupts the networking code and generates NS_ERROR_NET_ON_* error about the event, but it fails to supply the response metadata generated by the service/shared worker in that event.
Hoardy-Web then has to take guesses, and marks such reqres with buggy response metadata flag.
All of the above apply, moreover:
saveAs is not supported at the moment because of this bug.On Chromium-based browsers, there is no way to get HTTP response data without attaching Chromium’s debugger to a tab from which a request originates from. This makes things a bit tricky, for instance:
With this and this option enabled, newly spawned tabs will be reset to this value (about:blank by default) because the default of chrome://newtab/ does not allow attaching debugger to the tabs with chrome: URLs.
Requests made before the debugger is attached will get canceled by Hoardy-Web.
So, for instance, when you middle-click a link, Chromium will open a new tab, but Hoardy-Web will block the requests from there until the debugger gets attached and then automatically reload the tab after.
As side-effect of this, Chromium will show Request blocked page until the debugger is attached and the page is reloaded, meaning it will get visually stuck on Request blocked page if fetching the request ended up spawning a download instead of showing a page. The download will proceed as normal, though.
You will get an annoying notification bar constantly displayed in the browser while tracking is enabled in one of the tabs. Closing that notification will detach the debugger.
Hoardy-Web will reattach it immediately because it assumes you don’t want to lose data and closing that notification on accident is, unfortunately, quite easy.
However, closing the notification will make all in-flight requests lose their response data.
All alternatives to Hoardy-Web that work with Chromium suffer from the same issue.
If you disable this per-tab option the debugger will only get detached from the tab after all of its requests finish. But even if you disable that option in all open tabs and wait until there are no requests in-flight, the notification will not disappear immediately. Chromium will take its time in updating the UI after the debugger is detached.
Moreover, Chromium has the following long-standing issues/bugs making things difficult:
Chromium will automatically detach its debugger from a tab if it tries to save too much data into its debugger state. Which means that a tab that loads too much data too fast will get its debugger detached.
Chromium does this to try and save memory, but this, among other issues, means that large images will fail to be properly archived, and any page that loads such files is likely to fail to be archived too.
This is a design limitation of Chromium debugging interface, there appears to be no work-around for this at the moment.
Meanwhile, on Firefox, Hoardy-Web uses webRequest.filterResponseData API (not available on Chromium, because it greatly enhances browser’s ad-blocking capabilities) which does not suffer from this problem.
Chromium will occasionally detach debuggers from some tabs at random. It just happens.
Fortunately, Hoardy-Web will mark the resulting broken reqres as problematic by default as they match the conditions of at least one of this, this, or that options.
Chromium handling of media files (audio and video) within its debugging interface is very strange.
When Chromium encounters a media file, it immediately loads a first few frames of it, then cancels the rest of the download, generates a networking error debugging event, but forgets to give the already loaded data to it, and then, when the user clicks the play button, continues the download by requesting the rest of the file as normal.
Thus, on Chromium, for media files Hoardy-Web will only ever get 206 Partial Content HTTP responses with the first few kilobytes of file data missing.
This bug has no good workaround, all alternatives to Hoardy-Web that work with Chromium work it around by silently re-downloading the file the second time in background.
Similarly to unpatched Firefox, Chromium-based browsers do not supply contents of files in POST request data.
They do, however, provide a way to see if files were present in the request, so Hoardy-Web will mark such and only such requests as having a partial request body.
There is no patch for Chromium to fix this, nor do I plan to make one (feel free to contribute one, though).
Chromium fails to provide openerTabId to tabs created with chrome.tabs.create API so in the unlikely case of opening two or more new tabs/windows in rapid succession via Hoardy-Web context menu actions and not giving them time to initialize Hoardy-Web could end up mixing up settings between the newly created tabs/windows.
This bug is impossible to trigger unless your system is very slow or you are clicking things with automation tools like AutoHotKey or xnee.
To properly collect all the data about a reqres, Hoardy-Web has to use both the data generated by webRequest API and Chromium’s own debugging API events, using only one of those is usually insufficient.
But Chromium generates different request IDs for events generated by these two different APIs and also generates those events in arbitrary order. Therefore, Hoardy-Web tracks reqres generated by both sets of APIs separately and then matches those two lists against each other heuristically, merging matching reqres together.
Which is ugly enough.
But then, Chromium sometimes generates debugging API events and forgets to produce the corresponding webRequest API events, or vice versa, thus leaving some of those reqres unmatched.
To work around that, Hoardy-Web waits this many seconds for new events to arrive, and if none do, forcefully finishes all unmatched but network-complete in_flight reqres. Yes, this means that some minor metadata fields (like document_url) of those reqres might be missing, but waiting more time usually won’t fix it, so Hoardy-Web can’t do anything else there.
However, sometimes Chromium forgets to generate both loading-complete and loading-failed debugging events.
This usually happens when a request gets started and then canceled by a page’s JavaScript, or when you navigate between pages too fast.
In that case, Hoardy-Web can’t tell if a reqres is just slow at being loaded or if Chromium forgot about it, so those reqres will get stuck in the in_flight state indefinitely, at least until their originator tab gets closed, or until you press one of the relevant buttons (glob, win, tab).
Chromium sometimes simply does not generate any webRequest API events for a request it tracks.
Most commonly, this happens for responses loaded from cache, but it can also happen for network fetches, apparently, at random.
In this case, Hoardy-Web will collect no request data and metadata, this marking such reqres with both partial request body and buggy request metadata flags.
If you are reading this page outside of the extension’s UI be sure to read the very top of this page first.
Hoardy-Web send any of my captured web browsing data anywhere?No.
Hoardy-Web only ever sends your data to the configured Server URL when the Submit dumps via 'HTTP' option is enabled.
Nowhere else. Never else.
Hoardy-Web collect and send any telemetry anywhere?No.
For your convenience, Hoardy-Web saves some global stats across restarts (e.g., the Collected, Discarded, Picked, and Dropped lines).
However, none of those are ever sent anywhere and you can reset them at any time.
Hoardy-Web?No. I (the author) hate non-consensual data collection.
In fact, as you might have noticed, Hoardy-Web, unlike most other browser extensions, is almost trivial to reproducible-build from source on a POSIX-compliant system with a Nix package manager installed, and it has a privately operated source code mirror.
This is by design, I expect a chunk of Hoardy-Web users to be paranoid enough to only ever build it from source and install the results manually into their LibreWolf or some such, leaving zero telemetry fingerprints anywhere.
Hoardy-Web asks for a lot of permissions, what does it use all those permissions for?<all_urls> permission is used so that Hoardy-Web could capture all URLs.tabs permission is used for tracking per-tab states and stats, performing multi-tab DOM snapshots and replays, performing smart tab switches, performing switches to reqres-related tabs from the logs (glob, win, tab), etc.webRequest, webRequestBlocking, and (on Chromium) debugger permissions are used to track and capture HTTP requests and responses as well as to apply per-whatever settings when a tab navigates to a different URL.webNavigation permission is used to implement multi-frame DOM snapshots.storage permission is used to save extension config and stats.unlimitedStorage permission is used for stashing and archival of captured data to browser’s local storage.menus (contextMenus on Chromium) permission is used to add context menu actions.notifications permission is used to send notifications, which is mostly used for reporting various issues.Hoardy-Web to capture web pages while my browser runs with JavaScript disabled?Yes.
Hoardy-Web to capture web pages that use a lot of JavaScript?Yes, with the usual caveats of such a use case, which are discussed above.
Hoardy-Web to capture a web page as it currently is, after all JavaScript was run, not as it was when it was last fetched from the network?Yes, Hoardy-Web implement capture and archival of DOM snapshots.
Hoardy-Web capture a web page completely, especially when parts of it are loaded lazily?In the most general case, you will have to scroll the page around and click random buttons and media elements.
Hoardy-Web has no “autopilot” for doing this, nor will it ever get one, at least as part of Hoardy-Web extension itself, since “autopiloting” is very website-specific. So, at the moment, the most general semi-automated solution is to run a website-specific UserScript via Tampermonkey or some such, then take a DOM snapshot. (Hoardy-Web will implement UserScript-able API for that, eventually.)
On the other hand, if you
Hoardy-Web under Firefox,JavaScript to do the same,then you can simply go to about:config and toggle dom.image-lazy-loading.enabled to false. All images will start being loaded eagerly after that.
Hoardy-Web to capture a web page without archiving it, look at it, decide if I actually want to save it, and archive it only if I do, all without reloading the page a second time?Yes, this is why limbo mode exists.
https://addons.mozilla.org/ and https://chromewebstore.google.com/ can not be captured by Hoardy-Web?Browsers prevent extensions from running on extension store pages to prevent them from manipulating ratings, reviews, and similar things.
However, you can archive https://addons.mozilla.org/ pages by running Hoardy-Web under Chromium and https://chromewebstore.google.com/ pages by running Hoardy-Web under Firefox.
Hoardy-Web under Chromium, a lot of my captures fail with debugger::capture::EMIT_FORCED::BY_DETACHED_DEBUGGER, debugger::capture::NO_RESPONSE_BODY::DETACHED_DEBUGGER, webRequest::capture::CANCELED::NO_DEBUGGER, and similar errors. What do I do?You are either
pressing the Cancel or Close (cross) buttons in the Chromium’s popup-toolbar telling you about the debugger being enabled, and so Chromium detaches it, breaking everything (see there);
pressing Space or Escape keyboard keys when doing things in Chromium’s UI, but nothing at that particular moment reacts to the key you pressed, except there is that popup-toolbar… and so Chromium decides it must mean you want to press Cancel button there … and detaches the debugger, breaking everything (again);
yes, this is really annoying, and this is a common problem for me, since I usually page-down using Space and press Escape a lot (usually to cancel selection, but sometimes also as a long-time Vim user trauma);
the only solution to this I know of is to just not touch the keyboard at all, at least while things are still loading; i.e. just click on stuff using the mouse/track-point/touch-pad/touchscreen/etc, wait for the T (“Tracking”) to vanish from the extension’s badge, and only then let your (grabby and impatient for exercise via keyboard shortcuts) fingers to touch the keyboard;
even then, Chromium will detach its debugger from time to time seemingly at random, but at least it will be rare enough that you won’t need to reload much;
trying to capture large images, any audio files, or any videos;
as noted above, this has no workaround, run Hoardy-Web under Firefox instead.
Also, Chromium will occasionally detach its debugger at random, it just happens.
Hoardy-Web under Firefox, my captures get marked as buggy all the time. What do I do?This happens because of a race condition between webpage’s service/shared worker and browser’s networking code.
Usually, you can ignore these buggy reqres, since loading another related page is likely to fulfill the same URL.
However, if this happens a lot to you, or if it annoys you, you can go to about:config, toggle dom.serviceWorkers.enabled to false, and restart the browser. Alternatively, you can use NoScript or some such extension to disable JavaScript, and thus the offending service/shared workers, on the page in question.
Hoardy-Web?Did you read the notes on the bugs of the browser you are using?
Most notably:
both Firefox- and Chromium-based browsers in their default builds fail to properly supply POST request data to their extensions;
for Firefox-based browsers there exists a patch that fixes it, mostly;
Chromium users are out of luck at the moment;
on a Chromium-based browser, because of limitations of the Chromium’s debugging interface, it is impossible to properly capture media files (both audio and video) and large files in general;
this issue has no good work-around and, AFAIK, all alternatives to Hoardy-Web running on Chromium-based browser suffer from it (and work around it by silently re-downloading said files the second time in background);
try using Hoardy-Web under a Firefox-based browser instead.
Hoardy-Web hard to use. E.g., Wikipedia defines a ton of conflicting keyboard shortcuts making Alt+U navigate to their “Upload” page and Alt+O to their “Login” page, among others. Firefox then treats all of those as having higher priority than both Hoardy-Web’s and its own shortcuts, making things really annoying. Can this be worked around somehow?Kind of.
Go to about:config and set ui.key.generalAccessKey to 0. Doing that will make Firefox ignore all web page shortcuts defined via HTML’s accesskey mechanism. Which is not ideal if you use those sometimes, but this is better than your shortcuts doing completely random things on random websites.
Doing that will, at the very least, fix Hoardy-Web usage on Wikipedia and other MediaWiki websites. However, the above will not fix Hoardy-Web usage on websites that implement shortcuts via JavaScript handlers, those will be used with higher priority anyway.
Personally, I think that Firefox’s implementation of this whole thing is a bit weird. On Firefox, shortcuts defined by web pages have higher priority than browser’s own shortcuts, but add-on shortcuts have lower priority than both web page’s and browser’s own shortcuts. That is, on Firefox, their priority order is pages > browser > extensions. Both pages > extensions > browser and browser > extensions > pages orders I can justify:
Control+P printing actions and such;Meanwhile, Firefox’s order makes absolutely no sense to me.
In a better world, both the above order and browser’s own shortcuts would be configurable. In such a world, when using pages > extensions > browser order, browsers would also treat web page shortcuts as per-host opt-ins configurable with firewall-like rules, similarly how uBlock Origin configures itself.
In a simpler world, all browsers would just use browser > extensions > pages order. How many websites properly override browser’s own shortcuts in a useful and OS- and locale-aware way, anyway? Are users of those websites even aware that this feature is even supported there? I’m pretty sure the answers to the above questions are “almost none” and “some, most of these are power-users who discover it while trying use those shortcuts for something else”. So, IMHO, that feature introduces a lot of power-user-oriented annoyances while implementing a very fringe supposedly layperson-oriented use case. Please, remind me again, how many laypersons use keyboard shortcuts at all?
Hoardy-Web archival methods except for submission via HTTP are unsafe. Why?Archival by exporting using saveAs (generation of fake-Downloads) can fail and lose a bit of your collected data at a time if you press a wrong button in you browser’s UI, misconfigure your browser a bit, or your disk gets out of space unexpectedly.
Archival to browser’s local storage (which is what Hoardy-Web is doing by default) can loose all your collected data at the same time if you uninstall the extension by accident.
Meanwhile, archival by submission via HTTP has none of these problems:
Hoardy-Web keeps each reqres in memory until the archiving server responds with 200 OK for that reqres;
the archiving server only responds with 200 OK response to Hoardy-Web after the dump is written and fsync-ed to disk;
the archiving server never deletes any of your archived data;
by using an archiving server, you can only loose your archived data if you go to its directory and delete some of it yourself, or if your disk dies, or if your file system gets corrupted;
all of these problems can be trivially solved by doing backups regularly.
Archival to browser’s local storage was added because it was very easy to implement after stashing was added. It is the default because it usually works fine, it properly reports errors, has the most consistent behaviour across all browsers, and does not require the user to install any Python code, which helps with on-boarding.
In the ideal world, browsers would provide a better saveAs API which would have a less annoying UI for the user and would return out-of-disk-space errors to the extension, in which case exporting via saveAs would be the default.
As it is now, the only way to be absolutely sure you data is properly forever-saved to disk when the extension reports it archived is to use submission via HTTP or re-archive carefully.
Hoardy-Web under Firefox, enabling export via saveAs makes the browser’s UI quite annoying. Can it be fixed?Yes, go to about:config and toggle browser.download.alwaysOpenPanel to false.
Did you try searching for stuff with Control+F on this page? This document contains quite a bit of information.
Is your question about the Hoardy-Web browser extension in truth?
hoardy-web serve replay server, see there.Hoardy-Web project, see there.If none of those pages mention your problem, open an issue on GitHub or get in touch otherwise.
Usually, the simplest way to search for things is to simply git clone the whole thing and then search there with grep or more advanced tools. This applies not only to this project, but in general.
Support me via: