Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Null Check for validateIfNoneMatch() method #34511

Closed
wants to merge 1 commit into from

Conversation

dk185173
Copy link

@dk185173 dk185173 commented Feb 28, 2025

Basic Null Check to avoid Null pointer exception if the header is not sent

Null check to avoid N.P.Es

Signed-off-by: Dineshotham Kumar Khambhammettu <[email protected]>
@dk185173 dk185173 changed the title Update ServletWebRequest.java Adding Null Pointer Exception for validateIfNoneMatch() method Feb 28, 2025
@dk185173 dk185173 changed the title Adding Null Pointer Exception for validateIfNoneMatch() method Adding Null Check for validateIfNoneMatch() method Feb 28, 2025
@dk185173
Copy link
Author

Please merge it so that this header is not mandatory

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 28, 2025
@bclozel
Copy link
Member

bclozel commented Feb 28, 2025

The HttpServletRequest API states the following for the getHeaders method:

If the request did not include any headers of the specified name, this method returns an empty Enumeration.

Did you encounter a NullPointerException in production? Can you provide a stacktrace?

@bclozel bclozel added the status: waiting-for-feedback We need additional information before we can continue label Feb 28, 2025
@dk185173
Copy link
Author

dk185173 commented Feb 28, 2025

@bclozel
Error encountered::

 Cannot invoke "java.util.Enumeration.hasMoreElements()" because "ifNoneMatchHeaders" is null"
stack: "java.lang.NullPointerException: Cannot invoke "java.util.Enumeration.hasMoreElements()" because "ifNoneMatchHeaders" is null
	at org.springframework.web.context.request.ServletWebRequest.validateIfNoneMatch(ServletWebRequest.java:240)
	at org.springframework.web.context.request.ServletWebRequest.checkNotModified(ServletWebRequest.java:218)
	at org.springframework.web.context.request.ServletWebRequest.checkNotModified(ServletWebRequest.java:192)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1079)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:685)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:794)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at com.intuit.fmis.common.http.filter.SetEncodingFilter.doFilter(SetEncodingFilter.java:38)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at com.intuit.sso.http.filter.USPFilter.doFilter(USPFilter.java:249)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at com.ncr.di.admin.swts.filter.AdminPlatformScopeFilter.normalLoginChain(AdminPlatformScopeFilter.java:502)
	at com.ncr.di.admin.swts.filter.AdminPlatformScopeFilter.doFilter(AdminPlatformScopeFilter.java:211)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at com.intuit.fmis.filter.InputValidationFilter.doFilter(InputValidationFilter.java:87)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:142)
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:362)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:278)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
	at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:261)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:356)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:857)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1685)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:833)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 28, 2025
@bclozel
Copy link
Member

bclozel commented Feb 28, 2025

Thanks for the feedback @dk185173 .

I believe the bug is somewhere else, but not in Spring. Maybe one of your custom filters is not wrapping the request properly and returns a null value here where it should return an empty enumeration.

I couldn't reproduce this behavior with a vanilla Spring application:

@Controller
public class TestController {

	@GetMapping("/")
	@ResponseBody
	public String test(ServletWebRequest request) {
		if (request.checkNotModified("test")) {
			return null;
		}
		return "test";
	}
}
➜  ~ http :8080/ -vv
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/3.2.4

HTTP/1.1 200
Connection: keep-alive
Content-Length: 4
Content-Type: text/plain;charset=UTF-8
Date: Fri, 28 Feb 2025 10:36:07 GMT
ETag: "test"
Keep-Alive: timeout=60

test

I'm closing this as a result.

@bclozel bclozel closed this Feb 28, 2025
@bclozel bclozel added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Feb 28, 2025
@dk185173
Copy link
Author

@bclozel We encountered this issue after we upgraded from Spring 5->Spring 6. It was working in Spring 5.

@bclozel
Copy link
Member

bclozel commented Feb 28, 2025

I guess all of your application dependencies changed as well, since the Spring 5 -> Spring 6 upgrade requires a javax->jakarta change.

From here, I think you can work on a minimal sample application, starting with the controller I've provided and add things bit by bit, starting witht the Servlet container you are using, then custom filters, etc. The bug is most probably on a Servlet request wrapper implementation. You can also use a debug break point and inspect the HttpServletRequest instance you are getting at this point: what's the concrete type, where does it come from, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants