private void describeLimitsForRequest( HttpServletRequest request, FilterDirector director, MediaType preferredMediaType) { if (preferredMediaType.getMimeType() == MimeType.UNKNOWN) { director.setFilterAction(FilterAction.RETURN); director.setResponseStatus(HttpStatusCode.NOT_ACCEPTABLE); } else { // If include absolute limits let request pass thru but prepare the combined // (absolute and active) limits when processing the response if (includeAbsoluteLimits) { director.setFilterAction(FilterAction.PROCESS_RESPONSE); director .requestHeaderManager() .putHeader(CommonHttpHeader.ACCEPT.toString(), MimeType.APPLICATION_XML.toString()); } else { try { final MimeType mimeType = rateLimitingServiceHelper.queryActiveLimits( request, preferredMediaType, director.getResponseOutputStream()); director .responseHeaderManager() .putHeader(CommonHttpHeader.CONTENT_TYPE.toString(), mimeType.toString()); director.setFilterAction(FilterAction.RETURN); director.setResponseStatus(HttpStatusCode.OK); } catch (Exception e) { consumeException(e, director); } } } }
@Override public FilterDirector handleRequest( HttpServletRequest httpRequest, ReadableHttpServletResponse httpResponse) { MutableHttpServletRequest request = MutableHttpServletRequest.wrap(httpRequest); MutableHttpServletResponse response = MutableHttpServletResponse.wrap(httpRequest, httpResponse); FilterDirector filterDirector = new FilterDirectorImpl(); MediaType contentType = getContentType(request.getHeaderValue("content-type")); List<MediaType> acceptValues = getAcceptValues(request.getPreferredHeaders("Accept", DEFAULT_TYPE)); List<XmlChainPool> pools = getHandlerChainPool(request.getMethod(), contentType, acceptValues, "", requestProcessors); if (pools.isEmpty()) { filterDirector.setFilterAction(FilterAction.PROCESS_RESPONSE); return filterDirector; } try { ServletInputStream in = request.getInputStream(); TranslationResult result = null; for (XmlChainPool pool : pools) { final ByteBuffer internalBuffer = new CyclicByteBuffer(DEFAULT_BUFFER_SIZE, true); result = pool.executePool( new TranslationPreProcessor(in, contentType, true).getBodyStream(), new ByteBufferServletOutputStream(internalBuffer), getInputParameters(TranslationType.REQUEST, request, response, result)); if (result.isSuccess()) { in = new ByteBufferInputStream(internalBuffer); request.setInputStream(in); result.applyResults(filterDirector); if (StringUtilities.isNotBlank(pool.getResultContentType())) { filterDirector .requestHeaderManager() .putHeader("content-type", pool.getResultContentType()); contentType = getContentType(pool.getResultContentType()); } filterDirector.setFilterAction(FilterAction.PROCESS_RESPONSE); } else { filterDirector.setResponseStatus(HttpStatusCode.BAD_REQUEST); filterDirector.setFilterAction(FilterAction.RETURN); break; } } } catch (IOException ex) { LOG.error("Error executing request transformer chain", ex); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); filterDirector.setFilterAction(FilterAction.RETURN); } return filterDirector; }
@Override public FilterDirector handleRequest( HttpServletRequest request, ReadableHttpServletResponse response) { FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setFilterAction(FilterAction.PROCESS_RESPONSE); return filterDirector; }
@Override public FilterDirector handleRequest( HttpServletRequest request, ReadableHttpServletResponse response) { FilterDirector director = new FilterDirectorImpl(); director.setFilterAction(FilterAction.PASS); if (CacheRequest.isCacheRequest(request)) { if (isAllowed(request)) { director = performCacheRequest(request); } else { director.setResponseStatus(HttpStatusCode.FORBIDDEN); director.setFilterAction(FilterAction.RETURN); } } return director; }
@Override public FilterDirector handleRequest( HttpServletRequest request, ReadableHttpServletResponse response) { FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setResponseStatus(HttpStatusCode.UNAUTHORIZED); filterDirector.setFilterAction(FilterAction.RETURN); final String uri = request.getRequestURI(); LOG.debug("Uri is " + uri); if (uriMatcher.isUriOnWhiteList(uri)) { filterDirector.setFilterAction(FilterAction.PASS); LOG.debug("Uri is on whitelist! Letting request pass through."); } else { filterDirector = this.authenticate(request); } return filterDirector; }
public void onCacheDelete(HttpServletRequest request, final FilterDirector director) throws DatastoreOperationException, MalformedCacheRequestException { final CacheRequest cacheDelete = CacheRequest.marshallCacheRequest(request); hashRingDatastore.remove( cacheDelete.getCacheKey(), encodingProvider.decode(cacheDelete.getCacheKey()), cacheDelete.getRequestedRemoteBehavior()); director.setResponseStatus(HttpStatusCode.ACCEPTED); director.setFilterAction(FilterAction.RETURN); }
@Override public FilterDirector handleRequest( HttpServletRequest request, ReadableHttpServletResponse response) { final FilterDirector director = new FilterDirectorImpl(); MutableHttpServletRequest mutableRequest = MutableHttpServletRequest.wrap(request); MediaRangeProcessor processor = new MediaRangeProcessor( mutableRequest.getPreferredHeaders(CommonHttpHeader.ACCEPT.toString(), DEFAULT_TYPE)); List<MediaType> mediaTypes = processor.process(); if (requestHasExpectedHeaders(request)) { originalPreferredAccept = getPreferredMediaType(mediaTypes); MediaType preferredMediaType = originalPreferredAccept; final String requestUri = request.getRequestURI(); // request now considered valid with user. director.setFilterAction(FilterAction.PASS); // Record limits final boolean pass = recordLimitedRequest(request, director); // Does the request match the configured getCurrentLimits API call endpoint? if (pass && describeLimitsUriPattern.matcher(requestUri).matches()) { describeLimitsForRequest(request, director, preferredMediaType); } } else { LOG.warn( "Expected header: " + PowerApiHeader.USER.toString() + " was not supplied in the request. Rate limiting requires this header to operate."); // Auto return a 401 if the request does not meet expectations director.setResponseStatus(HttpStatusCode.UNAUTHORIZED); director.setFilterAction(FilterAction.RETURN); } return director; }
@Override public FilterDirector handleResponse( HttpServletRequest request, ReadableHttpServletResponse response) { FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setResponseStatusCode(response.getStatus()); filterDirector.setFilterAction(FilterAction.PASS); for (HttpLoggerWrapper loggerWrapper : loggers) { loggerWrapper.handle(request, response); } return filterDirector; }
private FilterDirector authenticate(HttpServletRequest request) { final FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setResponseStatus(HttpStatusCode.UNAUTHORIZED); filterDirector.setFilterAction(FilterAction.RETURN); final String authToken = request.getHeader(CommonHttpHeader.AUTH_TOKEN.toString()); ExtractorResult<String> account = null; AuthToken token = null; if (tenanted) { account = extractAccountIdentification(request); } final boolean allow = allowAccount(account); if ((!StringUtilities.isBlank(authToken) && allow)) { token = checkToken(account, authToken); if (token == null) { try { token = validateToken(account, StringUriUtilities.encodeUri(authToken)); cacheUserInfo(token); } catch (ClientHandlerException ex) { LOG.error("Failure communicating with the auth service: " + ex.getMessage(), ex); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } catch (AuthServiceException ex) { LOG.error("Failure in Auth-N: " + ex.getMessage()); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } catch (IllegalArgumentException ex) { LOG.error("Failure in Auth-N: " + ex.getMessage()); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } catch (Exception ex) { LOG.error("Failure in auth: " + ex.getMessage(), ex); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } } } List<AuthGroup> groups = getAuthGroups(token); setFilterDirectorValues( authToken, token, delegable, filterDirector, account == null ? "" : account.getResult(), groups); return filterDirector; }
public void onCachePut(HttpServletRequest request, final FilterDirector director) throws MalformedCacheRequestException, DatastoreOperationException { final CacheRequest cachePut = CacheRequest.marshallCachePutRequest(request); hashRingDatastore.put( cachePut.getCacheKey(), encodingProvider.decode(cachePut.getCacheKey()), cachePut.getPayload(), cachePut.getTtlInSeconds(), TimeUnit.SECONDS, cachePut.getRequestedRemoteBehavior()); director.setResponseStatus(HttpStatusCode.ACCEPTED); director.setFilterAction(FilterAction.RETURN); }
/** @return false if over-limit and response delegation is not enabled */ private boolean recordLimitedRequest(HttpServletRequest request, FilterDirector director) { boolean pass = true; try { rateLimitingServiceHelper.trackLimits(request); } catch (OverLimitException e) { new LimitLogger(e.getUser(), request) .log(e.getConfiguredLimit(), Integer.toString(e.getCurrentLimitAmount())); final HttpDate nextAvailableTime = new HttpDate(e.getNextAvailableTime()); // Tell the filter we want to return right away director.setFilterAction(FilterAction.RETURN); pass = false; // We use a 413 "Request Entity Too Large" to communicate that the user // in question has hit their rate limit for this requested URI if (overLimit429ResponseCode) { director.setResponseStatus(HttpStatusCode.TOO_MANY_REQUESTS); } else { director.setResponseStatus(HttpStatusCode.REQUEST_ENTITY_TOO_LARGE); } director .responseHeaderManager() .appendHeader(CommonHttpHeader.RETRY_AFTER.toString(), nextAvailableTime.toRFC1123()); } catch (CacheException e) { LOG.error("Failure when tracking limits. Reason: " + e.getMessage(), e); director.setFilterAction(FilterAction.RETURN); director.setResponseStatus(HttpStatusCode.BAD_GATEWAY); } return pass; }
public FilterDirector performCacheRequest(HttpServletRequest request) { final FilterDirector director = new FilterDirectorImpl(); // Defaults to return not-implemented director.setResponseStatus(HttpStatusCode.NOT_IMPLEMENTED); director.setFilterAction(FilterAction.RETURN); try { final String requestMethod = request.getMethod(); if ("GET".equalsIgnoreCase(requestMethod)) { onCacheGet(CacheRequest.marshallCacheRequest(request), director); } else if ("PUT".equalsIgnoreCase(requestMethod)) { onCachePut(request, director); } else if ("DELETE".equalsIgnoreCase(requestMethod)) { onCacheDelete(request, director); } } catch (MalformedCacheRequestException mcre) { LOG.error( "The request to interact with the cache is malformed: " + request.getMethod() + " Reason: " + mcre.getMessage(), mcre); director.getResponseWriter().write(mcre.getMessage() == null ? "" : mcre.getMessage()); director.setResponseStatus(HttpStatusCode.BAD_REQUEST); director.setFilterAction(FilterAction.RETURN); } catch (Exception ex) { LOG.error(ex.getMessage(), ex); director.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); director.setFilterAction(FilterAction.RETURN); } return director; }
public void onCacheGet(CacheRequest cacheGet, FilterDirector director) { final StoredElement element = hashRingDatastore.get( cacheGet.getCacheKey(), encodingProvider.decode(cacheGet.getCacheKey()), cacheGet.getRequestedRemoteBehavior()); if (!element.elementIsNull()) { try { director.getResponseOutputStream().write(element.elementBytes()); director.setResponseStatus(HttpStatusCode.OK); director.setFilterAction(FilterAction.RETURN); } catch (IOException ioe) { LOG.error(ioe.getMessage(), ioe); director.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); director.setFilterAction(FilterAction.RETURN); } } else { director.setResponseStatus(HttpStatusCode.NOT_FOUND); director.setFilterAction(FilterAction.RETURN); } }
@Override public FilterDirector authenticate(HttpServletRequest request) { final FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setResponseStatus(HttpStatusCode.UNAUTHORIZED); filterDirector.setFilterAction(FilterAction.RETURN); final String authToken = request.getHeader(CommonHttpHeader.AUTH_TOKEN.toString()); final ExtractorResult<Object> account = keyedRegexExtractor.extract(request.getRequestURI()); CachableUserInfo user = null; if ((!StringUtilities.isBlank(authToken) && account != null)) { user = checkUserCache(account.getResult(), authToken); if (user == null) { try { user = authenticationService.validateToken(account.getResult(), authToken); cacheUserInfo(user); } catch (Exception ex) { LOG.error("Failure in auth: " + ex.getMessage(), ex); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } } } Groups groups = null; if (user != null) { groups = authenticationService.getGroups(user.getUserId()); } final AuthenticationHeaderManager headerManager = new AuthenticationHeaderManager( authToken, user, delegatable, filterDirector, account == null ? "" : account.getResult(), groups, request); headerManager.setFilterDirectorValues(); return filterDirector; }
private void consumeException(Exception e, FilterDirector director) { LOG.error("Failure when querying limits. Reason: " + e.getMessage(), e); director.setFilterAction(FilterAction.RETURN); director.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); }
@Override public FilterDirector handleResponse( HttpServletRequest httpRequest, ReadableHttpServletResponse httpResponse) { MutableHttpServletRequest request = MutableHttpServletRequest.wrap(httpRequest); MutableHttpServletResponse response = MutableHttpServletResponse.wrap(httpRequest, httpResponse); final FilterDirector filterDirector = new FilterDirectorImpl(); filterDirector.setFilterAction(FilterAction.PASS); MediaType contentType = getContentType(response.getHeaderValue("Content-Type")); List<MediaType> acceptValues = getAcceptValues(request.getPreferredHeaders("Accept", DEFAULT_TYPE)); List<XmlChainPool> pools = getHandlerChainPool( "", contentType, acceptValues, String.valueOf(response.getStatus()), responseProcessors); if (pools.isEmpty()) { filterDirector.setResponseStatusCode(response.getStatus()); return filterDirector; } try { filterDirector.setResponseStatusCode(response.getStatus()); if (response.hasBody()) { InputStream in = response.getBufferedOutputAsInputStream(); TranslationResult result = null; for (XmlChainPool pool : pools) { if (in.available() > 0) { result = pool.executePool( new TranslationPreProcessor(in, contentType, true).getBodyStream(), filterDirector.getResponseOutputStream(), getInputParameters(TranslationType.RESPONSE, request, response, result)); if (result.isSuccess()) { result.applyResults(filterDirector); if (StringUtilities.isNotBlank(pool.getResultContentType())) { filterDirector .requestHeaderManager() .putHeader("content-type", pool.getResultContentType()); contentType = getContentType(pool.getResultContentType()); } in = new ByteArrayInputStream(filterDirector.getResponseMessageBodyBytes()); } else { filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); response.setContentLength(0); filterDirector.responseHeaderManager().removeHeader("Content-Length"); break; } } } } } catch (IOException ex) { LOG.error("Error executing response transformer chain", ex); filterDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); response.setContentLength(0); } return filterDirector; }