restlet/restlet-framework-java — pull request #592 by adennie (2012-05-18 16:30:57+00:00)
Title: fix issue #568 - strict conneg should return 406 if no acceptable varian...

...t

Use case:

Client does a conditional GET with an Accept header specifying a media
type not advertised by the target resource (via its @get annotation).

The current state of the resource satisfies the condition.

The server has requested strict content negotation

Current behavior: ServerResource.doConditionalHandle() gets a null Variant
back from getPreferredVariant() and passes this to
doGetInfo(Variant target), which calls doGetInfo(), i.e. the variation
with no params. If any registered converter is able to produce a
representation for a null target Variant (e.g. GwtConverter), then
whichever one of those converters "wins" will produce a representation that
gets returned back to doConditionalHandle. Later in that method, the
following code is executed:

if ((Method.GET.equals(​getMethod()) || Method.HEAD
.equals(getMethod()))
&& resultInfo instanceof Representation) {
result = (Representation) resultInfo;

and since the if() statement is true, it proceeds to return the result, and
the client gets back the converter-generated representation instead of a
406.

The fix: in doConditionalHandle(), change

if (existing) {
if (isNegotiated()) {
resultInfo = doGetInfo(getPreferredVariant(getVariants(Method.GET)));
}
to

if (existing) {
if (isNegotiated()) {
Variant preferredVariant = getPreferredVariant(getVariants(Method.GET));
if (preferredVariant == null
&& getConnegService().isStrict()) {
doError(Status.CLIENT_ERROR_NOT_ACCEPTABLE);
} else {
resultInfo = doGetInfo(preferredVariant);
}