private void verifyRequestWithExpectContinueFlagHas100continueHeader(final HttpRequest request) { if (request instanceof HttpEntityEnclosingRequest) { if (((HttpEntityEnclosingRequest) request).expectContinue() && ((HttpEntityEnclosingRequest) request).getEntity() != null) { add100ContinueHeaderIfMissing(request); } else { remove100ContinueHeaderIfExists(request); } } else { remove100ContinueHeaderIfExists(request); } }
private void verifyOPTIONSRequestWithBodyHasContentType(final HttpRequest request) { if (!HeaderConstants.OPTIONS_METHOD.equals(request.getRequestLine().getMethod())) { return; } if (!(request instanceof HttpEntityEnclosingRequest)) { return; } addContentTypeHeaderIfMissing((HttpEntityEnclosingRequest) request); }
/** * If the {@link HttpRequest} is non-compliant but 'fixable' we go ahead and * fix the request here. Returning the updated one. * * @param request the request to check for compliance * @return the updated request * @throws ClientProtocolException when we have trouble making the request compliant */ public HttpRequest makeRequestCompliant(HttpRequest request) throws ClientProtocolException { if (requestMustNotHaveEntity(request)) { ((HttpEntityEnclosingRequest) request).setEntity(null); } verifyRequestWithExpectContinueFlagHas100continueHeader(request); verifyOPTIONSRequestWithBodyHasContentType(request); decrementOPTIONSMaxForwardsIfGreaterThen0(request); stripOtherFreshnessDirectivesWithNoCache(request); if (requestVersionIsTooLow(request)) { return upgradeRequestTo(request, HttpVersion.HTTP_1_1); } if (requestMinorVersionIsTooHighMajorVersionsMatch(request)) { return downgradeRequestTo(request, HttpVersion.HTTP_1_1); } return request; }
private HttpResponse getFatallyNoncompliantResponse(final HttpRequestWrapper request, final HttpContext context) { HttpResponse fatalErrorResponse = null; final List<RequestProtocolError> fatalError = requestCompliance.requestIsFatallyNonCompliant(request); for (final RequestProtocolError error : fatalError) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); fatalErrorResponse = requestCompliance.getErrorForRequest(error); } return fatalErrorResponse; }
/** * If the {@link HttpRequest} is non-compliant but 'fixable' we go ahead and * fix the request here. * * @param request the request to check for compliance * @throws ClientProtocolException when we have trouble making the request compliant */ public void makeRequestCompliant(final HttpRequestWrapper request) throws ClientProtocolException { if (requestMustNotHaveEntity(request)) { ((HttpEntityEnclosingRequest) request).setEntity(null); } verifyRequestWithExpectContinueFlagHas100continueHeader(request); verifyOPTIONSRequestWithBodyHasContentType(request); decrementOPTIONSMaxForwardsIfGreaterThen0(request); stripOtherFreshnessDirectivesWithNoCache(request); if (requestVersionIsTooLow(request) || requestMinorVersionIsTooHighMajorVersionsMatch(request)) { request.setProtocolVersion(HttpVersion.HTTP_1_1); } }
/** * Test to see if the {@link HttpRequest} is HTTP1.1 compliant or not * and if not, we can not continue. * * @param request the HttpRequest Object * @return list of {@link RequestProtocolError} */ public List<RequestProtocolError> requestIsFatallyNonCompliant(HttpRequest request) { List<RequestProtocolError> theErrors = new ArrayList<RequestProtocolError>(); RequestProtocolError anError = requestHasWeakETagAndRange(request); if (anError != null) { theErrors.add(anError); } anError = requestHasWeekETagForPUTOrDELETEIfMatch(request); if (anError != null) { theErrors.add(anError); } anError = requestContainsNoCacheDirectiveWithFieldName(request); if (anError != null) { theErrors.add(anError); } return theErrors; }
CachingHttpClient( HttpClient client, HttpCache cache, CacheConfig config) { super(); if (client == null) { throw new IllegalArgumentException("HttpClient may not be null"); } if (cache == null) { throw new IllegalArgumentException("HttpCache may not be null"); } if (config == null) { throw new IllegalArgumentException("CacheConfig may not be null"); } this.maxObjectSizeBytes = config.getMaxObjectSize(); this.sharedCache = config.isSharedCache(); this.backend = client; this.responseCache = cache; this.validityPolicy = new CacheValidityPolicy(); this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes, sharedCache); this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); this.cacheableRequestPolicy = new CacheableRequestPolicy(); this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, config); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); this.requestCompliance = new RequestProtocolCompliance(); this.asynchRevalidator = makeAsynchronousValidator(config); }
requestCompliance.makeRequestCompliant(request); request.addHeader("Via",via);
private void stripOtherFreshnessDirectivesWithNoCache(final HttpRequest request) { final List<HeaderElement> outElts = new ArrayList<HeaderElement>(); boolean shouldStrip = false; for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (!disallowedWithNoCache.contains(elt.getName())) { outElts.add(elt); } if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elt.getName())) { shouldStrip = true; } } } if (!shouldStrip) { return; } request.removeHeaders(HeaderConstants.CACHE_CONTROL); request.setHeader(HeaderConstants.CACHE_CONTROL, buildHeaderFromElements(outElts)); }
/** * Test to see if the {@link HttpRequest} is HTTP1.1 compliant or not * and if not, we can not continue. * * @param request the HttpRequest Object * @return list of {@link RequestProtocolError} */ public List<RequestProtocolError> requestIsFatallyNonCompliant(final HttpRequest request) { final List<RequestProtocolError> theErrors = new ArrayList<RequestProtocolError>(); RequestProtocolError anError = requestHasWeakETagAndRange(request); if (anError != null) { theErrors.add(anError); } if (!weakETagOnPutDeleteAllowed) { anError = requestHasWeekETagForPUTOrDELETEIfMatch(request); if (anError != null) { theErrors.add(anError); } } anError = requestContainsNoCacheDirectiveWithFieldName(request); if (anError != null) { theErrors.add(anError); } return theErrors; }
private HttpResponse getFatallyNoncompliantResponse( final HttpRequestWrapper request, final HttpContext context) { HttpResponse fatalErrorResponse = null; final List<RequestProtocolError> fatalError = requestCompliance.requestIsFatallyNonCompliant(request); for (final RequestProtocolError error : fatalError) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); fatalErrorResponse = requestCompliance.getErrorForRequest(error); } return fatalErrorResponse; }
public CachingExec( final ClientExecChain backend, final HttpCache cache, final CacheConfig config, final AsynchronousValidator asynchRevalidator) { super(); Args.notNull(backend, "HTTP backend"); Args.notNull(cache, "HttpCache"); this.cacheConfig = config != null ? config : CacheConfig.DEFAULT; this.backend = backend; this.responseCache = cache; this.validityPolicy = new CacheValidityPolicy(); this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); this.cacheableRequestPolicy = new CacheableRequestPolicy(); this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, this.cacheConfig); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); this.requestCompliance = new RequestProtocolCompliance(this.cacheConfig.isWeakETagOnPutDeleteAllowed()); this.responseCachingPolicy = new ResponseCachingPolicy( this.cacheConfig.getMaxObjectSize(), this.cacheConfig.isSharedCache(), this.cacheConfig.isNeverCacheHTTP10ResponsesWithQuery(), this.cacheConfig.is303CachingEnabled()); this.asynchRevalidator = asynchRevalidator; }
requestCompliance.makeRequestCompliant(request); request.addHeader("Via",via);
private void stripOtherFreshnessDirectivesWithNoCache(HttpRequest request) { List<HeaderElement> outElts = new ArrayList<HeaderElement>(); boolean shouldStrip = false; for(Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(HeaderElement elt : h.getElements()) { if (!disallowedWithNoCache.contains(elt.getName())) { outElts.add(elt); } if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elt.getName())) { shouldStrip = true; } } } if (!shouldStrip) return; request.removeHeaders(HeaderConstants.CACHE_CONTROL); request.setHeader(HeaderConstants.CACHE_CONTROL, buildHeaderFromElements(outElts)); }
private HttpResponse getFatallyNoncompliantResponse(HttpRequest request, HttpContext context) { HttpResponse fatalErrorResponse = null; List<RequestProtocolError> fatalError = requestCompliance.requestIsFatallyNonCompliant(request); for (RequestProtocolError error : fatalError) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); fatalErrorResponse = requestCompliance.getErrorForRequest(error); } return fatalErrorResponse; }
private void verifyRequestWithExpectContinueFlagHas100continueHeader(HttpRequest request) { if (request instanceof HttpEntityEnclosingRequest) { if (((HttpEntityEnclosingRequest) request).expectContinue() && ((HttpEntityEnclosingRequest) request).getEntity() != null) { add100ContinueHeaderIfMissing(request); } else { remove100ContinueHeaderIfExists(request); } } else { remove100ContinueHeaderIfExists(request); } }
CachingHttpClient( final HttpClient client, final HttpCache cache, final CacheConfig config) { super(); Args.notNull(client, "HttpClient"); Args.notNull(cache, "HttpCache"); Args.notNull(config, "CacheConfig"); this.maxObjectSizeBytes = config.getMaxObjectSize(); this.sharedCache = config.isSharedCache(); this.backend = client; this.responseCache = cache; this.validityPolicy = new CacheValidityPolicy(); this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes, sharedCache, config.isNeverCacheHTTP10ResponsesWithQuery(), config.is303CachingEnabled()); this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); this.cacheableRequestPolicy = new CacheableRequestPolicy(); this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, config); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); this.requestCompliance = new RequestProtocolCompliance(config.isWeakETagOnPutDeleteAllowed()); this.asynchRevalidator = makeAsynchronousValidator(config); }
public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException { // default response context setResponseStatus(context, CacheResponseStatus.CACHE_MISS); String via = generateViaHeader(request); if (clientRequestsOurOptions(request)) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return new OptionsHttp11Response(); } HttpResponse fatalErrorResponse = getFatallyNoncompliantResponse( request, context); if (fatalErrorResponse != null) return fatalErrorResponse; request = requestCompliance.makeRequestCompliant(request); request.addHeader("Via",via); flushEntriesInvalidatedByRequest(target, request); if (!cacheableRequestPolicy.isServableFromCache(request)) { return callBackend(target, request, context); } HttpCacheEntry entry = satisfyFromCache(target, request); if (entry == null) { return handleCacheMiss(target, request, context); } return handleCacheHit(target, request, context, entry); }
private void verifyOPTIONSRequestWithBodyHasContentType(HttpRequest request) { if (!HeaderConstants.OPTIONS_METHOD.equals(request.getRequestLine().getMethod())) { return; } if (!(request instanceof HttpEntityEnclosingRequest)) { return; } addContentTypeHeaderIfMissing((HttpEntityEnclosingRequest) request); }