/** * Returns a summary string of the given {@link PathMappingContext}. */ static List<Object> generateSummary(PathMappingContext mappingCtx) { requireNonNull(mappingCtx, "mappingCtx"); // 0 : VirtualHost // 1 : HttpMethod // 2 : Path // 3 : Content-Type // 4~: Accept final List<Object> summary = new ArrayList<>(8); summary.add(mappingCtx.virtualHost()); summary.add(mappingCtx.method()); summary.add(mappingCtx.path()); summary.add(mappingCtx.consumeType()); final List<MediaType> produceTypes = mappingCtx.produceTypes(); if (produceTypes != null) { summary.addAll(produceTypes); } return summary; } }
@Override public void delayThrowable(Throwable cause) { delegate().delayThrowable(cause); }
@Override public Optional<Throwable> delayedThrowable() { return delegate().delayedThrowable(); }
final PathMappingResult result = pathStringMapping.apply(mappingCtx); if (!result.isPresent()) { if (mappingCtx.isCorsPreflight() && !mappingCtx.delayedThrowable().isPresent()) { mappingCtx.delayThrowable(HttpStatusException.of(HttpStatus.FORBIDDEN)); if (!mappingCtx.isCorsPreflight() && !supportedMethods.contains(mappingCtx.method())) { if (!mappingCtx.delayedThrowable().isPresent()) { mappingCtx.delayThrowable(HttpStatusException.of(HttpStatus.METHOD_NOT_ALLOWED)); final MediaType type = mappingCtx.consumeType(); boolean found = false; if (type != null) { mappingCtx.delayThrowable(HttpStatusException.of(HttpStatus.UNSUPPORTED_MEDIA_TYPE)); return PathMappingResult.empty(); // So there is a '*/*' at least in the 'mappingCtx.produceTypes()' if the virtual host supports final List<MediaType> types = mappingCtx.produceTypes(); if (types == null) { mappingCtx.delayThrowable(HttpStatusException.of(HttpStatus.NOT_ACCEPTABLE)); return PathMappingResult.empty();
@Override protected PathMappingResult doApply(PathMappingContext mappingCtx) { final String path = mappingCtx.path(); if (!path.startsWith(pathPrefix)) { return PathMappingResult.empty(); } final PathMappingResult result = mapping.apply(mappingCtx.overridePath(path.substring(pathPrefix.length() - 1))); if (result.isPresent()) { return PathMappingResult.of(path, mappingCtx.query(), result.pathParams()); } else { return PathMappingResult.empty(); } }
private void handleNonExistentMapping(ChannelHandlerContext ctx, DecodedHttpRequest req, VirtualHost host, PathAndQuery pathAndQuery, PathMappingContext mappingCtx) { final String path = mappingCtx.path(); if (path.charAt(path.length() - 1) != '/') { // Handle the case where /path doesn't exist but /path/ exists. final String pathWithSlash = path + '/'; if (host.findServiceConfig(mappingCtx.overridePath(pathWithSlash)).isPresent()) { final String location; final String originalPath = req.path(); if (path.length() == originalPath.length()) { location = pathWithSlash; } else { location = pathWithSlash + originalPath.substring(path.length()); } redirect(ctx, req, pathAndQuery, location); return; } } respond(ctx, req, HttpStatus.NOT_FOUND, null); }
@Override public PathMapped<V> find(PathMappingContext mappingCtx) { return findsBest(mappingCtx, trie.find(mappingCtx.path()), pathMappingResolver); }
@Nullable @Override public List<MediaType> produceTypes() { return delegate().produceTypes(); }
@Nullable @Override public MediaType consumeType() { return delegate().consumeType(); }
@Nullable @Override public String query() { return delegate().query(); }
@Override public String hostname() { return delegate().hostname(); }
@Override public HttpMethod method() { return delegate().method(); }
@Override public boolean isCorsPreflight() { return delegate().isCorsPreflight(); }
@Override public O serve(ServiceRequestContext ctx, I req) throws Exception { final PathMappingContext mappingCtx = ctx.pathMappingContext(); final PathMapped<Service<I, O>> mapped = findService(mappingCtx.overridePath(ctx.mappedPath())); if (!mapped.isPresent()) { throw HttpStatusException.of(HttpStatus.NOT_FOUND); } final Optional<String> childPrefix = mapped.mapping().prefix(); if (childPrefix.isPresent()) { final PathMapping newMapping = PathMapping.ofPrefix(ctx.pathMapping().prefix().get() + childPrefix.get().substring(1)); final ServiceRequestContext newCtx = new CompositeServiceRequestContext( ctx, newMapping, mapped.mappingResult().path()); try (SafeCloseable ignored = newCtx.push(false)) { return mapped.value().serve(newCtx, req); } } else { return mapped.value().serve(ctx, req); } }
@Override public String path() { return delegate().path(); }
/** * {@inheritDoc} This method performs sanity checks on the specified {@code path} and calls * {@link #doApply(PathMappingContext)}. */ @Override public final PathMappingResult apply(PathMappingContext mappingCtx) { ensureAbsolutePath(mappingCtx.path(), "path"); return doApply(mappingCtx); }