Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a text based 404 based on useragent #41989

Merged
merged 1 commit into from
Jul 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static io.quarkus.runtime.TemplateHtmlBuilder.adjustRoot;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
Expand Down Expand Up @@ -74,7 +75,7 @@ public String getHTMLContent() {

List<RouteDescription> combinedRoutes = getCombinedRoutes();
TemplateHtmlBuilder builder = new TemplateHtmlBuilder(this.baseUrl,
"404 - Resource Not Found", "", "Resources overview");
HEADING, "", "Resources overview");

builder.resourcesStart(RESOURCE_ENDPOINTS);

Expand Down Expand Up @@ -198,6 +199,70 @@ public JsonObject getJsonContent() {

}

@NonBlocking
public String getTextContent() {
List<RouteDescription> combinedRoutes = getCombinedRoutes();
try (StringWriter sw = new StringWriter()) {
sw.write(NL + HEADING + NL);
sw.write("------------------------" + NL);
sw.write(NL);
// REST Endpoints
if (!combinedRoutes.isEmpty()) {
sw.write(RESOURCE_ENDPOINTS + NL);
for (RouteDescription resource : combinedRoutes) {
for (RouteMethodDescription method : resource.getCalls()) {
String description = method.getHttpMethod();
if (method.getConsumes() != null) {
description = description + " (consumes: " + method.getConsumes() + ")";
}
if (method.getProduces() != null) {
description = description + " (produces:" + method.getProduces() + ")";
}
if (method.getJavaMethod() != null) {
description = description + " (java:" + method.getJavaMethod() + ")";
}
sw.write(TAB + "- " + adjustRoot(this.httpRoot, method.getFullPath()) + NL);
sw.write(TAB + TAB + "- " + description + NL);
}
}
sw.write(NL);
}
// Servlets
if (!servletMappings.isEmpty()) {
sw.write(SERVLET_MAPPINGS + NL);
for (String servletMapping : servletMappings) {
sw.write(TAB + "- " + adjustRoot(this.httpRoot, servletMapping) + NL);
}
sw.write(NL);
}
// Static Resources
if (!this.staticRoots.isEmpty()) {
List<String> resources = findRealResources();
if (!resources.isEmpty()) {
sw.write(STATIC_RESOURCES + NL);
for (String staticResource : resources) {
sw.write(TAB + "- " + adjustRoot(this.httpRoot, staticResource) + NL);
}
sw.write(NL);
}
}

// Additional Endpoints
if (!this.additionalEndpoints.isEmpty()) {
sw.write(ADDITIONAL_ENDPOINTS + NL);
for (AdditionalRouteDescription additionalEndpoint : this.additionalEndpoints) {
sw.write(TAB + "- " + additionalEndpoint.getUri() + NL);
sw.write(TAB + TAB + "- " + additionalEndpoint.getDescription() + NL);
}
sw.write(NL);
}

return sw.toString();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}

private List<RouteDescription> getCombinedRoutes() {
// Endpoints
List<RouteDescription> combinedRoutes = new ArrayList<>();
Expand Down Expand Up @@ -276,12 +341,15 @@ private boolean isHtmlFileName(String fileName) {
return fileName.endsWith(".html") || fileName.endsWith(".htm") || fileName.endsWith(".xhtml");
}

private static final String HEADING = "404 - Resource Not Found";
private static final String RESOURCE_ENDPOINTS = "Resource Endpoints";
private static final String SERVLET_MAPPINGS = "Servlet mappings";
private static final String STATIC_RESOURCES = "Static resources";
private static final String ADDITIONAL_ENDPOINTS = "Additional endpoints";
private static final String URI = "uri";
private static final String DESCRIPTION = "description";
private static final String EMPTY = "";
private static final String NL = "\n";
private static final String TAB = "\t";

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.vertx.http.runtime.devmode;

import java.util.Locale;

import jakarta.enterprise.inject.spi.CDI;

import io.vertx.core.Handler;
Expand All @@ -22,8 +24,17 @@ public void handle(RoutingContext routingContext) {
String header = routingContext.request().getHeader("Accept");
if (header != null && header.startsWith("application/json")) {
handleJson(routingContext);
} else {
} else if (header != null && header.startsWith("text/html")) {
handleHTML(routingContext);
} else {
// If not explicitly asked for json/html, let determine based on the user agent
String userAgent = routingContext.request().getHeader("User-Agent");
if (userAgent != null && (userAgent.toLowerCase(Locale.ROOT).startsWith("wget/")
|| userAgent.toLowerCase(Locale.ROOT).startsWith("curl/"))) {
handleText(routingContext);
} else {
handleHTML(routingContext);
}
}
}

Expand All @@ -34,6 +45,13 @@ private void handleJson(RoutingContext routingContext) {
.end(Json.encodePrettily(resourceNotFoundData.getJsonContent()));
}

private void handleText(RoutingContext routingContext) {
routingContext.response()
.setStatusCode(404)
.putHeader("content-type", "text/plain; charset=utf-8")
.end(resourceNotFoundData.getTextContent());
}

private void handleHTML(RoutingContext routingContext) {
routingContext.response()
.setStatusCode(404)
Expand Down
Loading