1. The Right Tool for Web Ingestion in Enterprise AI
Retrieval-Augmented Generation (RAG) and semantic search architectures frequently need to ingest web-accessible content: technical documentation portals (MkDocs, Docusaurus, Sphinx), internal developer hubs, Confluence pages, regulatory filings, and corporate intranets.
While OpenCrawling already provides a distributed web crawler through our oc-stormcrawler-repository-connector (running on Apache Storm clusters for web-scale crawling across millions of URLs), many teams simply need to crawl a few thousand pages per job without provisioning, supervising, and maintaining an external distributed compute cluster.
The brand-new Web Repository Connector (oc-web-repository-connector) is designed specifically for this sweet spot: it runs completely embedded within the OpenCrawling runtime, requires zero external infrastructure, and leverages Java 25 Virtual Threads to achieve high concurrency while strictly adhering to web etiquette and enterprise security policies.
🌐 Web Repository Connector (In-Process)
Target: Documentation sites, product portals, corporate intranets, knowledge bases (up to tens of thousands of pages).
Architecture: In-process Java 25 Virtual Threads, zero extra infrastructure, built-in SSRF Guard, shared runtime politeness gate.
🕷️ StormCrawler Connector (Distributed)
Target: Massive, continuous web crawling (millions of pages, multi-tenant internet crawling).
Architecture: Distributed Apache Storm 3.1.0 cluster, external worker bolts, Nimbus REST API orchestration.
2. RFC 9309 Robots.txt & Automatic Sitemap Discovery
Web etiquette is non-negotiable for enterprise crawlers. The connector integrates crawler-commons 1.5 to enforce full compliance with RFC 9309 (the standard for robots exclusion):
- Robots.txt Evaluation: Fetches and parses
robots.txtper host, accurately evaluatingUser-agent:,Disallow:, andAllow:rules before requesting any page. - Crawl-delay Respect: Honors
Crawl-delaydirectives issued by webmasters, dynamically raising the request interval up to a configurable ceiling (maxCrawlDelayMs). - Sitemap Ingestion: Automatically extracts
Sitemap:lines declared insiderobots.txt, and allows operators to supply explicit sitemap URLs (sitemapUrls). - Page-Level Directives: Honors
<meta name="robots" content="noindex, nofollow">and HTTPX-Robots-Tagheaders, preventing indexing of unindexed pages while respecting link traversal limits.
3. Runtime-Wide Politeness: The Shared HostRegistry
In enterprise deployments where multiple crawl jobs might run concurrently (or alongside other automated tasks), multiple workers targeting the same domain could accidentally trigger rate limiters or cause denial of service.
The Web Repository Connector solves this through a runtime-wide singleton HostRegistry. Every active crawl job in the JVM shares this registry. When any job requests a URL on docs.example.com, the host gate ensures that at least delayMs (default 1000ms, or the host's Crawl-delay) has elapsed since the last request to that same host, across all jobs.
Virtual Threads & Structured Concurrency: Crawl workers run on lightweight Java 25 Virtual Threads (Thread.ofVirtual()). Waiting for host politeness delays does not block underlying OS threads, allowing dozens of concurrent domain crawls with minimal memory footprint.
4. Spider Trap Prevention & Linear-Time Filtering
Web crawlers inevitably encounter "spider traps": dynamically generated calendar paths, infinite redirect chains, session-ID loops, or deeply nested directories. The connector incorporates defensive guards:
- Depth & Hop Limits: Restricts link exploration to
maxDepthlink hops from the seed (default 3, configurable from 0 to 50). - Trap Caps: Rejects URLs exceeding
maxUrlLength(2048 characters), query parameter counts exceedingmaxQueryParams(32), or repeated directory segments (maxRepeatedSegments: 3). - ReDoS-Free Regex Filtering: URL inclusion (
includePatterns) and exclusion (excludePatterns) are compiled with Google's RE2/J engine, guaranteeing linear-time execution and safeguarding the runtime against catastrophic backtracking attacks. - Query Parameter Normalization: Automatically strips tracking tokens (
utm_*,fbclid,gclid,msclkid, session IDs likejsessionid,phpsessid,sid) and sorts remaining query parameters for canonical consistency. - Content Deduplication: Follows
rel="canonical"link elements and calculates cryptographic SHA-256 body hashes to skip duplicate pages.
5. Enterprise SSRF Guard with DNS Rebinding Protection
Allowing a web crawler to fetch arbitrary URLs in an enterprise environment presents serious security risks: malicious users or manipulated links could trick the crawler into hitting internal network services (Server-Side Request Forgery - SSRF), such as Kubernetes control planes, internal databases, or cloud instance metadata endpoints (e.g., AWS/GCP 169.254.169.254).
The Web Repository Connector implements a deep defense layer via SsrfGuard:
Fail-Closed SSRF Defense: By default, all connections to loopback (127.0.0.0/8, ::1), RFC 1918 private subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local addresses (169.254.0.0/16), cloud metadata (169.254.169.254), and IPv6 unique-local addresses (fc00::/7) are strictly blocked.
Crucially, SsrfGuard validates target IP addresses at DNS resolution time using a custom Apache HttpClient 5 DnsResolver. It inspects every resolved IP before establishing a TCP socket connection, and repeats this check on every redirect hop, effectively neutralizing DNS rebinding attacks.
For crawling internal corporate intranets, operators can set allowPrivateNetworks: true accompanied by an explicit privateAllowlist specifying approved hostnames (e.g. intranet.corp.internal, .corp.local) or CIDR blocks (e.g. 10.50.0.0/16).
6. Zero-Trust Security & Reactive Backpressure
Like all OpenCrawling connectors, the Web Repository Connector natively participates in the Zero-Trust security model:
- ACL Modes: Supports
PUBLIC(default for public documentation) andSTATICmode (attaching user or group read keys such asgroup:engineering-staffto all documents). - Accidental Exposure Protection: When
allowPrivateNetworks: trueis enabled, settingaclMode: PUBLICfails validation unless the administrator explicitly providesconfirmPublicExposure: true, preventing accidental public exposure of internal intranet documents. - Reactive Backpressure: Emits a reactive
Flux<RepositoryDocument>backed by a thread-safeSemaphoredemand controller. Virtual crawling threads automatically pause when downstream Tika extraction, Ollama embeddings, or vector database writes fall behind.
7. Configuration & Job Examples
Settings can be specified at the job level (in crawlSpec JSON), at the connector level, or as Spring properties:
| Setting | Spring Property | Default | Description |
|---|---|---|---|
seeds |
spring.opencrawling.connector.web.seeds |
(Job path) | Start URLs for the crawl run |
maxDepth |
spring.opencrawling.connector.web.max-depth |
3 |
Link hops from seed URLs (0 to 50) |
maxPages |
spring.opencrawling.connector.web.max-pages |
1000 |
Maximum page requests executed per run |
delayMs |
spring.opencrawling.connector.web.delay-ms |
1000 |
Minimum wait time between requests to same host (ms) |
scope |
spring.opencrawling.connector.web.scope |
DOMAIN |
Crawl boundary: HOST, DOMAIN, PREFIX, or ANY |
respectRobots |
spring.opencrawling.connector.web.respect-robots |
true |
Honors RFC 9309 robots.txt rules and crawl-delay |
allowPrivateNetworks |
spring.opencrawling.connector.web.allow-private-networks |
false |
Permits crawling private intranet subnets |
privateAllowlist |
spring.opencrawling.connector.web.private-allowlist |
none | Permitted hostnames or CIDRs when private crawling is enabled |
aclMode |
spring.opencrawling.connector.web.acl-mode |
PUBLIC |
Security ACL mode: PUBLIC or STATIC |
maxThreads |
spring.opencrawling.connector.web.max-threads |
16 |
Concurrent virtual threads allocated per crawl run |
Example Job: Public Documentation Crawl
{
"name": "Product Documentation Crawl",
"repositoryConnector": "WebCrawler",
"outputConnector": "PGVector_Output",
"path": "https://docs.opencrawling.org/",
"crawlSpec": {
"maxDepth": 4,
"maxPages": 5000,
"delayMs": 1000,
"scope": "PREFIX",
"includePatterns": ["^/docs/"],
"excludePatterns": ["\\.(png|jpe?g|gif|svg|webp|css|js)$"],
"discoverSitemaps": true
}
}
Example Job: Authenticated Intranet Portal Crawl
{
"name": "Corporate Engineering Wiki",
"repositoryConnector": "WebCrawler",
"outputConnector": "PGVector_Output",
"path": "https://wiki.corp.internal/",
"crawlSpec": {
"maxDepth": 5,
"maxPages": 10000,
"allowPrivateNetworks": true,
"privateAllowlist": ["wiki.corp.internal", "10.50.0.0/16"],
"aclMode": "STATIC",
"aclIdentity": "group:engineering-staff",
"maxThreads": 8
}
}
Experience In-Process Web Ingestion Today
Try the Web Repository Connector in the live browser simulator, or read the complete architectural guide on our Wiki.