mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-10-06 07:32:38 +02:00
Compare commits
5 Commits
deploy-025
...
deploy-025
Author | SHA1 | Date | |
---|---|---|---|
|
fd32ae9fa7 | ||
|
470651ea4c | ||
|
8d4829e783 | ||
|
1290bc15dc | ||
|
e7fa558954 |
@@ -112,7 +112,7 @@ public class HttpClientProvider implements Provider<HttpClient> {
|
||||
});
|
||||
|
||||
final RequestConfig defaultRequestConfig = RequestConfig.custom()
|
||||
.setCookieSpec(StandardCookieSpec.RELAXED)
|
||||
.setCookieSpec(StandardCookieSpec.IGNORE)
|
||||
.setResponseTimeout(10, TimeUnit.SECONDS)
|
||||
.setConnectionRequestTimeout(5, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@@ -23,7 +24,8 @@ public class RetryStrategy implements HttpRequestRetryStrategy {
|
||||
case SocketTimeoutException ste -> false;
|
||||
case SSLException ssle -> false;
|
||||
case UnknownHostException uhe -> false;
|
||||
case HttpHostConnectException ex -> executionCount <= 2; // Only retry once for connection errors
|
||||
case HttpHostConnectException ex -> executionCount < 2;
|
||||
case SocketException ex -> executionCount < 2;
|
||||
default -> executionCount <= 3;
|
||||
};
|
||||
}
|
||||
|
@@ -18,6 +18,9 @@ import java.util.*;
|
||||
* and diagnosing servers!
|
||||
*/
|
||||
public class CertificateValidator {
|
||||
// If true, will attempt to fetch missing intermediate certificates via AIA urls.
|
||||
private static final boolean TRY_FETCH_MISSING_CERTS = false;
|
||||
|
||||
public static class ValidationResult {
|
||||
public boolean chainValid = false;
|
||||
public boolean certificateExpired = false;
|
||||
@@ -91,13 +94,15 @@ public class CertificateValidator {
|
||||
// 2. Check hostname validity
|
||||
result.hostnameValid = checkHostname(leafCert, hostname, result);
|
||||
|
||||
// 3. Not really checking if it's self-signed, but if the chain is incomplete (and likely self-signed)
|
||||
result.selfSigned = certChain.length <= 1;
|
||||
|
||||
// 3. Check certificate chain validity (with AIA fetching)
|
||||
// 4. Check certificate chain validity (optionally with AIA fetching)
|
||||
result.chainValid = checkChainValidity(certChain, RootCerts.getTrustAnchors(), result, autoTrustFetchedRoots);
|
||||
|
||||
// 4. Check revocation status
|
||||
result.certificateRevoked = checkRevocation(leafCert, result);
|
||||
// 5. Check revocation status
|
||||
result.certificateRevoked = false; // not implemented
|
||||
// checkRevocation(leafCert, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -177,6 +182,13 @@ public class CertificateValidator {
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (!TRY_FETCH_MISSING_CERTS) {
|
||||
result.errors.addAll(originalResult.issues);
|
||||
result.details.put("chainLength", originalChain.length);
|
||||
result.details.put("chainExtended", false);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
List<X509Certificate> repairedChain = CertificateFetcher.buildCompleteChain(originalChain[0]);
|
||||
|
||||
|
@@ -22,6 +22,7 @@ import nu.marginalia.search.model.NavbarModel;
|
||||
import nu.marginalia.search.model.ResultsPage;
|
||||
import nu.marginalia.search.model.UrlDetails;
|
||||
import nu.marginalia.search.svc.SearchFlagSiteService.FlagSiteFormData;
|
||||
import nu.marginalia.service.server.RateLimiter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -47,6 +48,8 @@ public class SearchSiteInfoService {
|
||||
private final HikariDataSource dataSource;
|
||||
private final SearchSiteSubscriptionService searchSiteSubscriptions;
|
||||
|
||||
private final RateLimiter rateLimiter = RateLimiter.custom(60);
|
||||
|
||||
@Inject
|
||||
public SearchSiteInfoService(SearchOperator searchOperator,
|
||||
DomainInfoClient domainInfoClient,
|
||||
@@ -144,6 +147,10 @@ public class SearchSiteInfoService {
|
||||
return new MapModelAndView("redirect.jte", Map.of("url", "/site"));
|
||||
}
|
||||
|
||||
if (!rateLimiter.isAllowed()) {
|
||||
return new MapModelAndView("unavailable.jte", Map.of("message", "Due to aggressive bot scraping, this feature is temporarily unavailable. Please try again later."));
|
||||
}
|
||||
|
||||
page = Objects.requireNonNullElse(page, 1);
|
||||
view = Objects.requireNonNullElse(view, "info");
|
||||
|
||||
|
@@ -0,0 +1,11 @@
|
||||
@param String message
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta charset="UTF-8">
|
||||
<title>Unavailable</title></head>
|
||||
<body>
|
||||
<h1>Service Overloaded</h1>
|
||||
<p>${message}</p>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user