@Override public HttpStatus handle(Channel ctx, boolean isKeepAlive, Req req) { if (!HttpUtils.isGetReq(req)) return HttpStatus.NOT_FOUND; try { String[] staticFilesLocations = customization.staticFilesPath(); if (!U.isEmpty(staticFilesLocations)) { Res res = HttpUtils.staticResource(req, staticFilesLocations); if (res != null) { StaticFilesSecurity staticFilesSecurity = customization.staticFilesSecurity(); if (staticFilesSecurity.canServe(req, res)) { byte[] bytes = res.getBytesOrNull(); if (bytes != null) { MediaType contentType = U.or(MediaType.getByFileName(res.getName()), MediaType.BINARY); HttpIO.INSTANCE.write200(HttpUtils.maybe(req), ctx, isKeepAlive, contentType, bytes); return HttpStatus.DONE; } } } } return HttpStatus.NOT_FOUND; } catch (Exception e) { return HttpIO.INSTANCE.errorAndDone(req, e, LogLevel.ERROR); } }
public static String getContextPath(Req req) { return zone(req).entry("contextPath").or(""); }
@Override public void logout() { HttpUtils.clearUserData(request()); HttpUtils.setResponseTokenCookie(this, ""); req.tokenChanged.set(true); }
private Object renderError(Req req, Resp resp, Throwable error) { if (resp.contentType() == MediaType.JSON) { return HttpUtils.getErrorInfo(resp, error); } else if (resp.contentType() == MediaType.PLAIN_TEXT_UTF_8) { return HttpUtils.getErrorMessageAndSetCode(resp, error); } else { return page(req, resp, error); } }
private void internalServerError(final Channel channel, final boolean isKeepAlive, final Req req) { MediaType contentType = req != null ? req.contentType() : HttpUtils.getDefaultContentType(); HttpResponseRenderer jsonRenderer = Customization.of(req).jsonResponseRenderer(); RespBody body = new RespBodyBytes(HttpUtils.responseToBytes(req, INTERNAL_SERVER_ERROR, contentType, jsonRenderer)); HttpIO.INSTANCE.respond(HttpUtils.maybe(req), channel, -1, -1, 500, isKeepAlive, contentType, body, null, null); }
private boolean isCacheable() { return route != null && HttpUtils.isGetReq(this) && route.cache() != null && cookies.isEmpty() && U.notEmpty(host()) && !hasToken(); }
void error(final Req req, final Throwable error, LogLevel logLevel) { try { logError(req, error, logLevel); Resp resp = req.response().code(500).result(null); Object result = Customization.of(req).errorHandler().handleError(req, resp, error); HttpUtils.resultOf(req, result); } catch (Exception e) { Log.error("An error occurred inside the error handler!", e); HttpUtils.resultToResponse(req, HttpUtils.getErrorInfo(req.response(), e)); } }
protected Object page(Req req, Resp resp, Throwable error) { if (error instanceof SecurityException) { resp.model("embedded", req.attr("_embedded", false)); resp.model("req", req); resp.model("loginUri", Msc.specialUri("login")); return resp.code(403).view("login").mvc(true); } else { BasicConfig zone = HttpUtils.zone(req); String home = zone.entry("home").or("/"); Map<String, ?> errorInfo = HttpUtils.getErrorInfo(resp, error); resp.model("req", req); resp.model("error", errorInfo); resp.model("home", home); return resp.mvc(true).view("error"); } }
private void process(final Req req, final Resp resp, final ProxyMapping mapping, final int attempts, final long since) { final String targetUrl = mapping.getTargetUrl(req); Map<String, String> headers = U.map(req.headers()); headers.remove("transfer-encoding"); headers.remove("content-length"); addExtraRequestHeaders(req, headers); HttpClient client = getOrCreateClient(); client.req() .verb(req.verb()) .url(targetUrl) .headers(headers) .cookies(req.cookies()) .body(req.body()) .raw(true) .execute((result, error) -> { if (error == null) { resp.code(result.code()); resp.body(result.bodyBytes()); // process the response headers SimpleHttpResp proxyResp = new SimpleHttpResp(); HttpUtils.proxyResponseHeaders(result.headers(), proxyResp); if (proxyResp.contentType != null) resp.contentType(proxyResp.contentType); if (proxyResp.headers != null) resp.headers().putAll(proxyResp.headers); if (proxyResp.cookies != null) resp.cookies().putAll(proxyResp.cookies); resp.done(); } else { handleError(error, req, resp, mapping, attempts, since); } }); }
private void respond(int code, RespBody body) { MediaType contentType = HttpUtils.getDefaultContentType(); if (tokenChanged.get()) { HttpUtils.saveTokenBeforeRenderingHeaders(this, token); } if (sessionChanged.get()) { saveSession(session.decorated()); } if (response != null) { contentType = U.or(response.contentType(), contentType); } renderResponse(code, contentType, body); }
@Override public Object wrap(final Req req, final HandlerInvocation invocation) throws Exception { TokenAuthData auth = HttpUtils.getAuth(req); String username = auth != null ? auth.user : null; if (U.isEmpty(username)) { HttpUtils.clearUserData(req); } Set<String> roles = userRoles(req, username); Set<String> scope = auth != null ? auth.scope : null; if (U.notEmpty(requiredRoles) && !Secure.hasAnyRole(username, roles, requiredRoles)) { throw new SecurityException("The user doesn't have the required roles!"); } Ctx ctx = Ctxs.required(); ctx.setUser(new UserInfo(username, roles, scope)); return invocation.invoke(); }
private void renderResponse() { HttpUtils.postProcessResponse(response); if (response.raw() != null) { int posBeforeResponse = channel.output().size(); byte[] bytes = Msc.toBytes(response.raw()); channel.write(bytes); if (willSaveToCache()) posBeforeBody = posBeforeResponse + HttpUtils.findBodyStart(bytes); completed = true; HttpIO.INSTANCE.done(this); } else { // render the response body RespBody body = BodyRenderer.toRespBody(this, response); // render the response doRendering(response.code(), body); } }
@Override public String contextPath() { if (contextPath == null) { synchronized (this) { if (contextPath == null) { contextPath = HttpUtils.getContextPath(this); } } } return contextPath; }
@Override public Resp cookie(String name, String value, String... extras) { if (U.notEmpty(extras)) { value += "; " + U.join("; ", extras); } if (!cookieContainsPath(extras)) { value += "; path=" + HttpUtils.cookiePath(); } cookies().put(name, value); return this; }
MediaType contentType = HttpUtils.getDefaultContentType();
@Override public Object wrap(final Req req, final HandlerInvocation invocation) { final AtomicReference<Object> resultHolder = new AtomicReference<>(); U.must(txMode != null && txMode != TransactionMode.NONE); boolean readOnly = (txMode == TransactionMode.AUTO) ? HttpUtils.isGetReq(req) : txMode == TransactionMode.READ_ONLY; try { JPA.transaction(() -> { Object res = invocation.invokeAndTransformResultCatchingErrors(result -> { if (result instanceof Throwable) { return result; } // serialize the result into a HTTP response body, while still inside tx (see #153) RespBody body = BodyRenderer.resultToRespBody(req.response(), result); return body; }); if (res instanceof Throwable) { // throw to rollback Throwable err = (Throwable) res; throw U.rte("Error occurred inside the transactional web handler!", err); } else { resultHolder.set(res); } }, readOnly); } catch (Throwable e) { resultHolder.set(e); } return resultHolder.get(); }
private void internalServerError(final Channel channel, final boolean isKeepAlive, final Req req) { MediaType contentType = req != null ? req.contentType() : HttpUtils.getDefaultContentType(); HttpResponseRenderer jsonRenderer = Customization.of(req).jsonResponseRenderer(); RespBody body = new RespBodyBytes(HttpUtils.responseToBytes(req, INTERNAL_SERVER_ERROR, contentType, jsonRenderer)); HttpIO.INSTANCE.respond(HttpUtils.maybe(req), channel, -1, -1, 500, isKeepAlive, contentType, body, null, null); }
void error(final Req req, final Throwable error, LogLevel logLevel) { try { logError(req, error, logLevel); Resp resp = req.response().code(500).result(null); Object result = Customization.of(req).errorHandler().handleError(req, resp, error); HttpUtils.resultOf(req, result); } catch (Exception e) { Log.error("An error occurred inside the error handler!", e); HttpUtils.resultToResponse(req, HttpUtils.getErrorInfo(req.response(), e)); } }
protected Object page(Req req, Resp resp, Throwable error) { if (error instanceof SecurityException) { resp.model("embedded", req.attr("_embedded", false)); resp.model("req", req); resp.model("loginUri", Msc.specialUri("login")); return resp.code(403).view("login").mvc(true); } else { BasicConfig zone = HttpUtils.zone(req); String home = zone.entry("home").or("/"); Map<String, ?> errorInfo = HttpUtils.getErrorInfo(resp, error); resp.model("req", req); resp.model("error", errorInfo); resp.model("home", home); return resp.mvc(true).view("error"); } }
private void saveToCache() { U.must(posBeforeBody != UNDEFINED); Buf out = channel.output(); int posAfterBody = out.size(); int bodyLength = (int) (posAfterBody - posBeforeBody); // FIXME validate '\r\n\r\n' before the start position of the response body Cache<HTTPCacheKey, CachedResp> cache = route.cache(); U.notNull(cache, "route.cache"); SimpleHttpResp proxyResp = new SimpleHttpResp(); proxyResp.cookies = U.map(U.safe(response != null ? response.cookies() : null)); Map<String, String> headers = response != null ? response.headers() : Collections.emptyMap(); HttpUtils.proxyResponseHeaders(headers, proxyResp); proxyResp.code = response != null ? response.code() : 200; if (proxyResp.contentType == null) { proxyResp.contentType = response != null ? response.contentType() : defaultContentType; } // don't cache the response if it contains cookies or token data if (U.notEmpty(proxyResp.cookies) || hasToken()) return; ByteBuffer body = writeBodyToBuf(out, bodyLength); CachedResp cached = new CachedResp(proxyResp.code, proxyResp.contentType, proxyResp.headers, body); cache.set(cacheKey, cached); }