You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by nf...@apache.org on 2009/07/14 07:21:11 UTC
svn commit: r793795 - in /incubator/wink/trunk:
wink-common/src/main/java/org/apache/wink/common/internal/providers/header/
wink-server/src/main/java/org/apache/wink/server/internal/contexts/
wink-server/src/test/java/org/apache/wink/server/internal/
Author: nfischer
Date: Tue Jul 14 05:21:10 2009
New Revision: 793795
URL: http://svn.apache.org/viewvc?rev=793795&view=rev
Log:
Fix for inconsistent behavior for mis-quoted etag header values [WINK-72]
Modified:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/EntityTagHeaderDelegate.java
incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/contexts/RequestImpl.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/PreconditionsTest.java
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/EntityTagHeaderDelegate.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/EntityTagHeaderDelegate.java?rev=793795&r1=793794&r2=793795&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/EntityTagHeaderDelegate.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/EntityTagHeaderDelegate.java Tue Jul 14 05:21:10 2009
@@ -41,8 +41,8 @@
}
// Check that e-tag is quoted-string
- if (!eTag.startsWith("\"") && !eTag.endsWith("\"")) {
- throw new IllegalArgumentException(" Entity Tag " + eTag + " is not quoted");
+ if (!eTag.startsWith("\"") || !eTag.endsWith("\"")) {
+ throw new IllegalArgumentException("Entity Tag " + eTag + " is not quoted properly");
}
// Remove quotes
Modified: incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/contexts/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/contexts/RequestImpl.java?rev=793795&r1=793794&r2=793795&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/contexts/RequestImpl.java (original)
+++ incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/contexts/RequestImpl.java Tue Jul 14 05:21:10 2009
@@ -27,10 +27,12 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.Variant;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.RuntimeDelegate;
@@ -76,7 +78,13 @@
* returns ResponseBuilder if none of the tags matched
*/
private ResponseBuilder evaluateIfMatch(EntityTag tag, String headerValue) {
- EntityTagMatchHeader ifMatchHeader = ifMatchHeaderDelegate.fromString(headerValue);
+ EntityTagMatchHeader ifMatchHeader = null;
+ try {
+ ifMatchHeader = ifMatchHeaderDelegate.fromString(headerValue);
+ } catch (IllegalArgumentException e) {
+ throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
+ }
+
if (!ifMatchHeader.isMatch(tag)) {
// none of the tags matches the etag
ResponseBuilder responseBuilder = delegate.createResponseBuilder();
@@ -90,7 +98,13 @@
* returns ResponseBuilder if any of the tags matched
*/
private ResponseBuilder evaluateIfNoneMatch(EntityTag tag, String headerValue) {
- EntityTagMatchHeader ifNoneMatchHeader = ifMatchHeaderDelegate.fromString(headerValue);
+ EntityTagMatchHeader ifNoneMatchHeader = null;
+ try {
+ ifNoneMatchHeader = ifMatchHeaderDelegate.fromString(headerValue);
+ } catch (IllegalArgumentException e) {
+ throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
+ }
+
if (ifNoneMatchHeader.isMatch(tag)) {
// some tag matched
ResponseBuilder responseBuilder = delegate.createResponseBuilder();
Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/PreconditionsTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/PreconditionsTest.java?rev=793795&r1=793794&r2=793795&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/PreconditionsTest.java (original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/PreconditionsTest.java Tue Jul 14 05:21:10 2009
@@ -252,6 +252,84 @@
assertEquals("status", 200, response.getStatus());
}
+
+ /**
+ * ensure multiple etags are supported
+ */
+ public void testConditionIfMatchesMultipleOnSingleHeader() throws Exception {
+ String etag = "blablabla";
+
+ // GET
+ MockHttpServletRequest request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ request.addHeader(HttpHeaders.IF_MATCH, "\"atlantic\",\"" + etag + "\",\"pacific\"");
+ MockHttpServletResponse response = invoke(request);
+ assertEquals("status", 200, response.getStatus());
+
+ // PUT
+ request = MockRequestConstructor.constructMockRequest("PUT", "get/" + etag, "*/*");
+ request.addHeader(HttpHeaders.IF_MATCH, "\"atlantic\",\"" + etag + "\",\"pacific\"");
+ response = invoke(request);
+ assertEquals("status", 200, response.getStatus());
+ }
+
+ /**
+ * ETags not wrapped in quotes are invalid. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
+ */
+ public void testConditionIfMatchesUnquoted() throws Exception {
+ String etag = "blablabla";
+
+ MockHttpServletRequest request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // no quotes
+ request.addHeader(HttpHeaders.IF_MATCH, etag);
+ MockHttpServletResponse response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // beginning quote only
+ request.addHeader(HttpHeaders.IF_MATCH, "\"" + etag);
+ response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // end quote only
+ request.addHeader(HttpHeaders.IF_MATCH, etag + "\"");
+ response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ }
+
+ /**
+ * ETags not wrapped in quotes are invalid. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
+ */
+ public void testConditionIfNoneMatchesUnquoted() throws Exception {
+ String etag = "blablabla";
+
+ MockHttpServletRequest request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // no quotes
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, etag);
+ MockHttpServletResponse response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // beginning quote only
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, "\"" + etag);
+ response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ // end quote only
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, etag + "\"");
+ response = invoke(request);
+ assertEquals("status", 400, response.getStatus());
+
+ }
public void testConditionGetNotIfMatches() throws Exception {
String etag = "blablabla";
@@ -288,6 +366,29 @@
assertEquals("status", 200, response.getStatus());
}
+
+
+ /**
+ * ensure multiple etags are supported. These are strange tests; I need to ensure it goes through
+ * the IF_NONE_MATCH code and hits the second string in the IF_NONE_MATCH header, so I want a 304 or 412 response.
+ */
+ public void testConditionIfNoneMatchesMultipleOnSingleHeader() throws Exception {
+ String etag = "blablabla";
+
+ // GET
+ MockHttpServletRequest request = MockRequestConstructor.constructMockRequest("GET", "get/"
+ + etag, "*/*");
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, "\"atlantic\",\"" + etag + "\",\"pacific\"");
+ MockHttpServletResponse response = invoke(request);
+ assertEquals("status", 304, response.getStatus());
+
+ // PUT
+ request = MockRequestConstructor.constructMockRequest("PUT", "get/" + etag, "*/*");
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, "\"atlantic\",\"" + etag + "\",\"pacific\"");
+ response = invoke(request);
+ assertEquals("status", 412, response.getStatus());
+
+ }
public void testConditionNoteIfNoneMatches() throws Exception {
String etag = "blablabla";