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 <[email protected]> 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 ([email protected]) * 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@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 _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

