1 /** 2 * Copyright (C) 2008 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.servlet; 18 19 import static com.google.inject.servlet.ManagedServletPipeline.REQUEST_DISPATCHER_REQUEST; 20 import static org.easymock.EasyMock.anyObject; 21 import static org.easymock.EasyMock.createMock; 22 import static org.easymock.EasyMock.eq; 23 import static org.easymock.EasyMock.expect; 24 import static org.easymock.EasyMock.expectLastCall; 25 import static org.easymock.EasyMock.replay; 26 import static org.easymock.EasyMock.verify; 27 28 import com.google.common.collect.ImmutableList; 29 import com.google.common.collect.Sets; 30 import com.google.inject.Binding; 31 import com.google.inject.Injector; 32 import com.google.inject.Key; 33 import com.google.inject.Provider; 34 import com.google.inject.TypeLiteral; 35 import com.google.inject.spi.BindingScopingVisitor; 36 import com.google.inject.util.Providers; 37 38 import junit.framework.TestCase; 39 40 import java.io.IOException; 41 import java.util.ArrayList; 42 import java.util.Date; 43 import java.util.HashMap; 44 import java.util.List; 45 import java.util.UUID; 46 47 import javax.servlet.RequestDispatcher; 48 import javax.servlet.ServletException; 49 import javax.servlet.http.HttpServlet; 50 import javax.servlet.http.HttpServletRequest; 51 import javax.servlet.http.HttpServletResponse; 52 53 /** 54 * Tests forwarding and inclusion (RequestDispatcher actions from the 55 * servlet spec). 56 * 57 * @author Dhanji R. Prasanna (dhanji@gmail com) 58 */ 59 public class ServletPipelineRequestDispatcherTest extends TestCase { 60 private static final Key<HttpServlet> HTTP_SERLVET_KEY = Key.get(HttpServlet.class); 61 private static final String A_KEY = "thinglyDEgintly" + new Date() + UUID.randomUUID(); 62 private static final String A_VALUE = ServletPipelineRequestDispatcherTest.class.toString() 63 + new Date() + UUID.randomUUID(); 64 testIncludeManagedServlet()65 public final void testIncludeManagedServlet() throws IOException, ServletException { 66 String pattern = "blah.html"; 67 final ServletDefinition servletDefinition = new ServletDefinition(pattern, 68 Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern), 69 new HashMap<String, String>(), null); 70 71 final Injector injector = createMock(Injector.class); 72 final Binding binding = createMock(Binding.class); 73 final HttpServletRequest requestMock = createMock(HttpServletRequest.class); 74 75 expect(requestMock.getAttribute(A_KEY)) 76 .andReturn(A_VALUE); 77 78 79 requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true); 80 requestMock.removeAttribute(REQUEST_DISPATCHER_REQUEST); 81 82 final boolean[] run = new boolean[1]; 83 final HttpServlet mockServlet = new HttpServlet() { 84 protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse) 85 throws ServletException, IOException { 86 run[0] = true; 87 88 final Object o = request.getAttribute(A_KEY); 89 assertEquals("Wrong attrib returned - " + o, A_VALUE, o); 90 } 91 }; 92 93 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())) 94 .andReturn(true); 95 expect(injector.getBinding(Key.get(HttpServlet.class))) 96 .andReturn(binding); 97 expect(injector.getInstance(HTTP_SERLVET_KEY)) 98 .andReturn(mockServlet); 99 100 101 final Key<ServletDefinition> servetDefsKey = Key 102 .get(TypeLiteral.get(ServletDefinition.class)); 103 104 Binding<ServletDefinition> mockBinding = createMock(Binding.class); 105 expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral()))) 106 .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding)); 107 Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition); 108 expect(mockBinding.getProvider()) 109 .andReturn(bindingProvider); 110 111 replay(injector, binding, requestMock, mockBinding); 112 113 // Have to init the Servlet before we can dispatch to it. 114 servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet()); 115 116 final RequestDispatcher dispatcher = new ManagedServletPipeline( 117 injector) 118 .getRequestDispatcher(pattern); 119 120 assertNotNull(dispatcher); 121 dispatcher.include(requestMock, createMock(HttpServletResponse.class)); 122 123 assertTrue("Include did not dispatch to our servlet!", run[0]); 124 125 verify(injector, requestMock, mockBinding); 126 } 127 testForwardToManagedServlet()128 public final void testForwardToManagedServlet() throws IOException, ServletException { 129 String pattern = "blah.html"; 130 final ServletDefinition servletDefinition = new ServletDefinition(pattern, 131 Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern), 132 new HashMap<String, String>(), null); 133 134 final Injector injector = createMock(Injector.class); 135 final Binding binding = createMock(Binding.class); 136 final HttpServletRequest requestMock = createMock(HttpServletRequest.class); 137 final HttpServletResponse mockResponse = createMock(HttpServletResponse.class); 138 139 expect(requestMock.getAttribute(A_KEY)) 140 .andReturn(A_VALUE); 141 142 143 requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true); 144 requestMock.removeAttribute(REQUEST_DISPATCHER_REQUEST); 145 146 expect(mockResponse.isCommitted()) 147 .andReturn(false); 148 149 mockResponse.resetBuffer(); 150 expectLastCall().once(); 151 152 final List<String> paths = new ArrayList<String>(); 153 final HttpServlet mockServlet = new HttpServlet() { 154 protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse) 155 throws ServletException, IOException { 156 paths.add(request.getRequestURI()); 157 158 final Object o = request.getAttribute(A_KEY); 159 assertEquals("Wrong attrib returned - " + o, A_VALUE, o); 160 } 161 }; 162 163 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())) 164 .andReturn(true); 165 expect(injector.getBinding(Key.get(HttpServlet.class))) 166 .andReturn(binding); 167 168 expect(injector.getInstance(HTTP_SERLVET_KEY)) 169 .andReturn(mockServlet); 170 171 final Key<ServletDefinition> servetDefsKey = Key 172 .get(TypeLiteral.get(ServletDefinition.class)); 173 174 Binding<ServletDefinition> mockBinding = createMock(Binding.class); 175 expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral()))) 176 .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding)); 177 Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition); 178 expect(mockBinding.getProvider()) 179 .andReturn(bindingProvider); 180 181 replay(injector, binding, requestMock, mockResponse, mockBinding); 182 183 // Have to init the Servlet before we can dispatch to it. 184 servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet()); 185 186 final RequestDispatcher dispatcher = new ManagedServletPipeline(injector) 187 .getRequestDispatcher(pattern); 188 189 assertNotNull(dispatcher); 190 dispatcher.forward(requestMock, mockResponse); 191 192 assertTrue("Include did not dispatch to our servlet!", paths.contains(pattern)); 193 194 verify(injector, requestMock, mockResponse, mockBinding); 195 } 196 testForwardToManagedServletFailureOnCommittedBuffer()197 public final void testForwardToManagedServletFailureOnCommittedBuffer() 198 throws IOException, ServletException { 199 IllegalStateException expected = null; 200 try { 201 forwardToManagedServletFailureOnCommittedBuffer(); 202 } 203 catch (IllegalStateException ise) { 204 expected = ise; 205 } finally { 206 assertNotNull("Expected IllegalStateException was not thrown", expected); 207 } 208 } 209 forwardToManagedServletFailureOnCommittedBuffer()210 public final void forwardToManagedServletFailureOnCommittedBuffer() 211 throws IOException, ServletException { 212 String pattern = "blah.html"; 213 final ServletDefinition servletDefinition = new ServletDefinition(pattern, 214 Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern), 215 new HashMap<String, String>(), null); 216 217 final Injector injector = createMock(Injector.class); 218 final Binding binding = createMock(Binding.class); 219 final HttpServletRequest mockRequest = createMock(HttpServletRequest.class); 220 final HttpServletResponse mockResponse = createMock(HttpServletResponse.class); 221 222 expect(mockResponse.isCommitted()) 223 .andReturn(true); 224 225 final HttpServlet mockServlet = new HttpServlet() { 226 protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse) 227 throws ServletException, IOException { 228 229 final Object o = request.getAttribute(A_KEY); 230 assertEquals("Wrong attrib returned - " + o, A_VALUE, o); 231 } 232 }; 233 234 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())) 235 .andReturn(true); 236 expect(injector.getBinding(Key.get(HttpServlet.class))) 237 .andReturn(binding); 238 239 expect(injector.getInstance(Key.get(HttpServlet.class))) 240 .andReturn(mockServlet); 241 242 243 final Key<ServletDefinition> servetDefsKey = Key 244 .get(TypeLiteral.get(ServletDefinition.class)); 245 246 Binding<ServletDefinition> mockBinding = createMock(Binding.class); 247 expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral()))) 248 .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding)); 249 Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition); 250 expect(mockBinding.getProvider()) 251 .andReturn(bindingProvider); 252 253 replay(injector, binding, mockRequest, mockResponse, mockBinding); 254 255 // Have to init the Servlet before we can dispatch to it. 256 servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet()); 257 258 final RequestDispatcher dispatcher = new ManagedServletPipeline(injector) 259 .getRequestDispatcher(pattern); 260 261 assertNotNull(dispatcher); 262 263 try { 264 dispatcher.forward(mockRequest, mockResponse); 265 } 266 finally { 267 verify(injector, mockRequest, mockResponse, mockBinding); 268 } 269 } 270 testWrappedRequestUriAndUrlConsistency()271 public final void testWrappedRequestUriAndUrlConsistency() { 272 final HttpServletRequest mockRequest = createMock(HttpServletRequest.class); 273 expect(mockRequest.getScheme()).andReturn("http"); 274 expect(mockRequest.getServerName()).andReturn("the.server"); 275 expect(mockRequest.getServerPort()).andReturn(12345); 276 replay(mockRequest); 277 HttpServletRequest wrappedRequest = ManagedServletPipeline.wrapRequest(mockRequest, "/new-uri"); 278 assertEquals("/new-uri", wrappedRequest.getRequestURI()); 279 assertEquals("http://the.server:12345/new-uri", wrappedRequest.getRequestURL().toString()); 280 } 281 testWrappedRequestUrlNegativePort()282 public final void testWrappedRequestUrlNegativePort() { 283 final HttpServletRequest mockRequest = createMock(HttpServletRequest.class); 284 expect(mockRequest.getScheme()).andReturn("http"); 285 expect(mockRequest.getServerName()).andReturn("the.server"); 286 expect(mockRequest.getServerPort()).andReturn(-1); 287 replay(mockRequest); 288 HttpServletRequest wrappedRequest = ManagedServletPipeline.wrapRequest(mockRequest, "/new-uri"); 289 assertEquals("/new-uri", wrappedRequest.getRequestURI()); 290 assertEquals("http://the.server/new-uri", wrappedRequest.getRequestURL().toString()); 291 } 292 testWrappedRequestUrlDefaultPort()293 public final void testWrappedRequestUrlDefaultPort() { 294 final HttpServletRequest mockRequest = createMock(HttpServletRequest.class); 295 expect(mockRequest.getScheme()).andReturn("http"); 296 expect(mockRequest.getServerName()).andReturn("the.server"); 297 expect(mockRequest.getServerPort()).andReturn(80); 298 replay(mockRequest); 299 HttpServletRequest wrappedRequest = ManagedServletPipeline.wrapRequest(mockRequest, "/new-uri"); 300 assertEquals("/new-uri", wrappedRequest.getRequestURI()); 301 assertEquals("http://the.server/new-uri", wrappedRequest.getRequestURL().toString()); 302 } 303 304 testWrappedRequestUrlDefaultHttpsPort()305 public final void testWrappedRequestUrlDefaultHttpsPort() { 306 final HttpServletRequest mockRequest = createMock(HttpServletRequest.class); 307 expect(mockRequest.getScheme()).andReturn("https"); 308 expect(mockRequest.getServerName()).andReturn("the.server"); 309 expect(mockRequest.getServerPort()).andReturn(443); 310 replay(mockRequest); 311 HttpServletRequest wrappedRequest = ManagedServletPipeline.wrapRequest(mockRequest, "/new-uri"); 312 assertEquals("/new-uri", wrappedRequest.getRequestURI()); 313 assertEquals("https://the.server/new-uri", wrappedRequest.getRequestURL().toString()); 314 } 315 } 316