Author: sergeyb
Date: Tue Jan 19 11:46:35 2010
New Revision: 900738
URL: http://svn.apache.org/viewvc?rev=900738&view=rev
Log:
JAX-RS : HttpHeaderImpl enhancements to do with parsing Cookies and other
multiple headers
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/HttpHeadersImplTest.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java?rev=900738&r1=900737&r2=900738&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java
Tue Jan 19 11:46:35 2010
@@ -26,6 +26,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -44,7 +45,11 @@
public class HttpHeadersImpl implements HttpHeaders {
- // TODO : it can be optimized, "Mastering Regular Expressions" has the
answers
+ private static final String COOKIE_SEPARATOR_PROPERTY =
+ "org.apache.cxf.http.cookie.separator";
+ private static final String COOKIE_SEPARATOR_CRLF = "crlf";
+ private static final String DEFAULT_SEPARATOR = ",";
+
private static final String COMPLEX_HEADER_EXPRESSION =
"(([\\w]+=\"[^\"]*\")|([\\w]+=[\\w]+)|([\\w]+))(;(([\\w]+=\"[^\"]*\")|([\\w]+=[\\w]+)|([\\w]+)))?";
private static final Pattern COMPLEX_HEADER_PATTERN =
@@ -63,10 +68,12 @@
}
+ private Message message;
private MultivaluedMap<String, String> headers;
@SuppressWarnings("unchecked")
public HttpHeadersImpl(Message message) {
+ this.message = message;
this.headers = new MetadataMap<String, String>(
(Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS),
true, true);
}
@@ -92,7 +99,7 @@
if (value == null) {
continue;
}
- List<String> cs = getHeaderValues(HttpHeaders.COOKIE, value);
+ List<String> cs = getHeaderValues(HttpHeaders.COOKIE, value,
getCookieSeparator());
for (String c : cs) {
Cookie cookie = Cookie.valueOf(c);
cl.put(cookie.getName(), cookie);
@@ -101,6 +108,16 @@
return cl;
}
+ private String getCookieSeparator() {
+ Object cookiePropValue =
message.getContextualProperty(COOKIE_SEPARATOR_PROPERTY);
+ if (cookiePropValue != null) {
+ return COOKIE_SEPARATOR_CRLF.equals(cookiePropValue.toString())
+ ? "\r\n" : cookiePropValue.toString();
+ } else {
+ return DEFAULT_SEPARATOR;
+ }
+ }
+
public Locale getLanguage() {
List<String> values = getListValues(HttpHeaders.CONTENT_LANGUAGE);
return values.size() == 0 ? null : createLocale(values.get(0).trim());
@@ -114,7 +131,7 @@
public MultivaluedMap<String, String> getRequestHeaders() {
Map<String, List<String>> newHeaders = new LinkedHashMap<String,
List<String>>();
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
- newHeaders.put(entry.getKey(), getListValues(entry.getKey()));
+ newHeaders.put(entry.getKey(), getRequestHeader(entry.getKey()));
}
return new MetadataMap<String, String>(newHeaders, true, true);
}
@@ -151,7 +168,22 @@
}
public List<String> getRequestHeader(String name) {
- return getListValues(name);
+ List<String> values = headers.get(name);
+ if (values == null || values.isEmpty() || values.get(0) == null) {
+ return Collections.emptyList();
+ }
+ if (HttpUtils.isDateRelatedHeader(name)) {
+ return values;
+ }
+ String sep = HttpHeaders.COOKIE.equalsIgnoreCase(name) ?
getCookieSeparator() : DEFAULT_SEPARATOR;
+ List<String> ls = new LinkedList<String>();
+ for (String value : values) {
+ if (value == null) {
+ continue;
+ }
+ ls.addAll(getHeaderValues(name, value, sep));
+ }
+ return ls;
}
private List<String> getListValues(String headerName) {
@@ -166,9 +198,13 @@
}
private List<String> getHeaderValues(String headerName, String
originalValue) {
+ return getHeaderValues(headerName, originalValue, DEFAULT_SEPARATOR);
+ }
+
+ private List<String> getHeaderValues(String headerName, String
originalValue, String sep) {
if (!originalValue.contains(QUOTE)
|| HEADERS_WITH_POSSIBLE_QUOTES.contains(headerName)) {
- String[] ls = originalValue.split(",");
+ String[] ls = originalValue.split(sep);
if (ls.length == 1) {
return Collections.singletonList(ls[0].trim());
} else {
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=900738&r1=900737&r2=900738&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
Tue Jan 19 11:46:35 2010
@@ -108,39 +108,34 @@
return;
}
- if (objs.get(0) != null) {
- Object responseObj = objs.get(0);
- Response response = null;
- if (objs.get(0) instanceof Response) {
- response = (Response)responseObj;
- } else {
- int status = getStatus(message, 200);
- response = Response.status(status).entity(responseObj).build();
- }
-
- Exchange exchange = message.getExchange();
- OperationResourceInfo ori =
(OperationResourceInfo)exchange.get(OperationResourceInfo.class
- .getName());
+ Object responseObj = objs.get(0);
+
+ Response response = null;
+ if (responseObj instanceof Response) {
+ response = (Response)responseObj;
+ } else {
+ int status = getStatus(message, responseObj != null ? 200 : 204);
+ response = Response.status(status).entity(responseObj).build();
+ }
+
+ Exchange exchange = message.getExchange();
+ OperationResourceInfo ori =
(OperationResourceInfo)exchange.get(OperationResourceInfo.class
+ .getName());
- List<ProviderInfo<ResponseHandler>> handlers =
- ProviderFactory.getInstance(message).getResponseHandlers();
- for (ProviderInfo<ResponseHandler> rh : handlers) {
- InjectionUtils.injectContextFields(rh.getProvider(), rh,
-
message.getExchange().getInMessage());
- InjectionUtils.injectContextFields(rh.getProvider(), rh,
-
message.getExchange().getInMessage());
- Response r = rh.getProvider().handleResponse(message, ori,
response);
- if (r != null) {
- response = r;
- }
+ List<ProviderInfo<ResponseHandler>> handlers =
+ ProviderFactory.getInstance(message).getResponseHandlers();
+ for (ProviderInfo<ResponseHandler> rh : handlers) {
+ InjectionUtils.injectContextFields(rh.getProvider(), rh,
+
message.getExchange().getInMessage());
+ InjectionUtils.injectContextFields(rh.getProvider(), rh,
+
message.getExchange().getInMessage());
+ Response r = rh.getProvider().handleResponse(message, ori,
response);
+ if (r != null) {
+ response = r;
}
-
- serializeMessage(message, response, ori, true);
-
- } else {
- int status = getStatus(message, 204);
- message.put(Message.RESPONSE_CODE, status);
}
+
+ serializeMessage(message, response, ori, true);
}
private int getStatus(Message message, int defaultValue) {
Modified:
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/HttpHeadersImplTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/HttpHeadersImplTest.java?rev=900738&r1=900737&r2=900738&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/HttpHeadersImplTest.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/HttpHeadersImplTest.java
Tue Jan 19 11:46:35 2010
@@ -30,6 +30,8 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.easymock.classextension.EasyMock;
@@ -219,6 +221,7 @@
public void testGetCookies() throws Exception {
Message m = new MessageImpl();
+ m.setExchange(new ExchangeImpl());
MetadataMap<String, String> headers = createHeaders();
headers.putSingle(HttpHeaders.COOKIE, "a=b,c=d");
m.put(Message.PROTOCOL_HEADERS, headers);
@@ -230,6 +233,24 @@
}
@Test
+ public void testGetCookiesWithSemiColon() throws Exception {
+
+ Message m = new MessageImpl();
+ Exchange ex = new ExchangeImpl();
+ ex.setInMessage(m);
+ ex.put("org.apache.cxf.http.cookie.separator", ";");
+ m.setExchange(ex);
+ MetadataMap<String, String> headers = createHeaders();
+ headers.putSingle(HttpHeaders.COOKIE, "a=b" + ";" + "c=d");
+ m.put(Message.PROTOCOL_HEADERS, headers);
+ HttpHeaders h = new HttpHeadersImpl(m);
+ Map<String, Cookie> cookies = h.getCookies();
+ assertEquals(2, cookies.size());
+ assertEquals("b", cookies.get("a").getValue());
+ assertEquals("d", cookies.get("c").getValue());
+ }
+
+ @Test
public void testMultipleAcceptableLanguages() throws Exception {
Message m = control.createMock(Message.class);
Modified:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=900738&r1=900737&r2=900738&view=diff
==============================================================================
---
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
(original)
+++
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
Tue Jan 19 11:46:35 2010
@@ -246,6 +246,13 @@
|| !cookies.containsKey("e")) {
throw new WebApplicationException();
}
+ List<String> cookiesList =
httpHeaders.getRequestHeader(HttpHeaders.COOKIE);
+ if (cookiesList.size() != 3
+ || !cookiesList.contains("a=b")
+ || !cookiesList.contains("c=d")
+ || !cookiesList.contains("e=f")) {
+ throw new WebApplicationException();
+ }
return doGetBook(ids.get(0) + ids.get(1) + ids.get(2));
}