You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/12/29 16:21:48 UTC

svn commit: r894421 - in /cxf/branches/2.2.x-fixes: ./ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/

Author: sergeyb
Date: Tue Dec 29 15:21:44 2009
New Revision: 894421

URL: http://svn.apache.org/viewvc?rev=894421&view=rev
Log:
Updating JAXRS RequestImpl to evaluate If-None-Match

Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Dec 29 15:21:44 2009
@@ -1 +1 @@
-/cxf/trunk:891375-891393,891452,891817,891827,891859,891945-891946,892056,892307,892360,892664,892890,892920,892953,892988,893011,893250,893388-893389,893563,893773,894197
+/cxf/trunk:817055,891375-891393,891452,891817,891827,891859,891945-891946,892056,892307,892360,892664,892890,892920,892953,892988,893011,893250,893388-893389,893563,893773,894197

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java?rev=894421&r1=894420&r2=894421&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java Tue Dec 29 15:21:44 2009
@@ -28,10 +28,15 @@
     
     public EntityTag fromString(String header) {
         
+        
         if (header == null) {
             throw new IllegalArgumentException("ETag value can not be null");
         }
         
+        if ("*".equals(header)) {
+            return new EntityTag("*");
+        }
+        
         String tag = null;
         boolean weak =  false;
         int i = header.indexOf(WEAK_PREFIX);

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java?rev=894421&r1=894420&r2=894421&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java Tue Dec 29 15:21:44 2009
@@ -23,7 +23,6 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.HttpHeaders;
@@ -43,9 +42,11 @@
 public class RequestImpl implements Request {
     
     private final Message m;
+    private final HttpHeaders headers;
     
     public RequestImpl(Message m) {
         this.m = m;
+        this.headers = new HttpHeadersImpl(m);
     }
 
     
@@ -58,42 +59,82 @@
 
 
     public ResponseBuilder evaluatePreconditions(EntityTag eTag) {
-        String ifMatch = getHeaderValue(HttpHeaders.IF_MATCH);
+        ResponseBuilder rb = evaluateIfMatch(eTag);
+        if (rb == null) {
+            rb = evaluateIfNonMatch(eTag);
+        }
+        return rb;
+    }
+
+    private ResponseBuilder evaluateIfMatch(EntityTag eTag) {
+        List<String> ifMatch = headers.getRequestHeader(HttpHeaders.IF_MATCH);
         
-        if (ifMatch == null || ifMatch.equals("*")) {
+        if (ifMatch == null || ifMatch.size() == 0) {
             return null;
         }
         
         try {
-            EntityTag requestTag = EntityTag.valueOf(ifMatch);
-            if (requestTag.equals(eTag) && !requestTag.isWeak()) {
-                return null;
+            for (String value : ifMatch) {
+                if ("*".equals(value)) {
+                    return null;
+                }
+                EntityTag requestTag = EntityTag.valueOf(value);
+                // must be a strong comparison
+                if (!requestTag.isWeak() && !eTag.isWeak() && requestTag.equals(eTag)) {
+                    return null;
+                }
             }
         } catch (IllegalArgumentException ex) {
             // ignore
         }
-        
         return Response.status(Response.Status.PRECONDITION_FAILED).tag(eTag);
     }
 
-
-
-    public ResponseBuilder evaluatePreconditions(Date lastModified) {
-        String ifModifiedSince = getHeaderValue(HttpHeaders.IF_MODIFIED_SINCE);
+    private ResponseBuilder evaluateIfNonMatch(EntityTag eTag) {
+        List<String> ifNonMatch = headers.getRequestHeader(HttpHeaders.IF_NONE_MATCH);
         
-        if (ifModifiedSince == null) {
+        if (ifNonMatch == null || ifNonMatch.size() == 0) {
             return null;
         }
         
+        String method = getMethod();
+        boolean getOrHead = "GET".equals(method) || "HEAD".equals(method);
+        try {
+            for (String value : ifNonMatch) {
+                boolean result = "*".equals(value);
+                if (!result) {
+                    EntityTag requestTag = EntityTag.valueOf(value);
+                    result = getOrHead ? requestTag.equals(eTag) 
+                        : !requestTag.isWeak() && !eTag.isWeak() && requestTag.equals(eTag);
+                }
+                if (result) {
+                    Response.Status status = getOrHead ? Response.Status.NOT_MODIFIED
+                        : Response.Status.PRECONDITION_FAILED;
+                    return Response.status(status).tag(eTag);
+                }
+            }
+        } catch (IllegalArgumentException ex) {
+            // ignore
+        }
+        return null;
+    }
+    
+    public ResponseBuilder evaluatePreconditions(Date lastModified) {
+        List<String> ifModifiedSince = headers.getRequestHeader(HttpHeaders.IF_MODIFIED_SINCE);
+        
+        if (ifModifiedSince == null || ifModifiedSince.size() == 0) {
+            return evaluateIfNotModifiedSince(lastModified);
+        }
+        
         SimpleDateFormat dateFormat = HttpUtils.getHttpDateFormat();
 
         dateFormat.setLenient(false);
         Date dateSince = null;
         try {
-            dateSince = dateFormat.parse(ifModifiedSince);
+            dateSince = dateFormat.parse(ifModifiedSince.get(0));
         } catch (ParseException ex) {
             // invalid header value, request should continue
-            return null;
+            return Response.status(Response.Status.PRECONDITION_FAILED);
         }
         
         if (dateSince.before(lastModified)) {
@@ -103,6 +144,31 @@
         
         return Response.status(Response.Status.NOT_MODIFIED);
     }
+    
+    public ResponseBuilder evaluateIfNotModifiedSince(Date lastModified) {
+        List<String> ifNotModifiedSince = headers.getRequestHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
+        
+        if (ifNotModifiedSince == null || ifNotModifiedSince.size() == 0) {
+            return null;
+        }
+        
+        SimpleDateFormat dateFormat = HttpUtils.getHttpDateFormat();
+
+        dateFormat.setLenient(false);
+        Date dateSince = null;
+        try {
+            dateSince = dateFormat.parse(ifNotModifiedSince.get(0));
+        } catch (ParseException ex) {
+            // invalid header value, request should continue
+            return Response.status(Response.Status.PRECONDITION_FAILED);
+        }
+        
+        if (dateSince.before(lastModified)) {
+            return Response.status(Response.Status.PRECONDITION_FAILED);
+        }
+        
+        return null;
+    }
 
 
 
@@ -115,24 +181,10 @@
                 
     }
     
-    @SuppressWarnings("unchecked")
-    private String getHeaderValue(String name) {
-        Map<String, List<String>> headers = 
-            (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS);
-        if (headers == null) {
-            return null;
-        }
-        List<String> values = headers.get(name);
-        if (values == null || values.size() == 0) {
-            return null;
-        }
-        return values.get(0);
-    }
-
-
-
     public String getMethod() {
         return m.get(Message.HTTP_REQUEST_METHOD).toString();
     }
 
+
+
 }

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java?rev=894421&r1=894420&r2=894421&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java Tue Dec 29 15:21:44 2009
@@ -24,12 +24,14 @@
 import java.util.Locale;
 
 import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -76,7 +78,7 @@
     
     
     @Test
-    public void testStrictEtags() {
+    public void testStrictEtagsPreconditionMet() {
         metadata.putSingle("If-Match", new EntityTag("123").toString());
         
         ResponseBuilder rb = 
@@ -85,6 +87,17 @@
     }
     
     @Test
+    public void testStrictEtagsPreconditionNotMet() {
+        metadata.putSingle("If-Match", new EntityTag("123", true).toString());
+        
+        
+        ResponseBuilder rb = 
+            new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
+        assertEquals("Precondition must not be met, strict comparison is required", 
+                     412, rb.build().getStatus());
+    }
+    
+    @Test
     public void testStarEtags() {
         metadata.putSingle("If-Match", "*");
         
@@ -94,6 +107,36 @@
     }
     
     @Test
+    public void testStarEtagsIfNotMatch() {
+        metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "*");
+        
+        ResponseBuilder rb = 
+            new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
+        assertEquals("Precondition must not be met", 
+                     304, rb.build().getStatus());
+    }
+    
+    @Test
+    public void testEtagsIfNotMatch() {
+        metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "\"123\"");
+        
+        ResponseBuilder rb = 
+            new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
+        assertEquals("Precondition must not be met", 
+                     304, rb.build().getStatus());
+    }
+    
+    @Test
+    public void testStarEtagsIfNotMatchPut() {
+        metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "*");
+        m.put(Message.HTTP_REQUEST_METHOD, "PUT");
+        ResponseBuilder rb = 
+            new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
+        assertEquals("Precondition must not be met", 
+                     412, rb.build().getStatus());
+    }
+    
+    @Test
     public void testBeforeDate() throws Exception {
         metadata.putSingle("If-Modified-Since", "Tue, 21 Oct 2008 14:00:00 GMT");
         Date serverDate = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
@@ -105,6 +148,17 @@
     }
     
     @Test
+    public void testBeforeDateIfNotModified() throws Exception {
+        metadata.putSingle(HttpHeaders.IF_UNMODIFIED_SINCE, "Mon, 20 Oct 2008 14:00:00 GMT");
+        Date serverDate = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
+            .parse("Tue, 21 Oct 2008 14:00:00 GMT");
+        
+        ResponseBuilder rb = 
+            new RequestImpl(m).evaluatePreconditions(serverDate);
+        assertEquals("Precondition must not be met", 412, rb.build().getStatus());
+    }
+    
+    @Test
     public void testAfterDate() throws Exception {
         metadata.putSingle("If-Modified-Since", "Tue, 21 Oct 2008 14:00:00 GMT");
         Date lastModified = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)