summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/binding-atom-runtime
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2011-01-01 23:22:49 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2011-01-01 23:22:49 +0000
commit743b32faab13dbd426a255ec770dff02fa2550f3 (patch)
tree53c51ffd8cfbdc938ca18398c7985a6362ac9f2a /sca-java-2.x/trunk/modules/binding-atom-runtime
parentc864ae0f334b2d2a81b2f31dae2ea51a54a69ccd (diff)
TUSCANY-3812 - Fixing ETag and Cache headers to avoid refresh issues in IE
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1054319 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/trunk/modules/binding-atom-runtime')
-rw-r--r--sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java15
-rw-r--r--sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java124
-rw-r--r--sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/utils/AtomBindingHttpUtils.java56
3 files changed, 132 insertions, 63 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
index c1de646f54..e569276b08 100644
--- a/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
+++ b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
@@ -6,15 +6,15 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
- * under the License.
+ * under the License.
*/
package org.apache.tuscany.sca.binding.atom.provider;
@@ -50,7 +50,7 @@ import org.oasisopen.sca.ServiceRuntimeException;
/**
* Invoker for the Atom binding.
- *
+ *
* @version $Rev$ $Date$
*/
class AtomBindingInvoker implements Invoker {
@@ -205,7 +205,7 @@ class AtomBindingInvoker implements Invoker {
// Write the Atom entry
StringWriter writer = new StringWriter();
feedEntry.writeTo(writer);
- // postMethod.setHeader("Content-type", "application/atom+xml; charset=utf-8");
+ // postMethod.setHeader("Content-type", "application/atom+xml; charset=utf-8"); - TUSCANY-3734
postMethod.setHeader("Content-type", "application/atom+xml;type=entry");
postMethod.setEntity(new StringEntity(writer.toString()));
@@ -228,7 +228,7 @@ class AtomBindingInvoker implements Invoker {
} else {
- // Returns the id of the created entry
+ // Returns the id of the created entry
msg.setBody(createdEntry.getId().toString());
}
@@ -304,7 +304,8 @@ class AtomBindingInvoker implements Invoker {
// Write the Atom entry
StringWriter writer = new StringWriter();
feedEntry.writeTo(writer);
- putMethod.setHeader("Content-type", "application/atom+xml; charset=utf-8");
+ //putMethod.setHeader("Content-type", "application/atom+xml; charset=utf-8"); - TUSCANY-3734
+ putMethod.setHeader("Content-type", "application/atom+xml;type=entry");
putMethod.setEntity(new StringEntity(writer.toString()));
response = httpClient.execute(putMethod);
diff --git a/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
index 7779203a3a..e8f1edc44a 100644
--- a/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
+++ b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
@@ -6,15 +6,15 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
- * under the License.
+ * under the License.
*/
package org.apache.tuscany.sca.binding.atom.provider;
@@ -50,7 +50,7 @@ import org.apache.abdera.model.Workspace;
import org.apache.abdera.parser.ParseException;
import org.apache.abdera.parser.Parser;
import org.apache.abdera.writer.WriterFactory;
-import org.apache.commons.codec.binary.Base64;
+import org.apache.tuscany.sca.binding.atom.utils.AtomBindingHttpUtils;
import org.apache.tuscany.sca.common.http.HTTPCacheContext;
import org.apache.tuscany.sca.common.http.HTTPUtils;
import org.apache.tuscany.sca.data.collection.Entry;
@@ -77,9 +77,9 @@ class AtomBindingListenerServlet extends HttpServlet {
private static final Factory abderaFactory = Abdera.getNewFactory();
private static final Parser abderaParser = Abdera.getNewParser();
private static final String ETAG = "ETag";
- private static final String LASTMODIFIED = "Last-Modified";
- private static final String LOCATION = "Location";
- private static final String CONTENTLOCATION = "Content-Location";
+ private static final String LASTMODIFIED = "Last-Modified";
+ private static final String LOCATION = "Location";
+ private static final String CONTENTLOCATION = "Content-Location";
private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
private Invocable wire;
@@ -102,7 +102,7 @@ class AtomBindingListenerServlet extends HttpServlet {
/**
* Constructs a new binding listener.
- *
+ *
* @param wire
* @param messageFactory
* @param feedType
@@ -149,7 +149,7 @@ class AtomBindingListenerServlet extends HttpServlet {
if (itemClass == org.apache.abdera.model.Entry.class) {
supportsFeedEntries = true;
}
- //We assume that the item type is the same for both input and
+ //We assume that the item type is the same for both input and
//ouput for all operations on the interface
itemClassType = getOperation.getOutputType().getLogical().get(0);
}
@@ -161,10 +161,10 @@ class AtomBindingListenerServlet extends HttpServlet {
// No authentication required for a get request
// Test for any cache info in the request
- HTTPCacheContext cacheContext = null;
- try {
+ HTTPCacheContext cacheContext = null;
+ try {
cacheContext = HTTPCacheContext.createCacheContextFromRequest( request );
- } catch ( java.text.ParseException e ) {
+ } catch ( java.text.ParseException e ) {
}
// System.out.println( "AtomBindingListener.doGet cache context=" + cacheContext );
@@ -173,7 +173,7 @@ class AtomBindingListenerServlet extends HttpServlet {
//String path = URLDecoder.decode(request.getRequestURI().substring(servletPathLength), "UTF-8");
String path = URLDecoder.decode(HTTPUtils.getRequestPath(request), "UTF-8");
-
+
logger.fine("get " + request.getRequestURI());
// Handle an Atom request
@@ -193,7 +193,8 @@ class AtomBindingListenerServlet extends HttpServlet {
*/
// Return the Atom service document
- response.setContentType("application/atomsvc+xml; charset=utf-8");
+ response.setDateHeader("Date", System.currentTimeMillis());
+ response.setContentType("application/atomsvc+xml");
String href = request.getRequestURL().toString();
href = href.substring(0, href.length() - "/atomsvc".length());
@@ -230,17 +231,17 @@ class AtomBindingListenerServlet extends HttpServlet {
collection.addAccepts("application/json;type=entry");
List<Category> categories = feed.getCategories();
if ( categories != null ) {
- collection.addCategories(categories, false, null);
+ collection.addCategories(categories, false, null);
} else {
collection.addCategories().setFixed(false);
}
} else {
collection.setTitle("entries");
- // collection.addAccepts("application/atom+xml;type=feed");
- collection.addAccepts("application/atom+xml; type=entry");
+
+ collection.addAccepts("application/atom+xml;type=entry");
collection.addAccepts("application/json;type=entry");
- collection.addCategories().setFixed(false);
+ collection.addCategories().setFixed(false);
}
workspace.addCollection(collection);
service.addWorkspace(workspace);
@@ -258,8 +259,7 @@ class AtomBindingListenerServlet extends HttpServlet {
Feed feed = getFeed( request );
if (feed != null) {
String feedETag = null;
- if (feed.getId() != null)
- feedETag = "\"" + feed.getId().toString() + "\"";
+ feedETag = HTTPUtils.calculateHashETag(feed.toString().getBytes("utf-8"));
Date feedUpdated = feed.getUpdated();
// Test request for predicates.
String predicate = request.getHeader( "If-Match" );
@@ -275,28 +275,28 @@ class AtomBindingListenerServlet extends HttpServlet {
return;
}
if ( feedUpdated != null ) {
- predicate = request.getHeader( "If-Unmodified-Since" );
+ predicate = request.getHeader( "If-Unmodified-Since" );
if ( predicate != null ) {
try {
- Date predicateDate = dateFormat.parse( predicate );
+ Date predicateDate = dateFormat.parse( predicate );
if ( predicateDate.compareTo( exactSeconds(feedUpdated) ) < 0 ) {
// Match, should short circuit
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return;
- }
+ }
} catch ( java.text.ParseException e ) {
// Ignore and move on
}
}
- predicate = request.getHeader( "If-Modified-Since" );
+ predicate = request.getHeader( "If-Modified-Since" );
if ( predicate != null ) {
try {
- Date predicateDate = dateFormat.parse( predicate );
+ Date predicateDate = dateFormat.parse( predicate );
if ( predicateDate.compareTo( exactSeconds(feedUpdated) ) >= 0 ) {
// Match, should short circuit
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
- }
+ }
} catch ( java.text.ParseException e ) {
// Ignore and move on
}
@@ -311,9 +311,12 @@ class AtomBindingListenerServlet extends HttpServlet {
response.addHeader(LASTMODIFIED, dateFormat.format( feedUpdated ));
}
+ //default http header for response
+ AtomBindingHttpUtils.prepareHTTPResponse(request, response);
+
// Content negotiation
String acceptType = request.getHeader( "Accept" );
- String preferredType = getContentPreference( acceptType );
+ String preferredType = getContentPreference( acceptType );
if (( preferredType != null ) && ((preferredType.indexOf( "json") > -1) || (preferredType.indexOf( "JSON") > -1 ))) {
// JSON response body
response.setContentType("application/json;type=feed");
@@ -325,7 +328,7 @@ class AtomBindingListenerServlet extends HttpServlet {
feed.writeTo(json, response.getWriter());
} catch (Exception e) {
throw new ServletException(e);
- }
+ }
} else {
// Write the Atom feed
@@ -360,23 +363,22 @@ class AtomBindingListenerServlet extends HttpServlet {
}
if (supportsFeedEntries) {
- // The service implementation returns a feed entry
+ // The service implementation returns a feed entry
feedEntry = responseMessage.getBody();
} else {
// The service implementation only returns a data item, create an entry
// from it
- Entry<Object, Object> entry = new Entry<Object, Object>(id, responseMessage.getBody());
+ Entry<Object, Object> entry = new Entry<Object, Object>(id, responseMessage.getBody());
feedEntry = feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory);
}
// Write the Atom entry
if (feedEntry != null) {
String entryETag = null;
- if (feedEntry.getId() != null)
- entryETag = feedEntry.getId().toString();
+ entryETag = HTTPUtils.calculateHashETag(feedEntry.toString().getBytes("utf-8"));
Date entryUpdated = feedEntry.getUpdated();
if ( entryUpdated != null )
response.addHeader(LASTMODIFIED, dateFormat.format( entryUpdated ));
- // TODO Check If-Modified-Since If-Unmodified-Since predicates against LASTMODIFIED.
+ // TODO Check If-Modified-Since If-Unmodified-Since predicates against LASTMODIFIED.
// If true return 304 and null body.
Link link = feedEntry.getSelfLink();
@@ -403,28 +405,28 @@ class AtomBindingListenerServlet extends HttpServlet {
return;
}
if ( entryUpdated != null ) {
- predicate = request.getHeader( "If-Unmodified-Since" );
+ predicate = request.getHeader( "If-Unmodified-Since" );
if ( predicate != null ) {
try {
- Date predicateDate = dateFormat.parse( predicate );
+ Date predicateDate = dateFormat.parse( predicate );
if ( predicateDate.compareTo( entryUpdated ) < 0 ) {
// Match, should short circuit
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
- }
+ }
} catch ( java.text.ParseException e ) {
// Ignore and move on
}
}
- predicate = request.getHeader( "If-Modified-Since" );
+ predicate = request.getHeader( "If-Modified-Since" );
if ( predicate != null ) {
try {
- Date predicateDate = dateFormat.parse( predicate );
+ Date predicateDate = dateFormat.parse( predicate );
if ( predicateDate.compareTo( entryUpdated ) > 0 ) {
// Match, should short circuit
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
- }
+ }
} catch ( java.text.ParseException e ) {
// Ignore and move on
}
@@ -439,9 +441,12 @@ class AtomBindingListenerServlet extends HttpServlet {
response.addHeader(LASTMODIFIED, dateFormat.format( entryUpdated ));
}
+ //default http header for response
+ AtomBindingHttpUtils.prepareHTTPResponse(request, response);
+
// Content negotiation
String acceptType = request.getHeader( "Accept" );
- String preferredType = getContentPreference( acceptType );
+ String preferredType = getContentPreference( acceptType );
if (( preferredType != null ) && ((preferredType.indexOf( "json") > -1) || (preferredType.indexOf( "JSON") > -1 ))) {
// JSON response body
response.setContentType("application/json;type=entry");
@@ -452,9 +457,9 @@ class AtomBindingListenerServlet extends HttpServlet {
feedEntry.writeTo(json, response.getWriter());
} catch (Exception e) {
throw new ServletException(e);
- }
+ }
} else {
- // XML response body
+ // XML response body
response.setContentType("application/atom+xml;type=entry");
try {
feedEntry.writeTo(getWriter(response));
@@ -486,7 +491,7 @@ class AtomBindingListenerServlet extends HttpServlet {
if (responseMessage.isFault()) {
throw new ServletException((Throwable)responseMessage.getBody());
}
- return (Feed)responseMessage.getBody();
+ return (Feed)responseMessage.getBody();
} else {
// The service implementation does not support feed entries,
@@ -624,10 +629,11 @@ class AtomBindingListenerServlet extends HttpServlet {
// A new entry for non-media was created successfully.
if (createdFeedEntry != null) {
+
// Set location of the created entry in the Location header
IRI feedId = createdFeedEntry.getId();
if ( feedId != null ) {
- response.addHeader(ETAG, "\"" + feedId.toString() + "\"" );
+ response.addHeader(ETAG, "\"" + HTTPUtils.calculateHashETag(createdFeedEntry.toString().getBytes("utf-8")) + "\"" );
}
Date entryUpdated = createdFeedEntry.getUpdated();
if ( entryUpdated != null ) {
@@ -636,7 +642,7 @@ class AtomBindingListenerServlet extends HttpServlet {
Link link = createdFeedEntry.getSelfLink();
if (link != null) {
response.addHeader(LOCATION, link.getHref().toString());
- }
+ }
Link editLink = createdFeedEntry.getEditLink();
if (editLink != null) {
response.addHeader(LOCATION, editLink.getHref().toString());
@@ -646,6 +652,9 @@ class AtomBindingListenerServlet extends HttpServlet {
response.addHeader(CONTENTLOCATION, editMediaLink.getHref().toString());
}
+ //default http header for response
+ AtomBindingHttpUtils.prepareHTTPResponse(request, response);
+
// Write the created Atom entry
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType("application/atom+xml;type=entry");
@@ -788,20 +797,22 @@ class AtomBindingListenerServlet extends HttpServlet {
}
}
}
-
+
/**
* Process the authorization header
- *
+ *
* @param request
* @return
* @throws ServletException
*/
private String processAuthorizationHeader(HttpServletRequest request) throws ServletException {
- // FIXME temporarily disabling this as it doesn't work with all browsers
- if (true)
+ // FIXME temporarily disabling this as it doesn't work with all browsers
+ if (true) {
return "admin";
+ }
+ /*
try {
String authorization = request.getHeader("Authorization");
if (authorization != null) {
@@ -827,12 +838,13 @@ class AtomBindingListenerServlet extends HttpServlet {
} catch (Exception e) {
throw new ServletException(e);
}
+ */
return null;
}
/**
* Authenticate a user.
- *
+ *
* @param user
* @param password
* @return
@@ -844,7 +856,7 @@ class AtomBindingListenerServlet extends HttpServlet {
/**
* Reject an unauthorized request.
- *
+ *
* @param response
*/
private void unauthorized(HttpServletResponse response) throws IOException {
@@ -859,11 +871,11 @@ class AtomBindingListenerServlet extends HttpServlet {
*/
private static String getContentPreference( String acceptType ) {
if (( acceptType == null ) || ( acceptType.length() < 1 )) {
- return "application/atom+xml";
+ return "application/atom+xml";
}
StringTokenizer st = new StringTokenizer( acceptType, "," );
if ( st.hasMoreTokens() ) {
- return st.nextToken();
+ return st.nextToken();
}
return "application/atom+xml";
}
@@ -874,7 +886,7 @@ class AtomBindingListenerServlet extends HttpServlet {
* @param properties
*/
private static void addPropertiesToHeader( HttpServletResponse response, String properties ) {
- if ( properties == null ) return;
+ if ( properties == null ) return;
StringTokenizer props = new StringTokenizer( properties, ",");
while( props.hasMoreTokens()) {
String prop = props.nextToken();
@@ -886,7 +898,7 @@ class AtomBindingListenerServlet extends HttpServlet {
if ( keyVal.hasMoreTokens() )
val = keyVal.nextToken();
if (( key != null ) && ( val != null )) {
- response.addHeader(key, val);
+ response.addHeader(key, val);
}
}
}
@@ -896,7 +908,7 @@ class AtomBindingListenerServlet extends HttpServlet {
* @param date with millisecond precision
* @return date rounded down to nearest second
*/
- private Date exactSeconds(Date date) {
+ private static Date exactSeconds(Date date) {
return new Date(date.getTime() / 1000 * 1000);
}
diff --git a/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/utils/AtomBindingHttpUtils.java b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/utils/AtomBindingHttpUtils.java
new file mode 100644
index 0000000000..684dc044d1
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/binding-atom-runtime/src/main/java/org/apache/tuscany/sca/binding/atom/utils/AtomBindingHttpUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.binding.atom.utils;
+
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tuscany.sca.common.http.HTTPUtils;
+
+public class AtomBindingHttpUtils {
+ /**
+ * Utility method to set common http headers and other stuff in a
+ * default http response. Applications / Extensions can then override and
+ * tweak as they see fit.
+ *
+ * @param response
+ */
+ public static void prepareHTTPResponse(HttpServletRequest request, HttpServletResponse response) {
+
+ // common http default response values
+ HTTPUtils.prepareHTTPResponse(response);
+
+ //set Cache-Control to no-cache to avoid intermediary
+ //proxy/reverse-proxy caches and always hit the server
+ //that would identify if the value was current or not
+ response.setHeader("Cache-Control", "no-cache");
+ response.setHeader("Expires", new Date(0).toGMTString());
+
+ }
+
+ private static boolean isIE(HttpServletRequest request) {
+ String userAgent = request.getHeader("user-agent");
+
+ return (userAgent.indexOf("MSIE") > -1);
+ }
+
+}