[jackson-jaxrs-providers] 81/162: Implement #6

Timo Aaltonen tjaalton at moszumanska.debian.org
Mon Sep 8 22:16:30 UTC 2014


This is an automated email from the git hooks/post-receive script.

tjaalton pushed a commit to branch master
in repository jackson-jaxrs-providers.

commit a25c4115e669441fb5af26270a6824014fc9f461
Author: Tatu Saloranta <tatu.saloranta at iki.fi>
Date:   Tue Jul 23 22:56:21 2013 -0700

    Implement #6
---
 .../fasterxml/jackson/jaxrs/base/ProviderBase.java | 111 +++++++++++++++++----
 .../jackson/jaxrs/cfg/EndpointConfigBase.java      |  12 +--
 .../fasterxml/jackson/jaxrs/cfg/JaxRSFeature.java  |  47 +++++++++
 release-notes/CREDITS                              |   6 ++
 release-notes/VERSION                              |   3 +
 5 files changed, 152 insertions(+), 27 deletions(-)

diff --git a/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java b/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java
index 73d128f..0742bf0 100644
--- a/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java
+++ b/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java
@@ -12,7 +12,6 @@ import javax.ws.rs.ext.MessageBodyWriter;
 import com.fasterxml.jackson.core.*;
 import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.databind.util.LRUMap;
-
 import com.fasterxml.jackson.jaxrs.cfg.*;
 import com.fasterxml.jackson.jaxrs.util.ClassKey;
 
@@ -28,6 +27,11 @@ public abstract class ProviderBase<
         Versioned
 {
     /**
+     * This header is useful on Windows, trying to deal with potential XSS attacks.
+     */
+    public final static String HEADER_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
+
+    /**
      * Looks like we need to worry about accidental
      *   data binding for types we shouldn't be handling. This is
      *   probably not a very good way to do it, but let's start by
@@ -105,6 +109,13 @@ public abstract class ProviderBase<
      */
     protected boolean _cfgCheckCanDeserialize = false;
 
+    /**
+     * Feature flags set.
+     * 
+     * @since 2.3.0
+     */
+    protected int _jaxRSFeatures;
+
     /*
     /**********************************************************
     /* Excluded types
@@ -241,36 +252,79 @@ public abstract class ProviderBase<
         _mapperConfig.setMapper(m);
     }
 
-    public THIS configure(DeserializationFeature f, boolean state) {
-        _mapperConfig.configure(f, state);
+    // // // JaxRSFeature config
+    
+    public THIS configure(JaxRSFeature feature, boolean state) {
+    	_jaxRSFeatures |= feature.getMask();
         return _this();
     }
 
-    public THIS configure(SerializationFeature f, boolean state) {
-        _mapperConfig.configure(f, state);
+    public THIS enable(JaxRSFeature feature) {
+    	_jaxRSFeatures |= feature.getMask();
         return _this();
     }
 
-    public THIS configure(JsonParser.Feature f, boolean state) {
-        _mapperConfig.configure(f, state);
+    public THIS enable(JaxRSFeature first, JaxRSFeature... f2) {
+    	_jaxRSFeatures |= first.getMask();
+    	for (JaxRSFeature f : f2) {
+        	_jaxRSFeatures |= f.getMask();
+    	}
+        return _this();
+    }
+    
+    public THIS disable(JaxRSFeature feature) {
+    	_jaxRSFeatures &= ~feature.getMask();
         return _this();
     }
 
-    public THIS configure(JsonGenerator.Feature f, boolean state) {
-        _mapperConfig.configure(f, state);
+    public THIS disable(JaxRSFeature first, JaxRSFeature... f2) {
+    	_jaxRSFeatures &= ~first.getMask();
+    	for (JaxRSFeature f : f2) {
+        	_jaxRSFeatures &= ~f.getMask();
+    	}
         return _this();
     }
 
+    public boolean isEnabled(JaxRSFeature f) {
+        return (_jaxRSFeatures & f.getMask()) != 0;
+    }
+    
+    // // // DeserializationFeature
+
+    public THIS configure(DeserializationFeature f, boolean state) {
+        _mapperConfig.configure(f, state);
+        return _this();
+    }
+    
     public THIS enable(DeserializationFeature f, boolean state) {
         _mapperConfig.configure(f, true);
         return _this();
     }
 
+    public THIS disable(DeserializationFeature f, boolean state) {
+        _mapperConfig.configure(f, false);
+        return _this();
+    }
+    
+    // // // SerializationFeature
+
+    public THIS configure(SerializationFeature f, boolean state) {
+        _mapperConfig.configure(f, state);
+        return _this();
+    }
+
     public THIS enable(SerializationFeature f, boolean state) {
         _mapperConfig.configure(f, true);
         return _this();
     }
 
+    public THIS disable(SerializationFeature f, boolean state) {
+        _mapperConfig.configure(f, false);
+        return _this();
+    }
+    
+    // // // JsonParser/JsonGenerator
+    
     public THIS enable(JsonParser.Feature f, boolean state) {
         _mapperConfig.configure(f, true);
         return _this();
@@ -281,23 +335,23 @@ public abstract class ProviderBase<
         return _this();
     }
 
-    public THIS disable(DeserializationFeature f, boolean state) {
+    public THIS disable(JsonParser.Feature f, boolean state) {
         _mapperConfig.configure(f, false);
         return _this();
     }
 
-    public THIS disable(SerializationFeature f, boolean state) {
+    public THIS disable(JsonGenerator.Feature f, boolean state) {
         _mapperConfig.configure(f, false);
         return _this();
     }
 
-    public THIS disable(JsonParser.Feature f, boolean state) {
-        _mapperConfig.configure(f, false);
+    public THIS configure(JsonParser.Feature f, boolean state) {
+        _mapperConfig.configure(f, state);
         return _this();
     }
 
-    public THIS disable(JsonGenerator.Feature f, boolean state) {
-        _mapperConfig.configure(f, false);
+    public THIS configure(JsonGenerator.Feature f, boolean state) {
+        _mapperConfig.configure(f, state);
         return _this();
     }
 
@@ -415,12 +469,13 @@ public abstract class ProviderBase<
         }
         return true;
     }
-
+    
     /**
      * Method that JAX-RS container calls to serialize given value.
      */
     @Override
-    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations,
+    		MediaType mediaType,
             MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) 
         throws IOException
     {
@@ -439,11 +494,12 @@ public abstract class ProviderBase<
             }
         }
 
+        // Any headers we should write?
+        _modifyHeaders(value, type, genericType, annotations, httpHeaders, endpoint);
+        
         ObjectWriter writer = endpoint.getWriter();
 
-        /* 27-Feb-2009, tatu: Where can we find desired encoding? Within
-         *   HTTP headers?
-         */
+        // Where can we find desired encoding? Within HTTP headers?
         JsonEncoding enc = findEncoding(mediaType, httpHeaders);
         JsonGenerator jg = writer.getFactory().createGenerator(entityStream, enc);
 
@@ -498,6 +554,21 @@ public abstract class ProviderBase<
         return JsonEncoding.UTF8;
     }
 
+    /**
+     * Overridable method used for adding optional response headers before
+     * serializing response object.
+     */
+    protected void _modifyHeaders(Object value, Class<?> type, Type genericType, Annotation[] annotations,
+            MultivaluedMap<String,Object> httpHeaders,
+            EP_CONFIG endpoint)
+        throws IOException
+    {
+        // [Issue#6]: Add "nosniff" header?
+        if (isEnabled(JaxRSFeature.ADD_NO_SNIFF_HEADER)) {
+            httpHeaders.add(HEADER_CONTENT_TYPE_OPTIONS, "nosniff");
+        }
+    }
+    
     /*
     /**********************************************************
     /* MessageBodyReader impl
diff --git a/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java
index 41496f0..a5ef5d3 100644
--- a/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java
+++ b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java
@@ -5,10 +5,8 @@ import java.lang.annotation.Annotation;
 import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
 import com.fasterxml.jackson.annotation.JsonRootName;
 import com.fasterxml.jackson.annotation.JsonView;
-
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.core.JsonParser;
-
 import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
 
@@ -19,11 +17,11 @@ import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
 public abstract class EndpointConfigBase<THIS extends EndpointConfigBase<THIS>>
 {
     // // General configuration
-    
-    protected Class<?> _activeView;
 
-    protected String _rootName;
+	protected Class<?> _activeView;
 
+    protected String _rootName;
+    
     // // Deserialization-only config
     
     protected DeserializationFeature[] _deserEnable;
@@ -140,13 +138,13 @@ public abstract class EndpointConfigBase<THIS extends EndpointConfigBase<THIS>>
         
         return (THIS) this;
     }
-
+    
     /*
     /**********************************************************
     /* Accessors
     /**********************************************************
      */
-
+    
     public final ObjectReader getReader() {
         if (_reader == null) { // sanity check, should never happen
             throw new IllegalStateException();
diff --git a/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/JaxRSFeature.java b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/JaxRSFeature.java
new file mode 100644
index 0000000..669b4e9
--- /dev/null
+++ b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/JaxRSFeature.java
@@ -0,0 +1,47 @@
+package com.fasterxml.jackson.jaxrs.cfg;
+
+import com.fasterxml.jackson.databind.cfg.ConfigFeature;
+
+/**
+ * Enumeration that defines simple on/off features that can be
+ * used on all Jackson JAX-RS providers, regardless of
+ * underlying data format.
+ */
+public enum JaxRSFeature implements ConfigFeature
+{
+    /*
+    /******************************************************
+    /* HTTP headers
+    /******************************************************
+     */
+    
+    /**
+     * Feature that can be enabled to make provider automatically
+     * add "nosniff" (see
+     * <a href="http://security.stackexchange.com/questions/20413/how-can-i-prevent-reflected-xss-in-my-json-web-services">this entry</a>
+     * for details
+     *<p>
+     * Feature is disabled by default.
+     */
+    ADD_NO_SNIFF_HEADER(false),
+
+    /*
+    /******************************************************
+    /* Other
+    /******************************************************
+     */
+
+    ;
+
+    private final boolean _defaultState;
+    
+    private JaxRSFeature(boolean defaultState) {
+        _defaultState = defaultState;
+    }
+
+    @Override
+    public boolean enabledByDefault() { return _defaultState; }
+
+    @Override
+    public int getMask() { return (1 << ordinal()); }
+}
diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index a54bdaa..e63ee6d 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -21,3 +21,9 @@ Michael Brackx (brackxm at github.com)
 
 * Requested #19: Add `InputStream` as unwritable class
  (2.2.3)
+
+Dain Sundstrom:
+
+* Suggested #6: Add `JaxRSFeature.ADD_NO_SNIFF_HEADER` to automatically add
+  X-Content-Type-Options header (works with IE)
+ (2.2.3)
diff --git a/release-notes/VERSION b/release-notes/VERSION
index de7eb7c..9d9ee44 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -5,6 +5,9 @@ Sub-modules:
   jackson-jaxrs-xml-provider
 Version: 2.2.3 (xx-xxx-2013)
 
+#6: Add `JaxRSFeature.ADD_NO_SNIFF_HEADER` to automatically add X-Content-Type-Options
+  header (works with IE)
+ (suggested by Dain S)
 #12, #16: More OSGi manifest fixes
  (reported by 'logoff at github')
 #18: Add LICENSE, NOTICE files in artifacts

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jackson-jaxrs-providers.git



More information about the pkg-java-commits mailing list