Skip to content
Merged

Master #9969

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 @@ -18,7 +18,6 @@ package grails.artefact
import grails.artefact.controller.support.RequestForwarder
import grails.artefact.controller.support.ResponseRedirector
import grails.artefact.controller.support.ResponseRenderer
import grails.core.GrailsApplication
import grails.interceptors.Matcher
import grails.util.GrailsNameUtils
import grails.web.api.ServletAttributes
Expand All @@ -35,12 +34,8 @@ import org.grails.web.servlet.mvc.exceptions.ControllerExecutionException
import org.grails.web.servlet.view.CompositeViewResolver
import org.grails.web.util.GrailsApplicationAttributes
import org.grails.web.util.WebUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.Ordered
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.ViewResolver

import javax.annotation.PostConstruct
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.concurrent.ConcurrentLinkedQueue
Expand Down Expand Up @@ -95,10 +90,11 @@ trait Interceptor implements ResponseRenderer, ResponseRedirector, RequestForwar
def uri = req.requestURI

def matchedInfo = request.getAttribute(UrlMappingsHandlerMapping.MATCHED_REQUEST)

UrlMappingInfo grailsMappingInfo = (UrlMappingInfo)matchedInfo

for(Matcher matcher in allMatchers) {
if(matcher.doesMatch(uri, grailsMappingInfo)) {
if(matcher.doesMatch(uri, grailsMappingInfo, req.method)) {
request.setAttribute(interceptorMatchKey, Boolean.TRUE)
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ interface Matcher {
*/
boolean doesMatch(String uri, UrlMappingInfo info)

/**
* Perform the matches using the http method of the request instead of the UrlMappingInfo
* @param uri
* @param info
* @param method
* @return
*/
boolean doesMatch(String uri, UrlMappingInfo info, String method)

/**
* Defines the match for the given arguments
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class UrlMappingMatcher implements Matcher {
}

boolean doesMatch(String uri, UrlMappingInfo info) {
return doesMatch(uri, info, null)
}

boolean doesMatch(String uri, UrlMappingInfo info, String method) {
boolean hasUriPatterns = !uriPatterns.isEmpty()

boolean isExcluded = this.isExcluded(uri, info)
Expand All @@ -75,7 +79,7 @@ class UrlMappingMatcher implements Matcher {
Boolean matched = CACHED_MATCHES.get(infoCode)
if (matched != null) return matched

if (doesMatchInternal(info)) {
if (doesMatchInternal(info, method)) {
if (Environment.current == Environment.PRODUCTION) {
CACHED_MATCHES.put(infoCode, Boolean.TRUE)
}
Expand All @@ -100,12 +104,12 @@ class UrlMappingMatcher implements Matcher {
false
}

protected boolean doesMatchInternal(UrlMappingInfo info) {
protected boolean doesMatchInternal(UrlMappingInfo info, String method) {
(info != null &&
((info.controllerName ?: '') ==~ controllerRegex) &&
((info.actionName ?: '') ==~ actionRegex) &&
((info.namespace ?: '') ==~ namespaceRegex) &&
((info.httpMethod ?: '') ==~ methodRegex))
((method ?: info.httpMethod ?: '') ==~ methodRegex))
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import org.grails.web.mapping.DefaultUrlMappingInfo
import org.grails.web.mapping.ForwardUrlMappingInfo
import org.grails.web.mapping.mvc.UrlMappingsHandlerMapping
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.mock.web.MockServletContext
import org.springframework.web.context.request.RequestContextHolder
import spock.lang.Specification

Expand Down Expand Up @@ -156,6 +159,25 @@ class InterceptorSpec extends Specification {
then:"We don't match"
i.doesMatch()
}

void "Test match with http method"() {
given:"A test interceptor"
def i = new TestMethodInterceptor()
def webRequest = GrailsWebMockUtil.bindMockWebRequest(new MockServletContext(), new MockHttpServletRequest(httpMethod, ""), new MockHttpServletResponse())
def request = webRequest.request

when:"The http method of the current request is ${httpMethod}"
request.setAttribute(UrlMappingsHandlerMapping.MATCHED_REQUEST, new ForwardUrlMappingInfo(controllerName: "test", action: "save"))

then: "We match: ${shouldMatch}"
i.doesMatch() == shouldMatch

where:
httpMethod | shouldMatch
'POST' | true
'GET' | false
}

void clearMatch(i, HttpServletRequest request) {
request.removeAttribute(i.getClass().name + InterceptorArtefactHandler.MATCH_SUFFIX)
}
Expand Down Expand Up @@ -197,4 +219,10 @@ class Test4Interceptor implements Interceptor {
matchAll()
.excludes(controller:"foo", action:"bar")
}
}
}

class TestMethodInterceptor implements Interceptor {
TestMethodInterceptor() {
match(method: 'POST')
}
}