diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyHttpServletRequest.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyHttpServletRequest.java index 4c64ca23a..f899a5c9d 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyHttpServletRequest.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyHttpServletRequest.java @@ -27,7 +27,6 @@ import java.io.UnsupportedEncodingException; import java.security.Principal; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -41,10 +40,10 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.stream.Collectors; import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; +import javax.servlet.ReadListener; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -60,21 +59,15 @@ import javax.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; public class ProxyHttpServletRequest implements HttpServletRequest { - private static final String HTTP = "http"; - - private static final String HTTPS = "https"; - private static final String CHARSET_PREFIX = "charset="; private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @@ -90,53 +83,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { private static final String[] DATE_FORMATS = new String[] { "EEE, dd MMM yyyy HH:mm:ss zzz", "EEE, dd-MMM-yy HH:mm:ss zzz", "EEE MMM dd HH:mm:ss yyyy" }; - // --------------------------------------------------------------------- - // Public constants - // --------------------------------------------------------------------- - - /** - * The default protocol: 'HTTP/1.1'. - * - * @since 4.3.7 - */ - public static final String DEFAULT_PROTOCOL = "HTTP/1.1"; - - /** - * The default scheme: 'http'. - * - * @since 4.3.7 - */ - public static final String DEFAULT_SCHEME = HTTP; - - /** - * The default server address: '127.0.0.1'. - */ - public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; - - /** - * The default server name: 'localhost'. - */ - public static final String DEFAULT_SERVER_NAME = "localhost"; - - /** - * The default server port: '80'. - */ - public static final int DEFAULT_SERVER_PORT = 80; - - /** - * The default remote address: '127.0.0.1'. - */ - public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; - - /** - * The default remote host: 'localhost'. - */ - public static final String DEFAULT_REMOTE_HOST = "localhost"; - - // --------------------------------------------------------------------- - // Lifecycle properties - // --------------------------------------------------------------------- - private final ServletContext servletContext; private boolean active = true; @@ -224,26 +170,7 @@ public class ProxyHttpServletRequest implements HttpServletRequest { private final MultiValueMap parts = new LinkedMultiValueMap<>(); - // --------------------------------------------------------------------- - // Constructors - // --------------------------------------------------------------------- - /** - * Create a new {@code MockHttpServletRequest} with the supplied - * {@link ServletContext}, {@code method}, and {@code requestURI}. - *

- * The preferred locale will be set to {@link Locale#ENGLISH}. - * - * @param servletContext the ServletContext that the request runs in (may be - * {@code null} to use a default - * {@link MockServletContext}) - * @param method the request method (may be {@code null}) - * @param requestURI the request URI (may be {@code null}) - * @see #setMethod - * @see #setRequestURI - * @see #setPreferredLocales - * @see MockServletContext - */ public ProxyHttpServletRequest(ServletContext servletContext, String method, String requestURI) { this.servletContext = servletContext; this.method = method; @@ -251,10 +178,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { this.locales.add(Locale.ENGLISH); } - // --------------------------------------------------------------------- - // Lifecycle methods - // --------------------------------------------------------------------- - /** * Return the ServletContext that this request is associated with. (Not * available in the standard HttpServletRequest interface for some reason.) @@ -264,49 +187,13 @@ public class ProxyHttpServletRequest implements HttpServletRequest { return this.servletContext; } - /** - * Return whether this request is still active (that is, not completed yet). - */ - public boolean isActive() { - return this.active; - } - - /** - * Mark this request as completed, keeping its state. - */ - public void close() { - this.active = false; - } - - /** - * Invalidate this request, clearing its state. - */ - public void invalidate() { - close(); - clearAttributes(); - } - - /** - * Check whether this request is still active (that is, not completed yet), - * throwing an IllegalStateException if not active anymore. - */ - protected void checkActive() throws IllegalStateException { - Assert.state(this.active, "Request is not active anymore"); - } - - // --------------------------------------------------------------------- - // ServletRequest interface - // --------------------------------------------------------------------- - @Override public Object getAttribute(String name) { - checkActive(); return this.attributes.get(name); } @Override public Enumeration getAttributeNames() { - checkActive(); return Collections.enumeration(new LinkedHashSet<>(this.attributes.keySet())); } @@ -426,7 +313,34 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public ServletInputStream getInputStream() { - throw new UnsupportedOperationException(); + InputStream stream = new ByteArrayInputStream(this.content); + return new ServletInputStream() { + + boolean finished = false; + + @Override + public int read() throws IOException { + int readByte = stream.read(); + if (readByte == -1) { + finished = true; + } + return readByte; + } + + @Override + public void setReadListener(ReadListener readListener) { + } + + @Override + public boolean isReady() { + return !finished; + } + + @Override + public boolean isFinished() { + return finished; + } + }; } /** @@ -561,19 +475,8 @@ public class ProxyHttpServletRequest implements HttpServletRequest { return Collections.unmodifiableMap(this.parameters); } - public void setProtocol(String protocol) { - // this.protocol = protocol; - throw new UnsupportedOperationException(); - } - @Override public String getProtocol() { - // return this.protocol; - throw new UnsupportedOperationException(); - } - - public void setScheme(String scheme) { -// this.scheme = scheme; throw new UnsupportedOperationException(); } @@ -643,7 +546,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public void setAttribute(String name, @Nullable Object value) { - checkActive(); Assert.notNull(name, "Attribute name must not be null"); if (value != null) { this.attributes.put(name, value); @@ -655,7 +557,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public void removeAttribute(String name) { - checkActive(); Assert.notNull(name, "Attribute name must not be null"); this.attributes.remove(name); } @@ -795,7 +696,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public int getLocalPort() { -// return this.localPort; throw new UnsupportedOperationException(); } @@ -846,10 +746,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { return this.dispatcherType; } - // --------------------------------------------------------------------- - // HttpServletRequest interface - // --------------------------------------------------------------------- - public void setAuthType(@Nullable String authType) { this.authType = authType; } @@ -860,21 +756,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { return this.authType; } - public void setCookies(@Nullable Cookie... cookies) { - this.cookies = (ObjectUtils.isEmpty(cookies) ? null : cookies); - if (this.cookies == null) { - removeHeader(HttpHeaders.COOKIE); - } - else { - doAddHeaderValue(HttpHeaders.COOKIE, encodeCookies(this.cookies), true); - } - } - - private static String encodeCookies(@NonNull Cookie... cookies) { - return Arrays.stream(cookies).map(c -> c.getName() + '=' + (c.getValue() == null ? "" : c.getValue())) - .collect(Collectors.joining("; ")); - } - @Override @Nullable public Cookie[] getCookies() { @@ -945,16 +826,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { } } - /** - * Remove already registered entries for the specified HTTP header, if any. - * - * @since 4.3.20 - */ - public void removeHeader(String name) { - Assert.notNull(name, "Header name must not be null"); - this.headers.remove(name); - } - /** * Return the long timestamp for the date header with the given {@code name}. *

@@ -1104,8 +975,6 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public boolean isUserInRole(String role) { throw new UnsupportedOperationException(); -// return (this.userRoles.contains(role) || (this.servletContext instanceof MockServletContext && -// ((MockServletContext) this.servletContext).getDeclaredRoles().contains(role))); } public void setUserPrincipal(@Nullable Principal userPrincipal) { @@ -1140,20 +1009,7 @@ public class ProxyHttpServletRequest implements HttpServletRequest { @Override public StringBuffer getRequestURL() { - String scheme = getScheme(); - String server = getServerName(); - int port = getServerPort(); - String uri = getRequestURI(); - - StringBuffer url = new StringBuffer(scheme).append("://").append(server); - if (port > 0 - && ((HTTP.equalsIgnoreCase(scheme) && port != 80) || (HTTPS.equalsIgnoreCase(scheme) && port != 443))) { - url.append(':').append(port); - } - if (StringUtils.hasText(uri)) { - url.append(uri); - } - return url; + throw new UnsupportedOperationException(); } public void setServletPath(String servletPath) { @@ -1166,28 +1022,13 @@ public class ProxyHttpServletRequest implements HttpServletRequest { } public void setSession(HttpSession session) { -// this.session = session; -// if (session instanceof MockHttpSession) { -// MockHttpSession mockSession = ((MockHttpSession) session); -// mockSession.access(); -// } throw new UnsupportedOperationException(); } @Override @Nullable public HttpSession getSession(boolean create) { - checkActive(); - // Reset session if invalidated. -// if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { -// this.session = null; -// } -// // Create new session if necessary. -// if (this.session == null && create) { -// this.session = new MockHttpSession(this.servletContext); -// } return this.session; -// throw new UnsupportedOperationException(); } @Override @@ -1196,20 +1037,8 @@ public class ProxyHttpServletRequest implements HttpServletRequest { return getSession(true); } - /** - * The implementation of this (Servlet 3.1+) method calls - * {@link MockHttpSession#changeSessionId()} if the session is a mock session. - * Otherwise it simply returns the current session id. - * - * @since 4.0.3 - */ @Override public String changeSessionId() { -// Assert.isTrue(this.session != null, "The request does not have a session"); -// if (this.session instanceof MockHttpSession) { -// return ((MockHttpSession) this.session).changeSessionId(); -// } -// return this.session.getId(); throw new UnsupportedOperationException(); } diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyMvc.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyMvc.java index e8423a323..e9c646d9c 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyMvc.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws-web/src/main/java/org/springframework/web/client/ProxyMvc.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; +import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class ProxyMvc { @@ -45,6 +46,8 @@ public class ProxyMvc { private final Filter[] filters; + private final ConfigurableWebApplicationContext applicationContext; + @Nullable private Charset defaultResponseCharacterEncoding; @@ -53,13 +56,16 @@ public class ProxyMvc { * * @see org.springframework.test.web.servlet.setup.MockMvcBuilders */ - public ProxyMvc(DispatcherServlet servlet, Filter... filters) { + public ProxyMvc(DispatcherServlet servlet, ConfigurableWebApplicationContext applicationContext) { Assert.notNull(servlet, "DispatcherServlet is required"); - Assert.notNull(filters, "Filters cannot be null"); - Assert.noNullElements(filters, "Filters cannot contain null values"); + this.applicationContext = applicationContext; this.servlet = servlet; - this.filters = filters; + this.filters = applicationContext.getBeansOfType(Filter.class).values().toArray(new Filter[0]); + } + + public void stop() { + this.applicationContext.stop(); } /** @@ -101,11 +107,15 @@ public class ProxyMvc { * @see org.springframework.test.web.servlet.request.MockMvcRequestBuilders * @see org.springframework.test.web.servlet.result.MockMvcResultMatchers */ - public void perform(HttpServletRequest request, HttpServletResponse response) throws Exception { + public void service(HttpServletRequest request, HttpServletResponse response) throws Exception { ProxyFilterChain filterChain = new ProxyFilterChain(this.servlet, this.filters); filterChain.doFilter(request, response); } + public ConfigurableWebApplicationContext getApplicationContext() { + return applicationContext; + } + private static class ProxyFilterChain implements FilterChain { @Nullable