/** * Responsible for logging server errors. * <p> * The base implementation uses a SLF4J Logger. If a special annotation is desired for internal server errors, you may want to use SLF4J directly with the Marker API to distinguish server errors from application errors. * <p> * This can also be overridden to add additional logging information, eg. the id of the authenticated user. * * @param request The request that triggered the server error. * @param usefulException The server error. */ protected void logServerError(RequestHeader request, UsefulException usefulException) { logger.error(String.format("\n\n! @%s - Internal server error, for (%s) [%s] ->\n", usefulException.id, request.method(), request.uri()), usefulException ); }
/** * Invoked when a client error occurs, that is, an error in the 4xx series, which is not handled * by any of the other methods in this class already. * * The base implementation uses {@code views.html.defaultpages.badRequest} template with the given status. * * @param request The request that caused the client error. * @param statusCode The error status code. Must be greater or equal to 400, and less than 500. * @param message The error message. * @return a CompletionStage containing the Result. */ protected CompletionStage<Result> onOtherClientError(RequestHeader request, int statusCode, String message) { return CompletableFuture.completedFuture(Results.status(statusCode, views.html.defaultpages.badRequest.render( request.method(), request.uri(), message, request.asScala() ))); }
/** * The transient language will be taken into account when using {@link MessagesApi#preferred(RequestHeader)}} (It will take precedence over any other language). * * @return The current transient language of this request. */ default Optional<Lang> transientLang() { return attrs().getOptional(Messages.Attrs.CurrentLang).map(play.api.i18n.Lang::asJava); }
/** * Defer execution until a later point. * * @param request the request * @param action the action to defer */ protected Http.RequestHeader defer(final Http.RequestHeader request, final AbstractDeadboltAction<T> action) { if (action != null) { LOGGER.info("Deferring action [{}]", this.getClass().getName()); return request.addAttr(ACTION_DEFERRED, action); } return request; }
@Override public Accumulator<ByteString, Result> apply(final Http.RequestHeader requestHeader) { return state.getServletContext().findMatchingServlet(requestHeader).map(servlet -> { final long length = requestHeader.getHeaders().get("Content-Length").map(Long::parseLong) .orElse(Long.MAX_VALUE); final BodyParser.Bytes slurper = new BodyParser.Bytes(length, state.getHttpErrorHandler()); return slurper.apply(requestHeader).mapFuture( resultOrBytes -> resultOrBytes.left.map(CompletableFuture::completedFuture).orElseGet(() -> { return state.getServletContext() .executeInvoke(servlet, requestHeader, resultOrBytes.right.get().iterator().asInputStream(), servlet.getServletPath()) .toCompletableFuture(); }), state.getServletContext().getDefaultExecutor()); }).orElseGet(() -> next.apply(requestHeader)); } };
/** * Get the deferred action from the request. * * @param request the request * @return a tuple containing the deferred action (or null if it doesn't exist) and the cleaned up request you should pass on */ @SuppressWarnings("unchecked") public F.Tuple<AbstractDeadboltAction<?>, Http.RequestHeader> getDeferredAction(final Http.RequestHeader request) { return request.attrs().getOptional(ACTION_DEFERRED).map(action -> { action.delegate = this; return F.<AbstractDeadboltAction<?>, Http.RequestHeader>Tuple(action, request.removeAttr(ACTION_DEFERRED).addAttr(IGNORE_DEFERRED_FLAG, true)); }).orElseGet(() -> F.Tuple(null, request)); }
/** * Get the deferred action from the request. * * @param request the request * @return a tuple containing the deferred action (or null if it doesn't exist) and the cleaned up request you should pass on */ @SuppressWarnings("unchecked") public F.Tuple<AbstractDeadboltAction<?>, Http.RequestHeader> getDeferredAction(final Http.RequestHeader request) { return request.attrs().getOptional(ACTION_DEFERRED).map(action -> { action.delegate = this; return F.<AbstractDeadboltAction<?>, Http.RequestHeader>Tuple(action, request.removeAttr(ACTION_DEFERRED).addAttr(IGNORE_DEFERRED_FLAG, true)); }).orElseGet(() -> F.Tuple(null, request)); }
@Override public String getContentType() { return playDelegate.contentType().orElse(null); }
@Override public Enumeration<String> getHeaders(final String name) { return enumeration(playDelegate.getHeaders().getAll(name)); }
@Override public Enumeration<String> getHeaderNames() { return enumeration(playDelegate.getHeaders().toMap().keySet()); }
@Override public String getParameter(final String name) { return ofNullable(playDelegate.getQueryString(name)).orElseGet(() -> playDelegate.contentType() .filter("multipart/form-data"::equalsIgnoreCase).map(ct -> params.get(name)).orElse(null)); }
public F.Promise<Result> onHandlerNotFound(Http.RequestHeader request) { ErrorResponse er = apply(NOT_FOUND, "URI not found", apply$default$3(), Some.apply(request.path())); return F.Promise.pure(notFound(toJson(er))); }
/** * Marks the current action as authorised. This allows method-level annotations to override controller-level annotations. * * @param request the request */ private Http.RequestHeader markAsAuthorised(final Http.RequestHeader request) { this.authorised = true; return request.addAttr(ACTION_AUTHORISED, true); }
@Override public String getCharacterEncoding() { return playDelegate.charset().orElseGet(() -> ofNullable(RequestAdapter.getCharsetFromContentType(getContentType())) .orElse(getServletContext().getRequestCharacterEncoding())); }
/** * Checks if an action is authorised. This allows controller-level annotations to cede control to method-level annotations. * * @param request the request * @return true if a more-specific annotation has authorised access, otherwise false */ protected static boolean isAuthorised(final Http.RequestHeader request) { return request.attrs().getOptional(ACTION_AUTHORISED).orElse(false); }
@Override public Map<String, String[]> getParameterMap() { final Stream<Map.Entry<String, String[]>> query = playDelegate.queryString().entrySet().stream(); final Stream<AbstractMap.SimpleEntry<String, String[]>> form = playDelegate.contentType() .filter("multipart/form-data"::equalsIgnoreCase) .map(ct -> params.entrySet().stream() .map(v -> new AbstractMap.SimpleEntry<>(v.getKey(), new String[] { v.getValue() }))) .orElseGet(Stream::empty); return Stream.concat(query, form).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (first, second) -> first)); }
@Override public Enumeration<String> getParameterNames() { return enumeration(Stream.concat(playDelegate.queryString().keySet().stream(), playDelegate.contentType() .filter("multipart/form-data"::equalsIgnoreCase).map(ct -> params.keySet().stream()).orElseGet(Stream::empty)) .collect(toSet())); }
/** * Check if there is a deferred action in the request. * * @param request the request * @return true if there is a deferred action in the request */ public boolean isDeferred(final Http.RequestHeader request) { return request.attrs().containsKey(ACTION_DEFERRED); }
@Override public String getHeader(final String name) { final List<String> option = playDelegate.getHeaders().getAll(name); return option != null && !option.isEmpty() ? option.iterator().next() : null; }
/** * Checks if an action is authorised. This allows controller-level annotations to cede control to method-level annotations. * * @param request the request * @return true if a more-specific annotation has authorised access, otherwise false */ protected static boolean isAuthorised(final Http.RequestHeader request) { return request.attrs().getOptional(ACTION_AUTHORISED).orElse(false); }