Skip to content

Commit

Permalink
Added fix to adjust how the servlet context path is handled
Browse files Browse the repository at this point in the history
Based on a thread from the Servlet Expert Group
  • Loading branch information
bdemers committed Sep 9, 2016
1 parent d41afcc commit b15ab92
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 2 deletions.
5 changes: 3 additions & 2 deletions web/src/main/java/org/apache/shiro/web/util/WebUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,12 @@ public static String getContextPath(HttpServletRequest request) {
if (contextPath == null) {
contextPath = request.getContextPath();
}
contextPath = normalize(decodeRequestString(request, contextPath));
if ("/".equals(contextPath)) {
// Invalid case, but happens for includes on Jetty: silently adapt it.
// the normalize method will return a "/" and includes on Jetty, will also be a "/".
contextPath = "";
}
return decodeRequestString(request, contextPath);
return contextPath;
}

/**
Expand Down
158 changes: 158 additions & 0 deletions web/src/test/groovy/org/apache/shiro/web/util/WebUtilsTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package org.apache.shiro.web.util

import org.junit.Assert
import org.junit.Test

import javax.servlet.http.HttpServletRequest

import static org.easymock.EasyMock.*
import static org.junit.Assert.*

/**
* Tests for {@link WebUtils}.
*/
public class WebUtilsTest {

@Test
void testGetContextPathIncludes() {
def request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn("/")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn("")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn("/context-path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context-path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn("//context-path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context-path", WebUtils.getContextPath(request)
verify request
}

@Test
void testGetContextPath() {

def request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/context-path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context-path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("//context-path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context-path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/context%20path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/c%6Fntext%20path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/context path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context path", WebUtils.getContextPath(request)
verify request

request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/context%2525path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
assertEquals "/context%25path", WebUtils.getContextPath(request)
verify request

// non visible character's are NOT normalized, such as a backspace
request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null)
expect(request.getContextPath()).andReturn("/context-%08path")
expect(request.getCharacterEncoding()).andReturn("UTF-8")
replay request
def expected = "/context-" + (char) 0x08 + "path"
assertEquals expected, WebUtils.getContextPath(request)
verify request

}


@Test
void testGetPathWithinApplication() {

doTestGetPathWithinApplication("/", "/foobar", "/foobar");
doTestGetPathWithinApplication("", "/foobar", "/foobar");
doTestGetPathWithinApplication("", "foobar", "/foobar");
doTestGetPathWithinApplication("/", "foobar", "/foobar");
doTestGetPathWithinApplication("//", "foobar", "/foobar");
doTestGetPathWithinApplication("//", "//foobar", "/foobar");
doTestGetPathWithinApplication("/context-path", "/context-path/foobar", "/foobar");
doTestGetPathWithinApplication("/context-path", "/context-path/foobar/", "/foobar/");
doTestGetPathWithinApplication("//context-path", "//context-path/foobar", "/foobar");
doTestGetPathWithinApplication("//context-path", "//context-path//foobar", "/foobar");
doTestGetPathWithinApplication("//context-path", "//context-path/remove-one/remove-two/../../././/foobar", "/foobar");
doTestGetPathWithinApplication("//context-path", "//context-path//../../././/foobar", null);
doTestGetPathWithinApplication("/context%2525path", "/context%2525path/foobar", "/foobar");
doTestGetPathWithinApplication("/c%6Fntext%20path", "/c%6Fntext%20path/foobar", "/foobar");
doTestGetPathWithinApplication("/context path", "/context path/foobar", "/foobar");

}

void doTestGetPathWithinApplication(String contextPath, String requestUri, String expectedValue) {

def request = createMock(HttpServletRequest)
expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(contextPath)
expect(request.getAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE)).andReturn(requestUri)
expect(request.getCharacterEncoding()).andReturn("UTF-8").times(2)
replay request
assertEquals expectedValue, WebUtils.getPathWithinApplication(request)
verify request
}
}

0 comments on commit b15ab92

Please sign in to comment.