From 680e628d85dc6e6aecb81cbf50448c207a503e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Denis?= Date: Tue, 11 Oct 2016 11:52:50 +0200 Subject: [PATCH] Handle http method override with X-HTTP-Method-Override header. Fixes #8 --- .../api/server/spi/EndpointsServlet.java | 21 +++++++++++++++--- .../api/server/spi/EndpointsServletTest.java | 22 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/endpoints-framework/src/main/java/com/google/api/server/spi/EndpointsServlet.java b/endpoints-framework/src/main/java/com/google/api/server/spi/EndpointsServlet.java index ede8993a..5f9852e2 100644 --- a/endpoints-framework/src/main/java/com/google/api/server/spi/EndpointsServlet.java +++ b/endpoints-framework/src/main/java/com/google/api/server/spi/EndpointsServlet.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList; import java.io.IOException; +import java.util.Enumeration; import java.util.List; import java.util.Map.Entry; @@ -61,19 +62,33 @@ public void init(ServletConfig config) throws ServletException { @Override public void service(HttpServletRequest request, HttpServletResponse response) throws IOException { - if ("OPTIONS".equals(request.getMethod())) { + String method = getRequestMethod(request); + if ("OPTIONS".equals(method)) { corsHandler.handle(request, response); } else { String path = Strings.stripSlash( request.getRequestURI().substring(request.getServletPath().length())); - EndpointsContext context = new EndpointsContext(request.getMethod(), path, request, response); - if (!dispatcher.dispatch(request.getMethod(), path, context)) { + EndpointsContext context = new EndpointsContext(method, path, request, response); + if (!dispatcher.dispatch(method, path, context)) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.getWriter().append("Not Found"); } } } + private String getRequestMethod(HttpServletRequest request) { + Enumeration headerNames = request.getHeaderNames(); + String methodOverride = null; + while (headerNames.hasMoreElements()) { + String headerName = (String) headerNames.nextElement(); + if (headerName.toLowerCase().equals("x-http-method-override")) { + methodOverride = request.getHeader(headerName); + break; + } + } + return methodOverride != null ? methodOverride.toUpperCase() : request.getMethod(); + } + private PathDispatcher createDispatcher() { PathDispatcher.Builder builder = PathDispatcher.builder(); List endpoints = systemService.getEndpoints(); diff --git a/endpoints-framework/src/test/java/com/google/api/server/spi/EndpointsServletTest.java b/endpoints-framework/src/test/java/com/google/api/server/spi/EndpointsServletTest.java index 10921e0d..91531e92 100644 --- a/endpoints-framework/src/test/java/com/google/api/server/spi/EndpointsServletTest.java +++ b/endpoints-framework/src/test/java/com/google/api/server/spi/EndpointsServletTest.java @@ -113,6 +113,22 @@ public void echo() throws IOException { assertThat(actual.get("x").asInt()).isEqualTo(1); } + @Test + public void methodOverride() throws IOException { + req.setRequestURI("/_ah/api/test/v2/increment"); + req.setMethod("POST"); + req.addHeader("X-HTTP-Method-Override", "PATCH"); + req.setParameter("x", "1"); + + servlet.service(req, resp); + + assertThat(resp.getStatus()).isEqualTo(HttpServletResponse.SC_OK); + ObjectMapper mapper = ObjectMapperUtil.createStandardObjectMapper(); + ObjectNode actual = mapper.readValue(resp.getContentAsString(), ObjectNode.class); + assertThat(actual.size()).isEqualTo(1); + assertThat(actual.get("x").asInt()).isEqualTo(2); + } + @Test public void proxy() throws IOException { req.setRequestURI("/_ah/api/static/proxy.html"); @@ -157,5 +173,11 @@ public void empty() {} public TestResource echo(TestResource r) { return r; } + + @ApiMethod(httpMethod = "PATCH") + public TestResource increment(TestResource r) { + r.x = r.x + 1; + return r; + } } }