/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.context.request;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import static org.junit.Assert.*;
/**
* Parameterized tests for ServletWebRequest
* @author Juergen Hoeller
* @author Brian Clozel
* @author Markus Malkusch
*/
@RunWith(Parameterized.class)
public class ServletWebRequestHttpMethodsTests {
private static final String CURRENT_TIME = "Wed, 09 Apr 2014 09:57:42 GMT";
private SimpleDateFormat dateFormat;
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse;
private ServletWebRequest request;
private Date currentDate;
@Parameter
public String method;
@Parameters(name = "{0}")
static public Iterable<Object[]> safeMethods() {
return Arrays.asList(new Object[][] {
{"GET"},
{"HEAD"}
});
}
@Before
public void setup() {
currentDate = new Date();
dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
servletRequest = new MockHttpServletRequest(method, "http://example.org");
servletResponse = new MockHttpServletResponse();
request = new ServletWebRequest(servletRequest, servletResponse);
}
@Test
public void checkNotModifiedNon2xxStatus() {
long epochTime = currentDate.getTime();
servletRequest.addHeader("If-Modified-Since", epochTime);
servletResponse.setStatus(304);
assertFalse(request.checkNotModified(epochTime));
assertEquals(304, servletResponse.getStatus());
assertNull(servletResponse.getHeader("Last-Modified"));
}
@Test // SPR-13516
public void checkNotModifiedInvalidStatus() {
long epochTime = currentDate.getTime();
servletRequest.addHeader("If-Modified-Since", epochTime);
servletResponse.setStatus(0);
assertFalse(request.checkNotModified(epochTime));
}
@Test // SPR-14559
public void checkNotModifiedInvalidIfNoneMatchHeader() {
String eTag = "\"etagvalue\"";
servletRequest.addHeader("If-None-Match", "missingquotes");
assertFalse(request.checkNotModified(eTag));
assertEquals(200, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedHeaderAlreadySet() {
long epochTime = currentDate.getTime();
servletRequest.addHeader("If-Modified-Since", epochTime);
servletResponse.addHeader("Last-Modified", CURRENT_TIME);
assertTrue(request.checkNotModified(epochTime));
assertEquals(304, servletResponse.getStatus());
assertEquals(1, servletResponse.getHeaders("Last-Modified").size());
assertEquals(CURRENT_TIME, servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkNotModifiedTimestamp() throws Exception {
long epochTime = currentDate.getTime();
servletRequest.addHeader("If-Modified-Since", epochTime);
assertTrue(request.checkNotModified(epochTime));
assertEquals(304, servletResponse.getStatus());
assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkModifiedTimestamp() {
long oneMinuteAgo = currentDate.getTime() - (1000 * 60);
servletRequest.addHeader("If-Modified-Since", oneMinuteAgo);
assertFalse(request.checkNotModified(currentDate.getTime()));
assertEquals(200, servletResponse.getStatus());
assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkNotModifiedETag() {
String eTag = "\"Foo\"";
servletRequest.addHeader("If-None-Match", eTag);
assertTrue(request.checkNotModified(eTag));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedETagWithSeparatorChars() {
String eTag = "\"Foo, Bar\"";
servletRequest.addHeader("If-None-Match", eTag);
assertTrue(request.checkNotModified(eTag));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkModifiedETag() {
String currentETag = "\"Foo\"";
String oldEtag = "Bar";
servletRequest.addHeader("If-None-Match", oldEtag);
assertFalse(request.checkNotModified(currentETag));
assertEquals(200, servletResponse.getStatus());
assertEquals(currentETag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedUnpaddedETag() {
String eTag = "Foo";
String paddedEtag = String.format("\"%s\"", eTag);
servletRequest.addHeader("If-None-Match", paddedEtag);
assertTrue(request.checkNotModified(eTag));
assertEquals(304, servletResponse.getStatus());
assertEquals(paddedEtag, servletResponse.getHeader("ETag"));
}
@Test
public void checkModifiedUnpaddedETag() {
String currentETag = "Foo";
String oldEtag = "Bar";
servletRequest.addHeader("If-None-Match", oldEtag);
assertFalse(request.checkNotModified(currentETag));
assertEquals(200, servletResponse.getStatus());
assertEquals(String.format("\"%s\"", currentETag), servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedWildcardIsIgnored() {
String eTag = "\"Foo\"";
servletRequest.addHeader("If-None-Match", "*");
assertFalse(request.checkNotModified(eTag));
assertEquals(200, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedETagAndTimestamp() {
String eTag = "\"Foo\"";
servletRequest.addHeader("If-None-Match", eTag);
servletRequest.addHeader("If-Modified-Since", currentDate.getTime());
assertTrue(request.checkNotModified(eTag, currentDate.getTime()));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified"));
}
@Test // SPR-14224
public void checkNotModifiedETagAndModifiedTimestamp() {
String eTag = "\"Foo\"";
servletRequest.addHeader("If-None-Match", eTag);
long currentEpoch = currentDate.getTime();
long oneMinuteAgo = currentEpoch - (1000 * 60);
servletRequest.addHeader("If-Modified-Since", oneMinuteAgo);
assertTrue(request.checkNotModified(eTag, currentEpoch));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
assertEquals(dateFormat.format(currentEpoch), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkModifiedETagAndNotModifiedTimestamp() throws Exception {
String currentETag = "\"Foo\"";
String oldEtag = "\"Bar\"";
servletRequest.addHeader("If-None-Match", oldEtag);
long epochTime = currentDate.getTime();
servletRequest.addHeader("If-Modified-Since", epochTime);
assertFalse(request.checkNotModified(currentETag, epochTime));
assertEquals(200, servletResponse.getStatus());
assertEquals(currentETag, servletResponse.getHeader("ETag"));
assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkNotModifiedETagWeakStrong() {
String eTag = "\"Foo\"";
String weakEtag = String.format("W/%s", eTag);
servletRequest.addHeader("If-None-Match", eTag);
assertTrue(request.checkNotModified(weakEtag));
assertEquals(304, servletResponse.getStatus());
assertEquals(weakEtag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedETagStrongWeak() {
String eTag = "\"Foo\"";
servletRequest.addHeader("If-None-Match", String.format("W/%s", eTag));
assertTrue(request.checkNotModified(eTag));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedMultipleETags() {
String eTag = "\"Bar\"";
String multipleETags = String.format("\"Foo\", %s", eTag);
servletRequest.addHeader("If-None-Match", multipleETags);
assertTrue(request.checkNotModified(eTag));
assertEquals(304, servletResponse.getStatus());
assertEquals(eTag, servletResponse.getHeader("ETag"));
}
@Test
public void checkNotModifiedTimestampWithLengthPart() throws Exception {
long epochTime = dateFormat.parse(CURRENT_TIME).getTime();
servletRequest.setMethod("GET");
servletRequest.addHeader("If-Modified-Since", "Wed, 09 Apr 2014 09:57:42 GMT; length=13774");
assertTrue(request.checkNotModified(epochTime));
assertEquals(304, servletResponse.getStatus());
assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkModifiedTimestampWithLengthPart() throws Exception {
long epochTime = dateFormat.parse(CURRENT_TIME).getTime();
servletRequest.setMethod("GET");
servletRequest.addHeader("If-Modified-Since", "Wed, 08 Apr 2014 09:57:42 GMT; length=13774");
assertFalse(request.checkNotModified(epochTime));
assertEquals(200, servletResponse.getStatus());
assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkNotModifiedTimestampConditionalPut() throws Exception {
long currentEpoch = currentDate.getTime();
long oneMinuteAgo = currentEpoch - (1000 * 60);
servletRequest.setMethod("PUT");
servletRequest.addHeader("If-UnModified-Since", currentEpoch);
assertFalse(request.checkNotModified(oneMinuteAgo));
assertEquals(200, servletResponse.getStatus());
assertEquals(null, servletResponse.getHeader("Last-Modified"));
}
@Test
public void checkNotModifiedTimestampConditionalPutConflict() throws Exception {
long currentEpoch = currentDate.getTime();
long oneMinuteAgo = currentEpoch - (1000 * 60);
servletRequest.setMethod("PUT");
servletRequest.addHeader("If-UnModified-Since", oneMinuteAgo);
assertTrue(request.checkNotModified(currentEpoch));
assertEquals(412, servletResponse.getStatus());
assertEquals(null, servletResponse.getHeader("Last-Modified"));
}
}