Merge remote-tracking branch 'origin/jetty-9.3.x' into jetty-9.4.x
This commit is contained in:
commit
25574d2843
|
@ -23,7 +23,6 @@ import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple Jetty FileServer.
|
* Simple Jetty FileServer.
|
||||||
|
@ -41,6 +40,7 @@ public class FileServer
|
||||||
// Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is
|
// Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is
|
||||||
// a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples.
|
// a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples.
|
||||||
ResourceHandler resource_handler = new ResourceHandler();
|
ResourceHandler resource_handler = new ResourceHandler();
|
||||||
|
|
||||||
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
|
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
|
||||||
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
|
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
|
||||||
resource_handler.setDirectoriesListed(true);
|
resource_handler.setDirectoriesListed(true);
|
||||||
|
@ -48,11 +48,8 @@ public class FileServer
|
||||||
resource_handler.setResourceBase(".");
|
resource_handler.setResourceBase(".");
|
||||||
|
|
||||||
// Add the ResourceHandler to the server.
|
// Add the ResourceHandler to the server.
|
||||||
GzipHandler gzip = new GzipHandler();
|
|
||||||
server.setHandler(gzip);
|
|
||||||
HandlerList handlers = new HandlerList();
|
HandlerList handlers = new HandlerList();
|
||||||
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
|
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
|
||||||
gzip.setHandler(handlers);
|
|
||||||
|
|
||||||
// Start things up! By using the server.join() the server thread will join with the current thread.
|
// Start things up! By using the server.join() the server thread will join with the current thread.
|
||||||
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
|
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
|
||||||
|
|
|
@ -30,15 +30,12 @@ For a more in-depth look at the syntax, see xref:jetty-xml-syntax[].
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
..
|
..
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
____
|
____
|
||||||
|
|
|
@ -80,41 +80,27 @@ bar.getParent().setName("demo2");
|
||||||
===== Understanding DTD and Parsing
|
===== Understanding DTD and Parsing
|
||||||
|
|
||||||
The document type descriptor
|
The document type descriptor
|
||||||
(link:{GITBROWSEURL}/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd?h=release-9[configure.dtd])
|
(link:{GITBROWSEURL}/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd?h=release-9[configure.dtd]) describes all valid elements in a Jetty XML configuration file using the Jetty IoC format.
|
||||||
describes all valid elements in a Jetty XML configuration file using the
|
The first two lines of an XML must reference the DTD to be used to validate the XML like:
|
||||||
Jetty IoC format. The first two lines of an XML must reference the DTD
|
|
||||||
to be used to validate the XML like:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
|
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Typcically a good XML editor will fetch the DTD from the URL and use it
|
Typcically a good XML editor will fetch the DTD from the URL and use it to give syntax highlighting and validation while a configuration file is being edited.
|
||||||
to give syntax highlighting and validation while a configuration file is
|
Some editors also allows DTD files to be locally cached.
|
||||||
being edited. Some editors also allows DTD files to be locally cached.
|
The URL may point to configure.dtd if you want the latest current version, or to a specific version like configure_9_0.dtd if you want a particular validation feature set.
|
||||||
The URL may point to configure.dtd if you want the latest current
|
|
||||||
version, or to a specific version like configure_9_0.dtd if you want a
|
|
||||||
particular validation feature set.
|
|
||||||
|
|
||||||
Files that conform to the configure.dtd format are processed in Jetty by
|
Files that conform to the configure.dtd format are processed in Jetty by the `XmlConfiguration` class which may also validate the XML (using a version of the DTD from the classes jar file), but is by default run in a forgiving mode that tries to work around validation failures.
|
||||||
the `XmlConfiguration` class which may also validate the XML (using a
|
|
||||||
version of the DTD from the classes jar file), but is by default run in
|
|
||||||
a forgiving mode that tries to work around validation failures.
|
|
||||||
|
|
||||||
===== Jetty XML Configuration Scope
|
===== Jetty XML Configuration Scope
|
||||||
|
|
||||||
The configuration of object instances with Jetty IoC XML is done on a
|
The configuration of object instances with Jetty IoC XML is done on a scoped basis, so that for any given XML element there is a corresponding Object in scope and the nested XML elements apply to that.
|
||||||
scoped basis, so that for any given XML element there is a corresponding
|
The outer most scope is given by a Configure element and elements like Call, New and Get establish new scopes.
|
||||||
Object in scope and the nested XML elements apply to that. The outer
|
The following example uses the name fields to explain the scope.
|
||||||
most scope is given by a Configure element and elements like Call, New
|
|
||||||
and Get establish new scopes. The following example uses the name fields
|
|
||||||
to explain the scope
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -134,50 +120,36 @@ to explain the scope
|
||||||
<Call name="methodOnObjectReturnedByMethodOnFooWithNoArgs"/>
|
<Call name="methodOnObjectReturnedByMethodOnFooWithNoArgs"/>
|
||||||
</Call>
|
</Call>
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
===== Coercing Arguments to a Type
|
===== Coercing Arguments to a Type
|
||||||
|
|
||||||
When trying to match XML elements to java elements, Jetty
|
When trying to match XML elements to java elements, Jetty `XmlConfiguration` may need to coerces values to match method arguments.
|
||||||
XmlConfiguration may need to coerces values to match method arguments.
|
By default it does so on a best effort basis, but you can also specify explicit types with the `type` attribute.
|
||||||
By default it does so on a best effort basis, but you can also specify
|
Supported values for type are: `String`, `Character`, `Short`, `Byte`, `Integer`, `Long`, `Boolean`, `Float`, `Double`, `char`, `short`, `byte`, `int`, `long`, `boolean`, `float`, `double`, `URL`, `InetAddress`, `InetAddrPort`, and `void`.
|
||||||
explicit types with the `type` attribute. Supported values for type are:
|
|
||||||
String, Character, Short, Byte, Integer, Long, Boolean, Float, Double,
|
|
||||||
char, short, byte, int, long, boolean, float, double, URL, InetAddress,
|
|
||||||
InetAddrPort, void
|
|
||||||
|
|
||||||
===== Referring to a Class
|
===== Referring to a Class
|
||||||
|
|
||||||
If you do not specify the classname, Jetty assumes you are calling the
|
If you do not specify the classname, Jetty assumes you are calling the method on the object that is current in scope (eg the object of the surrounding `Configure`, `New` or `Get` clause).
|
||||||
method on the object that is current in scope (eg the object of the
|
If the class attribute is specified to a fully-qualified class name, then it is either used to create a new instance (`Configure` and `New` elements) or is used to access a static (`Call`, `Set` or `Get` elements).
|
||||||
surrounding Configure, New or Get clause). If the class attribute is
|
|
||||||
specified to a fully-qualified class name, then it is either used to
|
|
||||||
create a new instance (Configure and New elements) or is used to access
|
|
||||||
a static (Call, Set or Get elements).
|
|
||||||
|
|
||||||
===== Referring to an Object
|
===== Referring to an Object
|
||||||
|
|
||||||
You can use the id attribute to store a reference to the current object
|
You can use the id attribute to store a reference to the current object when first creating or referring to this object.
|
||||||
when first creating or referring to this object. You can then use the
|
You can then use the link:#jetty-xml-ref[Ref element] to reference the object later.
|
||||||
link:#jetty-xml-ref[Ref element] to reference the object later. The id
|
The ID must be unique for each object you create.
|
||||||
must be unique for each object you create.
|
|
||||||
|
|
||||||
===== Attribute vs Element Style
|
===== Attribute vs Element Style
|
||||||
|
|
||||||
For XML elements that contain only other XML Elements, there is a choice
|
For XML elements that contain only other XML Elements, there is a choice of using attributes or elements style.
|
||||||
of using attributes or elements style. The following is an example of
|
The following is an example of attribute style:
|
||||||
attribute style:
|
|
||||||
|
|
||||||
....
|
....
|
||||||
<Call id="result" class="org.example.SomeClass" name="someMethod" arg="value0,value1"/>
|
<Call id="result" class="org.example.SomeClass" name="someMethod" arg="value0,value1"/>
|
||||||
....
|
....
|
||||||
|
|
||||||
Attribute style has the benefit of brevity, but is limited by: values
|
Attribute style has the benefit of brevity, but is limited by: values can only be Strings; multivalued items can not contain ','; values may not be subject to property expansion or other elements that return values.
|
||||||
can only be Strings; multivalued items can not contain ','; values may
|
Thus, the more verbose element style is available and the following is semantically equivalent to the attribute style above:
|
||||||
not be subject to property expansion or other elements that return
|
|
||||||
values. Thus the more verbose element style is available and the
|
|
||||||
following is semantically equivalent to the attribute style above:
|
|
||||||
|
|
||||||
....
|
....
|
||||||
<Call>
|
<Call>
|
||||||
|
@ -189,11 +161,8 @@ following is semantically equivalent to the attribute style above:
|
||||||
</Call>
|
</Call>
|
||||||
....
|
....
|
||||||
|
|
||||||
Note that multivalued elements like Arg, must be repeated and may not be
|
Note that multivalued elements like `Arg` must be repeated and may not be comma-separated like they are when provided as attributes.
|
||||||
comma separated like they are when provided as attributes. It is
|
It is possible to use a mix of styles and the following example shows a moretypical example that uses property expansion as the reason for element style:
|
||||||
possible to use a mix of styles and the following example shows a more
|
|
||||||
typical example that uses property expansion as the reason for element
|
|
||||||
style:
|
|
||||||
|
|
||||||
....
|
....
|
||||||
<Call id="result" name="someMethod">
|
<Call id="result" name="someMethod">
|
||||||
|
@ -205,16 +174,14 @@ style:
|
||||||
</Call>
|
</Call>
|
||||||
....
|
....
|
||||||
|
|
||||||
Attributes may not be expressed as elements when their parent element is
|
Attributes may not be expressed as elements when their parent element is one that contains data.
|
||||||
one that contains data. Thus Arg, Item, Set, Put and Get elements may
|
Thus `Arg`, `Item`, `Set`, `Put` and `Get` elements may not have their attributes expressed as elements.
|
||||||
not have their attributes expressed as elements.
|
|
||||||
|
|
||||||
[[jetty-xml-configure]]
|
[[jetty-xml-configure]]
|
||||||
==== <Configure>
|
==== <Configure>
|
||||||
|
|
||||||
This is the root element that specifies the class of object that is to
|
This is the root element that specifies the class of object that is to be configured.
|
||||||
be configured. It is usually either the Server, in `jetty.xml`, or a
|
It is usually either the Server, in `jetty.xml`, or a `WebAppContext` in `jetty-web.xml`.
|
||||||
WebAppContext in `jetty-web.xml`.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -226,8 +193,8 @@ You can use this to break up configuration of an object (such as the
|
||||||
Server) across multiple files.
|
Server) across multiple files.
|
||||||
|
|
||||||
|class |no |The fully qualified classname of the object to be
|
|class |no |The fully qualified classname of the object to be
|
||||||
configured. Could be org.eclipse.jetty.server.Server,
|
configured. Could be `org.eclipse.jetty.server.Server`,
|
||||||
org.eclipse.jetty.webapp.WebAppContext, a handler, etc.
|
`org.eclipse.jetty.webapp.WebAppContext`, a handler, etc.
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
===== Can Contain
|
===== Can Contain
|
||||||
|
@ -257,10 +224,9 @@ org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server();
|
||||||
server.setPort(8080);
|
server.setPort(8080);
|
||||||
----
|
----
|
||||||
|
|
||||||
====== Using id to break up configuration of one object across multiple
|
====== Using id to break up configuration of one object across multiple files
|
||||||
files
|
|
||||||
|
|
||||||
(etc/jetty.xml)
|
In `etc/jetty.xml`:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -269,7 +235,7 @@ files
|
||||||
</Configure>
|
</Configure>
|
||||||
----
|
----
|
||||||
|
|
||||||
(etc/jetty-logging.xml)
|
In `etc/jetty-logging.xml`:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -287,13 +253,11 @@ java -jar start.jar etc/jetty.xml jetty-logging.xml
|
||||||
[[jetty-xml-set]]
|
[[jetty-xml-set]]
|
||||||
==== <Set>
|
==== <Set>
|
||||||
|
|
||||||
A Set element maps to a call to a setter method or field on the current
|
A Set element maps to a call to a setter method or field on the current object.
|
||||||
object. It can contain text and/or elements such as Call, New,
|
It can contain text and/or elements such as `Call`, `New`, `SystemProperty`, etc., as values.
|
||||||
SystemProperty, etc., as values. The name and optional type attributes
|
The name and optional type attributes are used to select the setter method.
|
||||||
are used to select the setter method. If you do not specify a value
|
If you do not specify a value type, white space is trimmed out of the value.
|
||||||
type, white space is trimmed out of the value. If it contains multiple
|
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
|
||||||
elements as values, they are added as strings before being converted to
|
|
||||||
any specified type.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -370,15 +334,14 @@ server.setThreadPool(threadPool);
|
||||||
----
|
----
|
||||||
<Configure id="server" class="org.eclipse.jetty.server.Server">
|
<Configure id="server" class="org.eclipse.jetty.server.Server">
|
||||||
<Set class="org.eclipse.jetty.util.log.Log" name="logToParent">loggerName</Set>
|
<Set class="org.eclipse.jetty.util.log.Log" name="logToParent">loggerName</Set>
|
||||||
</Configure">
|
</Configure>
|
||||||
----
|
----
|
||||||
|
|
||||||
[[jetty-xml-get]]
|
[[jetty-xml-get]]
|
||||||
==== <Get>
|
==== <Get>
|
||||||
|
|
||||||
A Get element maps to a call to a getter method or field on the current
|
A Get element maps to a call to a getter method or field on the current object.
|
||||||
object. It can contain nested elements such as Set, Put, Call, etc.;
|
It can contain nested elements such as `Set`, `Put`, `Call`, etc.; these act on the object returned by the `Get` call.
|
||||||
these act on the object returned by the Get call.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -406,8 +369,8 @@ link:#jetty-xml-property[Property element]
|
||||||
|
|
||||||
====== Basic Example
|
====== Basic Example
|
||||||
|
|
||||||
This simple example doesn't do much on its own. You would normally use
|
This simple example doesn't do much on its own.
|
||||||
this in conjunction with a <Ref id="Logger" />.
|
You would normally use this in conjunction with a `<Ref id="Logger" />`.
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -432,12 +395,10 @@ this in conjunction with a <Ref id="Logger" />.
|
||||||
[[jetty-xml-put]]
|
[[jetty-xml-put]]
|
||||||
==== <Put>
|
==== <Put>
|
||||||
|
|
||||||
A Put element maps to a call to a put method on the current object,
|
A Put element maps to a call to a put method on the current object, which must implement the Map interface.
|
||||||
which must implement the Map interface. It can contain text and/or
|
It can contain text and/or elements such as `Call`, `New`, `SystemProperty`, etc. as values.
|
||||||
elements such as Call, New, SystemProperty, etc. as values. If you do
|
If you do not specify a no value type, white space is trimmed out of the value.
|
||||||
not specify a no value type, white space is trimmed out of the value. If
|
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
|
||||||
it contains multiple elements as values, they are added as strings
|
|
||||||
before being converted to any specified type.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -450,7 +411,7 @@ Arg for how to define null and empty string values.
|
||||||
|
|
||||||
===== Can Contain
|
===== Can Contain
|
||||||
|
|
||||||
value text , link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call
|
value text, link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call
|
||||||
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
|
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
|
||||||
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
|
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
|
||||||
element], link:#jetty-xml-system-property[System Property element],
|
element], link:#jetty-xml-system-property[System Property element],
|
||||||
|
@ -468,11 +429,9 @@ link:#jetty-xml-property[Property element]
|
||||||
[[jetty-xml-call]]
|
[[jetty-xml-call]]
|
||||||
==== <Call>
|
==== <Call>
|
||||||
|
|
||||||
A Call element maps to an arbitrary call to a method on the current
|
A `Call` element maps to an arbitrary call to a method on the current object.
|
||||||
object. It can contain a sequence of Arg elements followed by a sequence
|
It can contain a sequence of Arg elements followed by a sequence of configuration elements, such as Set, Put, Call.
|
||||||
of configuration elements, such as Set, Put, Call. The <Arg>s are passed
|
The <Arg>s are passed as arguments to the method; the sequence of configuration elements act on the object returned by the original call.
|
||||||
as arguments to the method; the sequence of configuration elements act
|
|
||||||
on the object returned by the original call.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -527,7 +486,7 @@ o2.setTest("1, 2, 3");
|
||||||
</Call>
|
</Call>
|
||||||
----
|
----
|
||||||
|
|
||||||
which is equivalent to:
|
Which is equivalent to:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -548,7 +507,7 @@ com.acme.Foo.setString("somestring");
|
||||||
</Configure>
|
</Configure>
|
||||||
----
|
----
|
||||||
|
|
||||||
which is equivalent to:
|
Which is equivalent to:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -562,13 +521,11 @@ com.acme.Environment.setPort( server.getPort() );
|
||||||
An Arg element can be an argument of either a method or a constructor.
|
An Arg element can be an argument of either a method or a constructor.
|
||||||
Use it within xref:jetty-syntax-call[] and xref:jetty-syntax-new[].
|
Use it within xref:jetty-syntax-call[] and xref:jetty-syntax-new[].
|
||||||
|
|
||||||
It can contain text and/or elements, such as Call, New, SystemProperty,
|
It can contain text and/or elements, such as `Call`, `New`, `SystemProperty`, etc., as values.
|
||||||
etc., as values. The optional type attribute can force the type of the
|
The optional type attribute can force the type of the value.
|
||||||
value. If you don't specify a type, white space is trimmed out of the
|
If you don't specify a type, white space is trimmed out of the value.
|
||||||
value. If it contains multiple elements as values, they are added as
|
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
|
||||||
strings before being converted to any specified type. Simple String
|
Simple `String` arguments can also be specified as a string separated arg attribute on the parent element.
|
||||||
arguments can also be specified as a string separated arg attribute on
|
|
||||||
the parent element.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -597,7 +554,7 @@ link:#jetty-xml-property[Property element]
|
||||||
<Arg>1</Arg> <!-- int, long, short, float, double -->
|
<Arg>1</Arg> <!-- int, long, short, float, double -->
|
||||||
<Arg><Ref refid="foo" /></Arg> <!-- any object; reference a previously created object with id "foo", and pass it as a parameter -->
|
<Arg><Ref refid="foo" /></Arg> <!-- any object; reference a previously created object with id "foo", and pass it as a parameter -->
|
||||||
<Arg></Arg> <!-- null value -->
|
<Arg></Arg> <!-- null value -->
|
||||||
<Arg type="String"></Arg> <!-- empty string "" ->
|
<Arg type="String"></Arg> <!-- empty string "" -->
|
||||||
----
|
----
|
||||||
|
|
||||||
====== Coercing Type
|
====== Coercing Type
|
||||||
|
@ -611,8 +568,7 @@ This explicitly coerces the type to a boolean:
|
||||||
|
|
||||||
====== As a Parameter
|
====== As a Parameter
|
||||||
|
|
||||||
Here are a couple of examples of link:#jetty-xml-arg[Arg element] being
|
Here are a couple of examples of link:#jetty-xml-arg[Arg element] being used as a parameter to methods and to constructors:
|
||||||
used as a parameter to methods and to constructors:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -653,13 +609,11 @@ new com.acme.Baz(com.acme.MyStaticObjectFactory.createObject(2));
|
||||||
[[jetty-xml-new]]
|
[[jetty-xml-new]]
|
||||||
==== <New>
|
==== <New>
|
||||||
|
|
||||||
Instantiates an object. Equivalent to new in Java, and allows the
|
Instantiates an object.
|
||||||
creation of a new object. A New element can contain a sequence of
|
Equivalent to `new` in Java, and allows the creation of a new object.
|
||||||
link:#jetty-xml-arg[Arg element]'s, followed by a sequence of
|
A `New` element can contain a sequence of link:#jetty-xml-arg[`Arg` element]'s, followed by a sequence of configuration elements (`Set`, `Put`, etc).
|
||||||
configuration elements (Set, Put, etc). link:#jetty-xml-arg[Arg
|
link:#jetty-xml-arg[`Arg` element]'s are used to select a constructor for the object to be created.
|
||||||
element]'s are used to select a constructor for the object to be
|
The sequence of configuration elements then acts on the newly-created object.
|
||||||
created. The sequence of configuration elements then acts on the
|
|
||||||
newly-created object.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -694,7 +648,7 @@ element], link:#jetty-xml-property[Property element]
|
||||||
</New>
|
</New>
|
||||||
----
|
----
|
||||||
|
|
||||||
which is equivalent to:
|
Which is equivalent to:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -708,7 +662,7 @@ com.acme.Foo foo = new com.acme.Foo("bar");
|
||||||
<New class="com.acme.Foo" />
|
<New class="com.acme.Foo" />
|
||||||
----
|
----
|
||||||
|
|
||||||
which is equivalent to:
|
Which is equivalent to:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -726,7 +680,7 @@ com.acme.Foo foo = new com.acme.Foo();
|
||||||
</New>
|
</New>
|
||||||
----
|
----
|
||||||
|
|
||||||
which is equivalent to:
|
Which is equivalent to:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -737,17 +691,14 @@ foo.setTest("1, 2, 3");
|
||||||
[[jetty-xml-ref]]
|
[[jetty-xml-ref]]
|
||||||
==== <Ref>
|
==== <Ref>
|
||||||
|
|
||||||
A Ref element allows a previously created object to be referenced by a
|
A `Ref` element allows a previously created object to be referenced by a unique id.
|
||||||
unique id. It can contain a sequence of elements, such as Set or Put
|
It can contain a sequence of elements, such as `Set` or `Put` which then act on the referenced object.
|
||||||
which then act on the referenced object. You can also use a Ref element
|
You can also use a `Ref` element as a value for other elements such as `Set` and `Arg`.
|
||||||
as a value for other elements such as Set and Arg.
|
|
||||||
|
|
||||||
The Ref element provides convenience and eases readability. You can
|
The `Ref` element provides convenience and eases readability.
|
||||||
usually achieve the effect of the Ref by nesting elements (method
|
You can usually achieve the effect of the `Ref` by nesting elements (method calls), but this can get complicated very easily.
|
||||||
calls), but this can get complicated very easily. The Ref element makes
|
The Ref element makes it possible to refer to the same object if you're using it multiple times, or passing it into multiple methods.
|
||||||
it possible to refer to the same object if you're using it multiple
|
It also makes it possible to split up configuration across multiple files.
|
||||||
times, or passing it into multiple methods. It also makes it possible to
|
|
||||||
split up configuration across multiple files.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -768,8 +719,7 @@ link:#jetty-xml-property[Property element]
|
||||||
|
|
||||||
====== Basic example
|
====== Basic example
|
||||||
|
|
||||||
Use the referenced object as an argument to a method call or
|
Use the referenced object as an argument to a method call or constructor:
|
||||||
constructor:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -805,8 +755,8 @@ foo.setTest("1, 2, 3");
|
||||||
|
|
||||||
====== Ref vs. Nested Elements
|
====== Ref vs. Nested Elements
|
||||||
|
|
||||||
Here is an example of the difference in syntax between using the Ref
|
Here is an example of the difference in syntax between using the `Ref` element, and nesting method calls.
|
||||||
element, and nesting method calls. They are exactly equivalent:
|
They are exactly equivalent:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -825,8 +775,7 @@ element, and nesting method calls. They are exactly equivalent:
|
||||||
</Configure>
|
</Configure>
|
||||||
----
|
----
|
||||||
|
|
||||||
Here is a more practical example, taken from the handler configuration
|
Here is a more practical example, taken from the handler configuration section in `etc/jetty.xml`:
|
||||||
section in ` etc/jetty.xml`:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -868,7 +817,7 @@ section in ` etc/jetty.xml`:
|
||||||
[[jetty-xml-array]]
|
[[jetty-xml-array]]
|
||||||
==== <Array>
|
==== <Array>
|
||||||
|
|
||||||
An Array element allows the creation of a new array.
|
An `Array` element allows the creation of a new array.
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|==================================================================
|
|==================================================================
|
||||||
|
@ -901,7 +850,7 @@ String[] a = new String[] { "value0", new String("value1") };
|
||||||
[[jetty-xml-item]]
|
[[jetty-xml-item]]
|
||||||
==== <Item>
|
==== <Item>
|
||||||
|
|
||||||
An Item element defines an entry for Array and Map elements.
|
An `Item` element defines an entry for Array and Map elements.
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -921,8 +870,7 @@ link:#jetty-xml-property[Property element]
|
||||||
[[jetty-xml-map]]
|
[[jetty-xml-map]]
|
||||||
==== <Map>
|
==== <Map>
|
||||||
|
|
||||||
A Map element allows the creation of a new HashMap and to populate it
|
A `Map` element allows the creation of a new HashMap and to populate it with `(key, value)` pairs.
|
||||||
with (key, value) pairs.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|================================================================
|
|================================================================
|
||||||
|
@ -957,8 +905,7 @@ m.put("keyName", new String("value1"));
|
||||||
[[jetty-xml-entry]]
|
[[jetty-xml-entry]]
|
||||||
==== <Entry>
|
==== <Entry>
|
||||||
|
|
||||||
An Entry element contains a key-value link:#jetty-xml-item[Item element]
|
An `Entry` element contains a key-value link:#jetty-xml-item[Item element] pair for a `Map`.
|
||||||
pair for a Map.
|
|
||||||
|
|
||||||
===== Can Contain
|
===== Can Contain
|
||||||
|
|
||||||
|
@ -967,8 +914,8 @@ link:#jetty-xml-item[Item element]
|
||||||
[[jetty-xml-system-property]]
|
[[jetty-xml-system-property]]
|
||||||
==== <SystemProperty>
|
==== <SystemProperty>
|
||||||
|
|
||||||
A SystemProperty element gets the value of a JVM system property. It can
|
A `SystemProperty` element gets the value of a JVM system property.
|
||||||
be used within elements that accept values, such as Set, Put, Arg.
|
It can be used within elements that accept values, such as `Set`, `Put`, `Arg`.
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -983,7 +930,7 @@ later.
|
||||||
|
|
||||||
===== Can Contain
|
===== Can Contain
|
||||||
|
|
||||||
Only attributes as Elements (Id, Name, Default).
|
Only attributes as Elements (`Id`, `Name`, `Default`).
|
||||||
|
|
||||||
===== Example
|
===== Example
|
||||||
|
|
||||||
|
@ -999,15 +946,14 @@ That is equivalent to:
|
||||||
System.getProperty("jetty.http.port", "8080");
|
System.getProperty("jetty.http.port", "8080");
|
||||||
----
|
----
|
||||||
|
|
||||||
Both try to retrieve the value of jetty.http.port. If jetty.http.port is
|
Both try to retrieve the value of `jetty.http.port`.
|
||||||
not set, then 8080 is used.
|
If `jetty.http.port` is not set, then 8080 is used.
|
||||||
|
|
||||||
[[jetty-xml-property]]
|
[[jetty-xml-property]]
|
||||||
==== <Property>
|
==== <Property>
|
||||||
|
|
||||||
A Property element allows arbitrary properties to be retrieved by name.
|
A `Property` element allows arbitrary properties to be retrieved by name.
|
||||||
It can contain a sequence of elements, such as Set, Put, Call that act
|
It can contain a sequence of elements, such as `Set`, `Put`, `Call` that act on the retrieved object.
|
||||||
on the retrieved object.
|
|
||||||
|
|
||||||
[cols=",,",options="header",]
|
[cols=",,",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
@ -1020,17 +966,13 @@ on the retrieved object.
|
||||||
later.
|
later.
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
The `name` attribute may be a comma separated list of property names,
|
The `Name` attribute may be a comma separated list of property names, with the first property name being the "official" name, and the others names being old, deprecated property names that are kept for backward compatibility.
|
||||||
with the first property name being the "official" name, and the others
|
A warning log is issued when deprecated property names are used.
|
||||||
names being old, deprecated property names that are kept for backward
|
The `Default` attribute contains the value to use in case none of the property names is found.
|
||||||
compatibility. A warning log is issued when deprecated property names
|
|
||||||
are used. The `default` attribute contains the value to use in case none
|
|
||||||
of the property names is found.
|
|
||||||
|
|
||||||
===== Can Contain
|
===== Can Contain
|
||||||
|
|
||||||
The attributes may be expressed as contained Elements (Id, Name,
|
The attributes may be expressed as contained Elements (`Id`, `Name`, `Default`).
|
||||||
Default).
|
|
||||||
|
|
||||||
===== Example
|
===== Example
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
=== Jetty XML Usage
|
=== Jetty XML Usage
|
||||||
|
|
||||||
Jetty provides an XML-based configuration.
|
Jetty provides an XML-based configuration.
|
||||||
It is grounded in Java's Reflection API. Classes in the java.lang.reflect represent Java methods and classes, such that you can instantiate objects and invoke their methods based on their names and argument types.
|
It is grounded in Java's Reflection API. Classes in the `java.lang.reflect` represent Java methods and classes, such that you can instantiate objects and invoke their methods based on their names and argument types.
|
||||||
Behind the scenes, Jetty's XML config parser translates the XML elements and attributes into Reflection calls.
|
Behind the scenes, Jetty's XML config parser translates the XML elements and attributes into Reflection calls.
|
||||||
|
|
||||||
[[using-jettyxml]]
|
[[using-jettyxml]]
|
||||||
|
@ -48,7 +48,7 @@ If you use the same ID across multiple configuration files, those configurations
|
||||||
[[setting-parameters-in-configuration-files]]
|
[[setting-parameters-in-configuration-files]]
|
||||||
==== Setting Parameters in Configuration Files
|
==== Setting Parameters in Configuration Files
|
||||||
|
|
||||||
You can set parameters in configuration files either with system properties (using ` <SystemProperty>`) or properties files (using `<Property>`) passed via the command line.
|
You can set parameters in configuration files either with system properties (using `<SystemProperty>`) or properties files (using `<Property>`) passed via the command line.
|
||||||
For example, this code in `jetty.xml` allows the port to be defined on the command line, falling back onto `8080`if the port is not specified:
|
For example, this code in `jetty.xml` allows the port to be defined on the command line, falling back onto `8080`if the port is not specified:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
|
|
|
@ -22,17 +22,18 @@ The challenge is to do so without changing the webapp itself. You can use a `jet
|
||||||
But there are some changes that `jetty.xml` cannot accomplish, for example, modifications to servlet init-params and context init-params.
|
But there are some changes that `jetty.xml` cannot accomplish, for example, modifications to servlet init-params and context init-params.
|
||||||
Using `webdefault.xml` is not an option because Jetty applies `webdefault.xml` to a web application _before_ the application's own `WEB-INF/web.xml`, which means that it cannot override values inside the webapp's ` web.xml`.
|
Using `webdefault.xml` is not an option because Jetty applies `webdefault.xml` to a web application _before_ the application's own `WEB-INF/web.xml`, which means that it cannot override values inside the webapp's ` web.xml`.
|
||||||
|
|
||||||
The solution is `override-web.xml`. It is a `web.xml` file that Jetty applies to a web application _after_ the application's own `WEB-INF/web.xml`, which means that it can override values or add new elements.
|
The solution is `override-web.xml`.
|
||||||
You define it per-webapp, using the xref:jetty-xml-syntax[].
|
It is a `web.xml` file that Jetty applies to a web application _after_ the application's own `WEB-INF/web.xml`, which means that it can override values or add new elements.
|
||||||
|
This is defined on a per-webapp basis, using the xref:jetty-xml-syntax[].
|
||||||
|
|
||||||
[[using-override-web-xml]]
|
[[using-override-web-xml]]
|
||||||
==== Using `override-web.xml`
|
==== Using override-web.xml
|
||||||
|
|
||||||
You can specify the `override-web.xml` to use for an individual web application, in that webapp's xref:jetty-web-xml-config[].
|
You can specify the `override-web.xml` to use for an individual web application in a deployable xml file located in Jetty webapps folder .
|
||||||
|
For example, if you had a webapp named MyApp, you would place a deployable xml file named `myapp.xml` in `${jetty.base}/webapps` which includes an `overrideDescriptor` entry for the `override-web.xml` file.
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
...
|
...
|
||||||
<!-- Set up the path to the custom override descriptor,
|
<!-- Set up the path to the custom override descriptor,
|
||||||
|
@ -40,15 +41,12 @@ You can specify the `override-web.xml` to use for an individual web application,
|
||||||
<Set name="overrideDescriptor"><SystemProperty name="jetty.home" default="."/>/my/path/to/override-web.xml</Set>
|
<Set name="overrideDescriptor"><SystemProperty name="jetty.home" default="."/>/my/path/to/override-web.xml</Set>
|
||||||
...
|
...
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
The equivalent in code is:
|
The equivalent in code is:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -58,11 +56,9 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
//Set the path to the override descriptor, based on your $(jetty.home) directory
|
//Set the path to the override descriptor, based on your $(jetty.home) directory
|
||||||
wac.setOverrideDescriptor(System.getProperty("jetty.home")+"/my/path/to/override-web.xml");
|
wac.setOverrideDescriptor(System.getProperty("jetty.home")+"/my/path/to/override-web.xml");
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Alternatively, use the classloader (xref:jetty-classloading[]) to get the path to the override descriptor as a resource.
|
Alternatively, you can use the classloader (xref:jetty-classloading[]) to get the path to the override descriptor as a resource.
|
||||||
|
|
||||||
[[override-using-jetty-maven-plugin]]
|
[[override-using-jetty-maven-plugin]]
|
||||||
==== Using the Jetty Maven Plugin
|
==== Using the Jetty Maven Plugin
|
||||||
|
@ -71,7 +67,6 @@ Use the `<overrideDescriptor>` tag as follows:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
<project>
|
<project>
|
||||||
...
|
...
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -89,8 +84,6 @@ Use the `<overrideDescriptor>` tag as follows:
|
||||||
</plugins>
|
</plugins>
|
||||||
...
|
...
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
[[override-web-xml-additional-resources]]
|
[[override-web-xml-additional-resources]]
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.http;
|
package org.eclipse.jetty.http;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
@ -86,112 +85,8 @@ public class HttpField
|
||||||
if (_value == null)
|
if (_value == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ArrayList<String> list = new ArrayList<>();
|
QuotedCSV list = new QuotedCSV(false,_value);
|
||||||
int state = 0;
|
return list.getValues().toArray(new String[list.size()]);
|
||||||
int start=0;
|
|
||||||
int end=0;
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
for (int i=0;i<_value.length();i++)
|
|
||||||
{
|
|
||||||
char c = _value.charAt(i);
|
|
||||||
switch(state)
|
|
||||||
{
|
|
||||||
case 0: // initial white space
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case '"': // open quote
|
|
||||||
state=2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ',': // ignore leading empty field
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ' ': // more white space
|
|
||||||
case '\t':
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // character
|
|
||||||
start=i;
|
|
||||||
end=i;
|
|
||||||
state=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // In token
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case ',': // next field
|
|
||||||
list.add(_value.substring(start,end+1));
|
|
||||||
state=0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ' ': // more white space
|
|
||||||
case '\t':
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
end=i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // In Quoted
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case '\\': // next field
|
|
||||||
state=3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '"': // end quote
|
|
||||||
list.add(builder.toString());
|
|
||||||
builder.setLength(0);
|
|
||||||
state=4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
builder.append(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // In Quoted Quoted
|
|
||||||
builder.append(c);
|
|
||||||
state=2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4: // WS after end quote
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case ' ': // white space
|
|
||||||
case '\t': // white space
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ',': // white space
|
|
||||||
state=0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("c="+(int)c);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(state)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
list.add(_value.substring(start,end+1));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("state="+state);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -282,6 +282,100 @@ public class HttpFields implements Iterable<HttpField>
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add comma separated values, but only if not already
|
||||||
|
* present.
|
||||||
|
* @param header The header to add the value(s) to
|
||||||
|
* @param values The value(s) to add
|
||||||
|
* @return True if headers were modified
|
||||||
|
*/
|
||||||
|
public boolean addCSV(HttpHeader header,String... values)
|
||||||
|
{
|
||||||
|
QuotedCSV existing = null;
|
||||||
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
|
if (f.getHeader()==header)
|
||||||
|
{
|
||||||
|
if (existing==null)
|
||||||
|
existing = new QuotedCSV(false);
|
||||||
|
existing.addValue(f.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = addCSV(existing,values);
|
||||||
|
if (value!=null)
|
||||||
|
{
|
||||||
|
add(header,value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add comma separated values, but only if not already
|
||||||
|
* present.
|
||||||
|
* @param header The header to add the value(s) to
|
||||||
|
* @param values The value(s) to add
|
||||||
|
* @return True if headers were modified
|
||||||
|
*/
|
||||||
|
public boolean addCSV(String name,String... values)
|
||||||
|
{
|
||||||
|
QuotedCSV existing = null;
|
||||||
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
|
if (f.getName().equalsIgnoreCase(name))
|
||||||
|
{
|
||||||
|
if (existing==null)
|
||||||
|
existing = new QuotedCSV(false);
|
||||||
|
existing.addValue(f.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String value = addCSV(existing,values);
|
||||||
|
if (value!=null)
|
||||||
|
{
|
||||||
|
add(name,value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String addCSV(QuotedCSV existing,String... values)
|
||||||
|
{
|
||||||
|
// remove any existing values from the new values
|
||||||
|
boolean add = true;
|
||||||
|
if (existing!=null && !existing.isEmpty())
|
||||||
|
{
|
||||||
|
add = false;
|
||||||
|
|
||||||
|
for (int i=values.length;i-->0;)
|
||||||
|
{
|
||||||
|
String unquoted = QuotedCSV.unquote(values[i]);
|
||||||
|
if (existing.getValues().contains(unquoted))
|
||||||
|
values[i] = null;
|
||||||
|
else
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
StringBuilder value = new StringBuilder();
|
||||||
|
for (String v:values)
|
||||||
|
{
|
||||||
|
if (v==null)
|
||||||
|
continue;
|
||||||
|
if (value.length()>0)
|
||||||
|
value.append(", ");
|
||||||
|
value.append(v);
|
||||||
|
}
|
||||||
|
if (value.length()>0)
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get multiple field values of the same name, split
|
* Get multiple field values of the same name, split
|
||||||
* as a {@link QuotedCSV}
|
* as a {@link QuotedCSV}
|
||||||
|
@ -292,11 +386,17 @@ public class HttpFields implements Iterable<HttpField>
|
||||||
*/
|
*/
|
||||||
public List<String> getCSV(HttpHeader header,boolean keepQuotes)
|
public List<String> getCSV(HttpHeader header,boolean keepQuotes)
|
||||||
{
|
{
|
||||||
QuotedCSV values = new QuotedCSV(keepQuotes);
|
QuotedCSV values = null;
|
||||||
for (HttpField f : this)
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
if (f.getHeader()==header)
|
if (f.getHeader()==header)
|
||||||
|
{
|
||||||
|
if (values==null)
|
||||||
|
values = new QuotedCSV(keepQuotes);
|
||||||
values.addValue(f.getValue());
|
values.addValue(f.getValue());
|
||||||
return values.getValues();
|
}
|
||||||
|
}
|
||||||
|
return values==null?Collections.emptyList():values.getValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -309,11 +409,17 @@ public class HttpFields implements Iterable<HttpField>
|
||||||
*/
|
*/
|
||||||
public List<String> getCSV(String name,boolean keepQuotes)
|
public List<String> getCSV(String name,boolean keepQuotes)
|
||||||
{
|
{
|
||||||
QuotedCSV values = new QuotedCSV(keepQuotes);
|
QuotedCSV values = null;
|
||||||
for (HttpField f : this)
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
if (f.getName().equalsIgnoreCase(name))
|
if (f.getName().equalsIgnoreCase(name))
|
||||||
|
{
|
||||||
|
if (values==null)
|
||||||
|
values = new QuotedCSV(keepQuotes);
|
||||||
values.addValue(f.getValue());
|
values.addValue(f.getValue());
|
||||||
return values.getValues();
|
}
|
||||||
|
}
|
||||||
|
return values==null?Collections.emptyList():values.getValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -325,11 +431,18 @@ public class HttpFields implements Iterable<HttpField>
|
||||||
*/
|
*/
|
||||||
public List<String> getQualityCSV(HttpHeader header)
|
public List<String> getQualityCSV(HttpHeader header)
|
||||||
{
|
{
|
||||||
QuotedQualityCSV values = new QuotedQualityCSV();
|
QuotedQualityCSV values = null;
|
||||||
for (HttpField f : this)
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
if (f.getHeader()==header)
|
if (f.getHeader()==header)
|
||||||
|
{
|
||||||
|
if (values==null)
|
||||||
|
values = new QuotedQualityCSV();
|
||||||
values.addValue(f.getValue());
|
values.addValue(f.getValue());
|
||||||
return values.getValues();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values==null?Collections.emptyList():values.getValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,11 +454,17 @@ public class HttpFields implements Iterable<HttpField>
|
||||||
*/
|
*/
|
||||||
public List<String> getQualityCSV(String name)
|
public List<String> getQualityCSV(String name)
|
||||||
{
|
{
|
||||||
QuotedQualityCSV values = new QuotedQualityCSV();
|
QuotedQualityCSV values = null;
|
||||||
for (HttpField f : this)
|
for (HttpField f : this)
|
||||||
|
{
|
||||||
if (f.getName().equalsIgnoreCase(name))
|
if (f.getName().equalsIgnoreCase(name))
|
||||||
|
{
|
||||||
|
if (values==null)
|
||||||
|
values = new QuotedQualityCSV();
|
||||||
values.addValue(f.getValue());
|
values.addValue(f.getValue());
|
||||||
return values.getValues();
|
}
|
||||||
|
}
|
||||||
|
return values==null?Collections.emptyList():values.getValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* Implements a quoted comma separated list of values
|
* Implements a quoted comma separated list of values
|
||||||
|
@ -52,6 +54,9 @@ public class QuotedCSV implements Iterable<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
/** Add and parse a value string(s)
|
||||||
|
* @param value A value that may contain one or more Quoted CSV items.
|
||||||
|
*/
|
||||||
public void addValue(String value)
|
public void addValue(String value)
|
||||||
{
|
{
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
@ -241,6 +246,15 @@ public class QuotedCSV implements Iterable<String>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return _values.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return _values.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getValues()
|
public List<String> getValues()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.http;
|
package org.eclipse.jetty.http;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -340,7 +341,89 @@ public class HttpFieldsTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetQualityValues() throws Exception
|
public void testGetCSV() throws Exception
|
||||||
|
{
|
||||||
|
HttpFields fields = new HttpFields();
|
||||||
|
|
||||||
|
fields.put("name0", "value0A,value0B");
|
||||||
|
fields.add("name0", "value0C,value0D");
|
||||||
|
fields.put("name1", "value1A, \"value\t, 1B\" ");
|
||||||
|
fields.add("name1", "\"value1C\",\tvalue1D");
|
||||||
|
|
||||||
|
Enumeration<String> e = fields.getValues("name0");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0A,value0B");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0C,value0D");
|
||||||
|
assertEquals(false, e.hasMoreElements());
|
||||||
|
|
||||||
|
e = Collections.enumeration(fields.getCSV("name0",false));
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0A");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0B");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0C");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value0D");
|
||||||
|
assertEquals(false, e.hasMoreElements());
|
||||||
|
|
||||||
|
e = Collections.enumeration(fields.getCSV("name1",false));
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value1A");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value\t, 1B");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value1C");
|
||||||
|
assertEquals(true, e.hasMoreElements());
|
||||||
|
assertEquals(e.nextElement(), "value1D");
|
||||||
|
assertEquals(false, e.hasMoreElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddQuotedCSV() throws Exception
|
||||||
|
{
|
||||||
|
HttpFields fields = new HttpFields();
|
||||||
|
|
||||||
|
fields.put("some", "value");
|
||||||
|
fields.add("name", "\"zero\"");
|
||||||
|
fields.add("name", "one, \"1 + 1\"");
|
||||||
|
fields.put("other", "value");
|
||||||
|
fields.add("name", "three");
|
||||||
|
fields.add("name", "four, I V");
|
||||||
|
|
||||||
|
List<String> list = fields.getCSV("name",false);
|
||||||
|
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
||||||
|
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
||||||
|
assertEquals("1 + 1",HttpFields.valueParameters(list.get(2),null));
|
||||||
|
assertEquals("three",HttpFields.valueParameters(list.get(3),null));
|
||||||
|
assertEquals("four",HttpFields.valueParameters(list.get(4),null));
|
||||||
|
assertEquals("I V",HttpFields.valueParameters(list.get(5),null));
|
||||||
|
|
||||||
|
fields.addCSV("name","six");
|
||||||
|
list = fields.getCSV("name",false);
|
||||||
|
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
||||||
|
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
||||||
|
assertEquals("1 + 1",HttpFields.valueParameters(list.get(2),null));
|
||||||
|
assertEquals("three",HttpFields.valueParameters(list.get(3),null));
|
||||||
|
assertEquals("four",HttpFields.valueParameters(list.get(4),null));
|
||||||
|
assertEquals("I V",HttpFields.valueParameters(list.get(5),null));
|
||||||
|
assertEquals("six",HttpFields.valueParameters(list.get(6),null));
|
||||||
|
|
||||||
|
fields.addCSV("name","1 + 1","7","zero");
|
||||||
|
list = fields.getCSV("name",false);
|
||||||
|
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
||||||
|
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
||||||
|
assertEquals("1 + 1",HttpFields.valueParameters(list.get(2),null));
|
||||||
|
assertEquals("three",HttpFields.valueParameters(list.get(3),null));
|
||||||
|
assertEquals("four",HttpFields.valueParameters(list.get(4),null));
|
||||||
|
assertEquals("I V",HttpFields.valueParameters(list.get(5),null));
|
||||||
|
assertEquals("six",HttpFields.valueParameters(list.get(6),null));
|
||||||
|
assertEquals("7",HttpFields.valueParameters(list.get(7),null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetQualityCSV() throws Exception
|
||||||
{
|
{
|
||||||
HttpFields fields = new HttpFields();
|
HttpFields fields = new HttpFields();
|
||||||
|
|
||||||
|
@ -351,7 +434,8 @@ public class HttpFieldsTest
|
||||||
fields.add("name", "one;q=0.4");
|
fields.add("name", "one;q=0.4");
|
||||||
fields.add("name", "three;x=y;q=0.2;a=b,two;q=0.3");
|
fields.add("name", "three;x=y;q=0.2;a=b,two;q=0.3");
|
||||||
|
|
||||||
List<String> list = HttpFields.qualityList(fields.getValues("name",","));
|
|
||||||
|
List<String> list = fields.getQualityCSV("name");
|
||||||
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
||||||
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
||||||
assertEquals("two",HttpFields.valueParameters(list.get(2),null));
|
assertEquals("two",HttpFields.valueParameters(list.get(2),null));
|
||||||
|
|
|
@ -320,7 +320,7 @@ public class HttpTester
|
||||||
@Override
|
@Override
|
||||||
public void parsedHeader(HttpField field)
|
public void parsedHeader(HttpField field)
|
||||||
{
|
{
|
||||||
put(field.getName(),field.getValue());
|
add(field.getName(),field.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,10 +30,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.CompressedContentFormat;
|
import org.eclipse.jetty.http.CompressedContentFormat;
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpFields;
|
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.http.pathmap.PathSpecSet;
|
import org.eclipse.jetty.http.pathmap.PathSpecSet;
|
||||||
import org.eclipse.jetty.server.HttpOutput;
|
import org.eclipse.jetty.server.HttpOutput;
|
||||||
|
@ -489,12 +487,22 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpOutput.Interceptor orig_interceptor = out.getInterceptor();
|
||||||
|
try
|
||||||
|
{
|
||||||
// install interceptor and handle
|
// install interceptor and handle
|
||||||
out.setInterceptor(new GzipHttpOutputInterceptor(this,getVaryField(),baseRequest.getHttpChannel(),out.getInterceptor(),isSyncFlush()));
|
out.setInterceptor(new GzipHttpOutputInterceptor(this,getVaryField(),baseRequest.getHttpChannel(),orig_interceptor,isSyncFlush()));
|
||||||
|
|
||||||
if (_handler!=null)
|
if (_handler!=null)
|
||||||
_handler.handle(target,baseRequest, request, response);
|
_handler.handle(target,baseRequest, request, response);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// reset interceptor if request not handled
|
||||||
|
if (!baseRequest.isHandled() && !baseRequest.isAsyncStarted())
|
||||||
|
out.setInterceptor(orig_interceptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||||
|
import org.eclipse.jetty.http.QuotedCSV;
|
||||||
import org.eclipse.jetty.server.HttpChannel;
|
import org.eclipse.jetty.server.HttpChannel;
|
||||||
import org.eclipse.jetty.server.HttpOutput;
|
import org.eclipse.jetty.server.HttpOutput;
|
||||||
import org.eclipse.jetty.server.Response;
|
import org.eclipse.jetty.server.Response;
|
||||||
|
@ -190,7 +191,8 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has the Content-Encoding header already been set?
|
// Has the Content-Encoding header already been set?
|
||||||
String ce=response.getHeader("Content-Encoding");
|
HttpFields fields = response.getHttpFields();
|
||||||
|
String ce=fields.get(HttpHeader.CONTENT_ENCODING);
|
||||||
if (ce != null)
|
if (ce != null)
|
||||||
{
|
{
|
||||||
LOG.debug("{} exclude by content-encoding {}",this,ce);
|
LOG.debug("{} exclude by content-encoding {}",this,ce);
|
||||||
|
@ -203,9 +205,13 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
||||||
if (_state.compareAndSet(GZState.MIGHT_COMPRESS,GZState.COMMITTING))
|
if (_state.compareAndSet(GZState.MIGHT_COMPRESS,GZState.COMMITTING))
|
||||||
{
|
{
|
||||||
// We are varying the response due to accept encoding header.
|
// We are varying the response due to accept encoding header.
|
||||||
HttpFields fields = response.getHttpFields();
|
|
||||||
if (_vary != null)
|
if (_vary != null)
|
||||||
|
{
|
||||||
|
if (fields.contains(HttpHeader.VARY))
|
||||||
|
fields.addCSV(HttpHeader.VARY,_vary.getValues());
|
||||||
|
else
|
||||||
fields.add(_vary);
|
fields.add(_vary);
|
||||||
|
}
|
||||||
|
|
||||||
long content_length = response.getContentLength();
|
long content_length = response.getContentLength();
|
||||||
if (content_length<0 && complete)
|
if (content_length<0 && complete)
|
||||||
|
|
|
@ -134,6 +134,8 @@ public class GzipHandlerTest
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
|
if (req.getParameter("vary")!=null)
|
||||||
|
response.addHeader("Vary",req.getParameter("vary"));
|
||||||
response.setHeader("ETag",__contentETag);
|
response.setHeader("ETag",__contentETag);
|
||||||
String ifnm = req.getHeader("If-None-Match");
|
String ifnm = req.getHeader("If-None-Match");
|
||||||
if (ifnm!=null && ifnm.equals(__contentETag))
|
if (ifnm!=null && ifnm.equals(__contentETag))
|
||||||
|
@ -181,7 +183,7 @@ public class GzipHandlerTest
|
||||||
HttpTester.Response response;
|
HttpTester.Response response;
|
||||||
|
|
||||||
request.setMethod("GET");
|
request.setMethod("GET");
|
||||||
request.setURI("/ctx/content");
|
request.setURI("/ctx/content?vary=Other");
|
||||||
request.setVersion("HTTP/1.0");
|
request.setVersion("HTTP/1.0");
|
||||||
request.setHeader("Host","tester");
|
request.setHeader("Host","tester");
|
||||||
|
|
||||||
|
@ -190,16 +192,16 @@ public class GzipHandlerTest
|
||||||
assertThat(response.getStatus(),is(200));
|
assertThat(response.getStatus(),is(200));
|
||||||
assertThat(response.get("Content-Encoding"),not(equalToIgnoringCase("gzip")));
|
assertThat(response.get("Content-Encoding"),not(equalToIgnoringCase("gzip")));
|
||||||
assertThat(response.get("ETag"),is(__contentETag));
|
assertThat(response.get("ETag"),is(__contentETag));
|
||||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
assertThat(response.getValuesList("Vary"),Matchers.contains("Other","Accept-Encoding"));
|
||||||
|
|
||||||
InputStream testIn = new ByteArrayInputStream(response.getContentBytes());
|
InputStream testIn = new ByteArrayInputStream(response.getContentBytes());
|
||||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||||
IO.copy(testIn,testOut);
|
IO.copy(testIn,testOut);
|
||||||
|
|
||||||
assertEquals(__content, testOut.toString("UTF8"));
|
assertEquals(__content, testOut.toString("UTF8"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGzipHandler() throws Exception
|
public void testGzipHandler() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -208,7 +210,7 @@ public class GzipHandlerTest
|
||||||
HttpTester.Response response;
|
HttpTester.Response response;
|
||||||
|
|
||||||
request.setMethod("GET");
|
request.setMethod("GET");
|
||||||
request.setURI("/ctx/content");
|
request.setURI("/ctx/content?vary=Accept-Encoding,Other");
|
||||||
request.setVersion("HTTP/1.0");
|
request.setVersion("HTTP/1.0");
|
||||||
request.setHeader("Host","tester");
|
request.setHeader("Host","tester");
|
||||||
request.setHeader("accept-encoding","gzip");
|
request.setHeader("accept-encoding","gzip");
|
||||||
|
@ -218,7 +220,7 @@ public class GzipHandlerTest
|
||||||
assertThat(response.getStatus(),is(200));
|
assertThat(response.getStatus(),is(200));
|
||||||
assertThat(response.get("Content-Encoding"),Matchers.equalToIgnoringCase("gzip"));
|
assertThat(response.get("Content-Encoding"),Matchers.equalToIgnoringCase("gzip"));
|
||||||
assertThat(response.get("ETag"),is(__contentETagGzip));
|
assertThat(response.get("ETag"),is(__contentETagGzip));
|
||||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
assertThat(response.getCSV("Vary",false),Matchers.contains("Accept-Encoding","Other"));
|
||||||
|
|
||||||
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||||
|
|
Loading…
Reference in New Issue