From 74021fc32adae0f081071f6fe4630b72e620ae8a Mon Sep 17 00:00:00 2001 From: lresende Date: Tue, 30 Sep 2008 07:24:48 +0000 Subject: [Work in progress] Enabling security policy for http binding. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@700368 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/provider/HTTPBindingListenerServlet.java | 317 +++++++++++++-------- .../http/provider/HTTPServiceBindingProvider.java | 6 +- .../http/provider/HTTPServiceListenerServlet.java | 60 +++- .../sca/binding/http/util/HTTPHeadersParser.java | 50 ++++ .../sca/binding/http/TestBindingCacheImpl.java | 10 +- .../tuscany/sca/binding/http/CacheContext.java | 257 ----------------- .../tuscany/sca/binding/http/HTTPCacheContext.java | 257 +++++++++++++++++ .../tuscany/sca/binding/http/HTTPHeader.java | 51 ++++ 8 files changed, 617 insertions(+), 391 deletions(-) create mode 100644 java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/util/HTTPHeadersParser.java delete mode 100644 java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java create mode 100644 java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPCacheContext.java create mode 100644 java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPHeader.java diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java index e969749358..084f52026f 100644 --- a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java +++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java @@ -24,16 +24,25 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URLDecoder; import java.text.ParseException; +import java.util.List; import javax.servlet.ServletException; +import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; -import org.apache.tuscany.sca.binding.http.CacheContext; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.binding.http.HTTPCacheContext; +import org.apache.tuscany.sca.binding.http.util.HTTPHeadersParser; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySetAttachPoint; +import org.apache.tuscany.sca.policy.authentication.basic.BasicAuthenticationPolicy; /** * Servlet responsible for dispatching HTTP requests to the @@ -44,6 +53,13 @@ import org.apache.tuscany.sca.invocation.MessageFactory; public class HTTPBindingListenerServlet extends HttpServlet { private static final long serialVersionUID = 2865466417329430610L; + private static final QName AUTEHTICATION_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","authentication"); + + transient private Binding binding; + + transient private boolean requiresAuthentication = false; + transient private BasicAuthenticationPolicy basicAuthenticationPolicy = null; + private MessageFactory messageFactory; private Invoker getInvoker; private Invoker conditionalGetInvoker; @@ -57,11 +73,48 @@ public class HTTPBindingListenerServlet extends HttpServlet { /** * Constructs a new HTTPServiceListenerServlet. */ - public HTTPBindingListenerServlet(MessageFactory messageFactory) { + public HTTPBindingListenerServlet(Binding binding, MessageFactory messageFactory) { + this.binding = binding; this.messageFactory = messageFactory; + + + // find out which policies are active + if (binding instanceof PolicySetAttachPoint) { + List intents = ((PolicySetAttachPoint)binding).getRequiredIntents(); + for(Intent intent : intents) { + if(intent.getName().equals(AUTEHTICATION_INTENT)) { + requiresAuthentication = true; + } + } + + + List policySets = ((PolicySetAttachPoint)binding).getApplicablePolicySets(); + for (PolicySet ps : policySets) { + for (Object p : ps.getPolicies()) { + if (BasicAuthenticationPolicy.class.isInstance(p)) { + basicAuthenticationPolicy = (BasicAuthenticationPolicy)p; + } else { + // etc. check for other types of policy being present + } + } + } + } } + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + if(requiresAuthentication) { + if(! hasAuthenticationHeader(request, response)) { + response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\""); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + } + } + + super.service(request, response); + } + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the request path @@ -75,12 +128,16 @@ public class HTTPBindingListenerServlet extends HttpServlet { // Invoke the get operation on the service implementation Message requestMessage = messageFactory.createMessage(); + + //store http headers to message + requestMessage.getHeaders().addAll(HTTPHeadersParser.getHeaders(request)); + String id = path.substring(1); Message responseMessage = null; - CacheContext cacheContext = null; + HTTPCacheContext cacheContext = null; try { - cacheContext = CacheContext.getCacheContextFromRequest(request); + cacheContext = HTTPCacheContext.getCacheContextFromRequest(request); } catch (ParseException e) { } @@ -144,9 +201,9 @@ public class HTTPBindingListenerServlet extends HttpServlet { String id = path.substring(1); Message responseMessage = null; - CacheContext cacheContext = null; + HTTPCacheContext cacheContext = null; try { - cacheContext = CacheContext.getCacheContextFromRequest(request); + cacheContext = HTTPCacheContext.getCacheContextFromRequest(request); } catch (ParseException e) { } @@ -210,9 +267,9 @@ public class HTTPBindingListenerServlet extends HttpServlet { String id = path.substring(1); Message responseMessage = null; - CacheContext cacheContext = null; + HTTPCacheContext cacheContext = null; try { - cacheContext = CacheContext.getCacheContextFromRequest(request); + cacheContext = HTTPCacheContext.getCacheContextFromRequest(request); } catch (ParseException e) { } @@ -276,9 +333,9 @@ public class HTTPBindingListenerServlet extends HttpServlet { // String id = path.substring(1); Message responseMessage = null; - CacheContext cacheContext = null; + HTTPCacheContext cacheContext = null; try { - cacheContext = CacheContext.getCacheContextFromRequest(request); + cacheContext = HTTPCacheContext.getCacheContextFromRequest(request); } catch (ParseException e) { } @@ -314,9 +371,9 @@ public class HTTPBindingListenerServlet extends HttpServlet { // Test if the ETag and LastModified are returned as a cache context. Object body = responseMessage.getBody(); - if ( body.getClass() == CacheContext.class ) { + if ( body.getClass() == HTTPCacheContext.class ) { // Transfer to header if so. - CacheContext cc = (CacheContext)responseMessage.getBody(); + HTTPCacheContext cc = (HTTPCacheContext)responseMessage.getBody(); if (( cc != null ) && ( cc.isEnabled() )) { String eTag = cc.getETag(); if ( eTag != null ) @@ -328,116 +385,132 @@ public class HTTPBindingListenerServlet extends HttpServlet { } } - /** - * @return the getInvoker - */ - public Invoker getGetInvoker() { - return getInvoker; - } - - /** - * @param getInvoker the getInvoker to set - */ - public void setGetInvoker(Invoker getInvoker) { - this.getInvoker = getInvoker; - } - - /** - * @return the conditionalGetInvoker - */ - public Invoker getConditionalGetInvoker() { - return conditionalGetInvoker; - } - - /** - * @param conditionalGetInvoker the conditionalGetInvoker to set - */ - public void setConditionalGetInvoker(Invoker conditionalGetInvoker) { - this.conditionalGetInvoker = conditionalGetInvoker; - } + /** + * @return the getInvoker + */ + public Invoker getGetInvoker() { + return getInvoker; + } + + /** + * @param getInvoker the getInvoker to set + */ + public void setGetInvoker(Invoker getInvoker) { + this.getInvoker = getInvoker; + } + + /** + * @return the conditionalGetInvoker + */ + public Invoker getConditionalGetInvoker() { + return conditionalGetInvoker; + } + + /** + * @param conditionalGetInvoker the conditionalGetInvoker to set + */ + public void setConditionalGetInvoker(Invoker conditionalGetInvoker) { + this.conditionalGetInvoker = conditionalGetInvoker; + } + + /** + * @return the putInvoker + */ + public Invoker getPutInvoker() { + return putInvoker; + } + + /** + * @param putInvoker the putInvoker to set + */ + public void setPutInvoker(Invoker putInvoker) { + this.putInvoker = putInvoker; + } + + /** + * @return the conditionalPutInvoker + */ + public Invoker getConditionalPutInvoker() { + return conditionalPutInvoker; + } + + /** + * @param conditionalPutInvoker the conditionalPutInvoker to set + */ + public void setConditionalPutInvoker(Invoker conditionalPutInvoker) { + this.conditionalPutInvoker = conditionalPutInvoker; + } + + /** + * @return the postInvoker + */ + public Invoker getPostInvoker() { + return postInvoker; + } + + /** + * @param postInvoker the postInvoker to set + */ + public void setPostInvoker(Invoker postInvoker) { + this.postInvoker = postInvoker; + } + + /** + * @return the conditionalPostInvoker + */ + public Invoker getConditionalPostInvoker() { + return conditionalPostInvoker; + } + + /** + * @param conditionalPostInvoker the conditionalPostInvoker to set + */ + public void setConditionalPostInvoker(Invoker conditionalPostInvoker) { + this.conditionalPostInvoker = conditionalPostInvoker; + } + + /** + * @return the deleteInvoker + */ + public Invoker getDeleteInvoker() { + return deleteInvoker; + } + + /** + * @param deleteInvoker the deleteInvoker to set + */ + public void setDeleteInvoker(Invoker deleteInvoker) { + this.deleteInvoker = deleteInvoker; + } + + /** + * @return the conditionalDeleteInvoker + */ + public Invoker getConditionalDeleteInvoker() { + return conditionalDeleteInvoker; + } + + /** + * @param conditionalDeleteInvoker the conditionalDeleteInvoker to set + */ + public void setConditionalDeleteInvoker(Invoker conditionalDeleteInvoker) { + this.conditionalDeleteInvoker = conditionalDeleteInvoker; + } + + + /** + * Utility Methods related to Policy + */ - /** - * @return the putInvoker - */ - public Invoker getPutInvoker() { - return putInvoker; - } - - /** - * @param putInvoker the putInvoker to set - */ - public void setPutInvoker(Invoker putInvoker) { - this.putInvoker = putInvoker; - } - - /** - * @return the conditionalPutInvoker - */ - public Invoker getConditionalPutInvoker() { - return conditionalPutInvoker; - } - - /** - * @param conditionalPutInvoker the conditionalPutInvoker to set - */ - public void setConditionalPutInvoker(Invoker conditionalPutInvoker) { - this.conditionalPutInvoker = conditionalPutInvoker; - } - - /** - * @return the postInvoker - */ - public Invoker getPostInvoker() { - return postInvoker; - } - - /** - * @param postInvoker the postInvoker to set - */ - public void setPostInvoker(Invoker postInvoker) { - this.postInvoker = postInvoker; - } - - /** - * @return the conditionalPostInvoker - */ - public Invoker getConditionalPostInvoker() { - return conditionalPostInvoker; - } - - /** - * @param conditionalPostInvoker the conditionalPostInvoker to set - */ - public void setConditionalPostInvoker(Invoker conditionalPostInvoker) { - this.conditionalPostInvoker = conditionalPostInvoker; - } - - /** - * @return the deleteInvoker - */ - public Invoker getDeleteInvoker() { - return deleteInvoker; - } - - /** - * @param deleteInvoker the deleteInvoker to set - */ - public void setDeleteInvoker(Invoker deleteInvoker) { - this.deleteInvoker = deleteInvoker; - } - - /** - * @return the conditionalDeleteInvoker - */ - public Invoker getConditionalDeleteInvoker() { - return conditionalDeleteInvoker; - } - - /** - * @param conditionalDeleteInvoker the conditionalDeleteInvoker to set - */ - public void setConditionalDeleteInvoker(Invoker conditionalDeleteInvoker) { - this.conditionalDeleteInvoker = conditionalDeleteInvoker; - } + + private boolean hasAuthenticationHeader(HttpServletRequest request, ServletResponse response) { + boolean result = false; + if(request.getHeader("Authorization") != null) { + result = true; + } + + return result; + } + } diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java index 0a8f74edca..8f91ff4343 100644 --- a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java +++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java @@ -39,10 +39,10 @@ import org.apache.tuscany.sca.runtime.RuntimeWire; * @version $Rev$ $Date$ */ public class HTTPServiceBindingProvider implements ServiceBindingProvider { - private RuntimeComponentService service; private HTTPBinding binding; private MessageFactory messageFactory; + private ServletHost servletHost; private String servletMapping; private HTTPBindingListenerServlet bindingListenerServlet; @@ -63,7 +63,7 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider { RuntimeComponentService componentService = (RuntimeComponentService) service; RuntimeWire wire = componentService.getRuntimeWire(binding); Servlet servlet = null; - bindingListenerServlet = new HTTPBindingListenerServlet( messageFactory ); + bindingListenerServlet = new HTTPBindingListenerServlet(binding, messageFactory ); for (InvocationChain invocationChain : wire.getInvocationChains()) { Operation operation = invocationChain.getTargetOperation(); String operationName = operation.getName(); @@ -101,7 +101,7 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider { servlet = bindingListenerServlet; } else if (operationName.equals("service")) { Invoker serviceInvoker = invocationChain.getHeadInvoker(); - servlet = new HTTPServiceListenerServlet(serviceInvoker, messageFactory); + servlet = new HTTPServiceListenerServlet(binding, serviceInvoker, messageFactory); break; } } diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java index 03b91c4db2..493255655d 100644 --- a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java +++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java @@ -20,17 +20,25 @@ package org.apache.tuscany.sca.binding.http.provider; import java.io.IOException; +import java.util.List; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; +import org.apache.tuscany.sca.assembly.Binding; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySetAttachPoint; +import org.apache.tuscany.sca.policy.authentication.basic.BasicAuthenticationPolicy; /** * Servlet responsible for dispatching HTTP service requests to the @@ -39,17 +47,45 @@ import org.apache.tuscany.sca.invocation.MessageFactory; * @version $Rev$ $Date$ */ public class HTTPServiceListenerServlet implements Servlet { + private static final QName AUTEHTICATION_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","authentication"); - private ServletConfig config; - private MessageFactory messageFactory; - private Invoker serviceInvoker; + transient private Binding binding; + transient private ServletConfig config; + transient private MessageFactory messageFactory; + transient private Invoker serviceInvoker; + transient private boolean requiresAuthentication = false; + transient private BasicAuthenticationPolicy basicAuthenticationPolicy = null; + /** * Constructs a new HTTPServiceListenerServlet. */ - public HTTPServiceListenerServlet(Invoker serviceInvoker, MessageFactory messageFactory) { + public HTTPServiceListenerServlet(Binding binding, Invoker serviceInvoker, MessageFactory messageFactory) { + this.binding = binding; this.serviceInvoker = serviceInvoker; this.messageFactory = messageFactory; + + // find out which policies are active + if (binding instanceof PolicySetAttachPoint) { + List intents = ((PolicySetAttachPoint)binding).getRequiredIntents(); + for(Intent intent : intents) { + if(intent.getName().equals(AUTEHTICATION_INTENT)) { + requiresAuthentication = true; + } + } + + + List policySets = ((PolicySetAttachPoint)binding).getApplicablePolicySets(); + for (PolicySet ps : policySets) { + for (Object p : ps.getPolicies()) { + if (BasicAuthenticationPolicy.class.isInstance(p)) { + basicAuthenticationPolicy = (BasicAuthenticationPolicy)p; + } else { + // etc. check for other types of policy being present + } + } + } + } } public ServletConfig getServletConfig() { @@ -65,10 +101,17 @@ public class HTTPServiceListenerServlet implements Servlet { } public void destroy() { + } public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { + if(requiresAuthentication) { + if(! hasAuthenticationHeader((HttpServletRequest)request, (HttpServletResponse)response)) { + ((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED); + } + } + // Dispatch the service interaction to the service invoker Message requestMessage = messageFactory.createMessage(); requestMessage.setBody(new Object[]{request, response}); @@ -81,4 +124,13 @@ public class HTTPServiceListenerServlet implements Servlet { } } + + private boolean hasAuthenticationHeader(HttpServletRequest request, ServletResponse response) { + boolean result = false; + if(request.getHeader("Authorization") != null) { + result = true; + } + + return result; + } } diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/util/HTTPHeadersParser.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/util/HTTPHeadersParser.java new file mode 100644 index 0000000000..1fe4600e31 --- /dev/null +++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/util/HTTPHeadersParser.java @@ -0,0 +1,50 @@ +/* + * 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.http.util; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.tuscany.sca.binding.http.HTTPHeader; + +public class HTTPHeadersParser { + + /** + * Parse http request headers to a map + * + * @param request + * @return + */ + public static List getHeaders(HttpServletRequest request) { + List headers = new ArrayList(); + + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = (String) headerNames.nextElement(); + Object headerValue = request.getHeader(headerName); + HTTPHeader header = new HTTPHeader(headerName, headerValue); + headers.add(header); + } + return headers; + } +} diff --git a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestBindingCacheImpl.java b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestBindingCacheImpl.java index a3fce376f3..f2456f3175 100644 --- a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestBindingCacheImpl.java +++ b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestBindingCacheImpl.java @@ -49,7 +49,7 @@ public class TestBindingCacheImpl { * @param id * @return */ - public InputStream conditionalGet(String id, CacheContext cacheContext) + public InputStream conditionalGet(String id, HTTPCacheContext cacheContext) throws NotModifiedException, PreconditionFailedException { if (cacheContext != null) { @@ -99,7 +99,7 @@ public class TestBindingCacheImpl { * @param id * @return */ - public InputStream conditionalDelete(String id, CacheContext cacheContext) + public InputStream conditionalDelete(String id, HTTPCacheContext cacheContext) throws NotModifiedException, PreconditionFailedException { if (cacheContext != null) { @@ -151,7 +151,7 @@ public class TestBindingCacheImpl { * @param id * @return */ - public CacheContext conditionalPost(CacheContext cacheContext) + public HTTPCacheContext conditionalPost(HTTPCacheContext cacheContext) throws NotModifiedException, PreconditionFailedException { String id = "" + (new java.util.Random()).nextInt(Integer.MAX_VALUE); @@ -180,7 +180,7 @@ public class TestBindingCacheImpl { } // Return the ETag and LastModfied fields by serialize to a byte array - CacheContext returnContext = new CacheContext(); + HTTPCacheContext returnContext = new HTTPCacheContext(); returnContext.setETag( "ETag" + (new java.util.Random()).nextInt(Integer.MAX_VALUE) ); returnContext.setLastModified( new Date() ); return returnContext; @@ -202,7 +202,7 @@ public class TestBindingCacheImpl { * @param id * @return */ - public InputStream conditionalPut(String id, CacheContext cacheContext) + public InputStream conditionalPut(String id, HTTPCacheContext cacheContext) throws NotModifiedException, PreconditionFailedException { if (cacheContext != null) { diff --git a/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java deleted file mode 100644 index aa80b7a40b..0000000000 --- a/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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.http; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; - -/** - * A class to store cache settings for Atom and HTTP requests and responses. - * - * Predicates are statements that work in conjunction with - * ETags and LastModified dates to determine if a precondition - * or postcondition is satisfied. - * See HTTP specification for how predicates wrk: - * http://tools.ietf.org/html/rfc2616 - * Example predicates in HTTP include If-Match, If-None-Match, - * If-Modified-Since, If-Unmodified-Since, If-Range. - - */ -public class CacheContext { - public static final SimpleDateFormat RFC822DateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time - - public boolean enabled; - public String eTag; - public String lastModified; - public Date lastModifiedDate; - public boolean ifModifiedSince; - public boolean ifUnmodifiedSince; - public boolean ifMatch; - public boolean ifNoneMatch; - public boolean ifRange; - - /** - * An ETag is a unique ID for an item. It changes when - * a field in the item or the update date changes. - * See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the eTag - */ - public String getETag() { - return eTag; - } - /** - * @param tag the eTag to set - */ - public void setETag(String tag) { - eTag = tag; - enabled = true; - } - /** - * The LastModified date is the time the item was last - * changed. See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the lastModified - */ - public String getLastModified() { - return lastModified; - } - /** - * The LastModified date is the time the item was last - * changed. See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the lastModified - */ - public Date getLastModifiedAsDate() { - return lastModifiedDate; - } - /** - * @param lastModified the lastModified to set - */ - public void setLastModified(String lastModified) throws java.text.ParseException { - this.lastModified = lastModified; - // Catch date formatting on input to help debugging. - lastModifiedDate = RFC822DateFormat.parse( lastModified ); - enabled = true; - } - - /** - * @param lastModified the lastModified to set - */ - public void setLastModified(Date updated) { - this.lastModified = RFC822DateFormat.format( updated ); - lastModifiedDate = updated; - enabled = true; - } - - /** - * @return the ifModifedSince - */ - public boolean isIfModifiedSince() { - return ifModifiedSince; - } - /** - * @param ifModifedSince the ifModifedSince to set - */ - public void setIfModifiedSince(boolean ifModifiedSince) { - this.ifModifiedSince = ifModifiedSince; - if ( ifModifiedSince ) - enabled = true; - } - /** - * @return the ifUnModifiedSince - */ - public boolean isIfUnmodifiedSince() { - return ifUnmodifiedSince; - } - /** - * @param ifUnModifiedSince the ifUnModifiedSince to set - */ - public void setIfUnmodifiedSince(boolean ifUnmodifiedSince) { - this.ifUnmodifiedSince = ifUnmodifiedSince; - if ( ifUnmodifiedSince ) - enabled = true; - } - /** - * @return the ifMatch - */ - public boolean isIfMatch() { - return ifMatch; - } - /** - * @param ifMatch the ifMatch to set - */ - public void setIfMatch(boolean ifMatch) { - this.ifMatch = ifMatch; - if ( ifMatch ) - enabled = true; - } - /** - * @return the ifNoneMatch - */ - public boolean isIfNoneMatch() { - return ifNoneMatch; - } - /** - * @param ifNoneMatch the ifNoneMatch to set - */ - public void setIfNoneMatch(boolean ifNoneMatch) { - this.ifNoneMatch = ifNoneMatch; - if ( ifNoneMatch ) - enabled = true; - } - /** - * @return the ifRange - */ - public boolean isIfRange() { - return ifRange; - } - /** - * @param ifRange the ifRange to set - */ - public void setIfRange(boolean ifRange) { - this.ifRange = ifRange; - if ( ifRange ) - enabled = true; - } - - public String toString() { - final String PREDPREFIX = ", predicates="; - StringBuffer sb = new StringBuffer(PREDPREFIX); - if ( ifMatch || ifNoneMatch || ifModifiedSince || ifUnmodifiedSince || ifRange ) { - if ( ifMatch ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Match"); - } - if ( ifNoneMatch ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-None-Match"); - } - if ( ifModifiedSince ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Modified-Since"); - } - if ( ifUnmodifiedSince ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-UnModified-Since"); - } - if ( ifRange ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Range"); - } - } else { - sb.append("null"); - } - - return "eTag=" + eTag + ", lastModified=" + lastModified - + sb.toString(); - } - - /** - * Gets the cache context information (ETag, LastModified, predicates) from the Http request. - * @param request - * @return - */ - public static CacheContext getCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException { - CacheContext context = new CacheContext(); - - String eTag = request.getHeader( "If-Match" ); - if ( eTag != null ) { - context.setETag( eTag ); - context.setIfMatch( true ); - } - eTag = request.getHeader( "If-None-Match" ); - if ( eTag != null ) { - context.setETag( eTag ); - context.setIfNoneMatch( true ); - } - String lastModifiedString = request.getHeader( "If-Modified-Since" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfModifiedSince( true ); - } - lastModifiedString = request.getHeader( "If-Unmodified-Since" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfUnmodifiedSince( true ); - } - lastModifiedString = request.getHeader( "If-Range" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfRange( true ); - } - return context; - } - /** - * Enabled is true whenever ETag, LastModified, or predicate is set. - * @return the enabled - */ - public boolean isEnabled() { - return enabled; - } - /** - * @param enabled the enabled to set - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } -} diff --git a/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPCacheContext.java b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPCacheContext.java new file mode 100644 index 0000000000..023423f0eb --- /dev/null +++ b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPCacheContext.java @@ -0,0 +1,257 @@ +/* + * 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.http; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.servlet.http.HttpServletRequest; + +/** + * A class to store cache settings for Atom and HTTP requests and responses. + * + * Predicates are statements that work in conjunction with + * ETags and LastModified dates to determine if a precondition + * or postcondition is satisfied. + * See HTTP specification for how predicates wrk: + * http://tools.ietf.org/html/rfc2616 + * Example predicates in HTTP include If-Match, If-None-Match, + * If-Modified-Since, If-Unmodified-Since, If-Range. + + */ +public class HTTPCacheContext { + public static final SimpleDateFormat RFC822DateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time + + public boolean enabled; + public String eTag; + public String lastModified; + public Date lastModifiedDate; + public boolean ifModifiedSince; + public boolean ifUnmodifiedSince; + public boolean ifMatch; + public boolean ifNoneMatch; + public boolean ifRange; + + /** + * An ETag is a unique ID for an item. It changes when + * a field in the item or the update date changes. + * See HTTP specification for how ETags work: + * http://tools.ietf.org/html/rfc2616 + * @return the eTag + */ + public String getETag() { + return eTag; + } + /** + * @param tag the eTag to set + */ + public void setETag(String tag) { + eTag = tag; + enabled = true; + } + /** + * The LastModified date is the time the item was last + * changed. See HTTP specification for how ETags work: + * http://tools.ietf.org/html/rfc2616 + * @return the lastModified + */ + public String getLastModified() { + return lastModified; + } + /** + * The LastModified date is the time the item was last + * changed. See HTTP specification for how ETags work: + * http://tools.ietf.org/html/rfc2616 + * @return the lastModified + */ + public Date getLastModifiedAsDate() { + return lastModifiedDate; + } + /** + * @param lastModified the lastModified to set + */ + public void setLastModified(String lastModified) throws java.text.ParseException { + this.lastModified = lastModified; + // Catch date formatting on input to help debugging. + lastModifiedDate = RFC822DateFormat.parse( lastModified ); + enabled = true; + } + + /** + * @param lastModified the lastModified to set + */ + public void setLastModified(Date updated) { + this.lastModified = RFC822DateFormat.format( updated ); + lastModifiedDate = updated; + enabled = true; + } + + /** + * @return the ifModifedSince + */ + public boolean isIfModifiedSince() { + return ifModifiedSince; + } + /** + * @param ifModifedSince the ifModifedSince to set + */ + public void setIfModifiedSince(boolean ifModifiedSince) { + this.ifModifiedSince = ifModifiedSince; + if ( ifModifiedSince ) + enabled = true; + } + /** + * @return the ifUnModifiedSince + */ + public boolean isIfUnmodifiedSince() { + return ifUnmodifiedSince; + } + /** + * @param ifUnModifiedSince the ifUnModifiedSince to set + */ + public void setIfUnmodifiedSince(boolean ifUnmodifiedSince) { + this.ifUnmodifiedSince = ifUnmodifiedSince; + if ( ifUnmodifiedSince ) + enabled = true; + } + /** + * @return the ifMatch + */ + public boolean isIfMatch() { + return ifMatch; + } + /** + * @param ifMatch the ifMatch to set + */ + public void setIfMatch(boolean ifMatch) { + this.ifMatch = ifMatch; + if ( ifMatch ) + enabled = true; + } + /** + * @return the ifNoneMatch + */ + public boolean isIfNoneMatch() { + return ifNoneMatch; + } + /** + * @param ifNoneMatch the ifNoneMatch to set + */ + public void setIfNoneMatch(boolean ifNoneMatch) { + this.ifNoneMatch = ifNoneMatch; + if ( ifNoneMatch ) + enabled = true; + } + /** + * @return the ifRange + */ + public boolean isIfRange() { + return ifRange; + } + /** + * @param ifRange the ifRange to set + */ + public void setIfRange(boolean ifRange) { + this.ifRange = ifRange; + if ( ifRange ) + enabled = true; + } + + public String toString() { + final String PREDPREFIX = ", predicates="; + StringBuffer sb = new StringBuffer(PREDPREFIX); + if ( ifMatch || ifNoneMatch || ifModifiedSince || ifUnmodifiedSince || ifRange ) { + if ( ifMatch ) { + if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); + sb.append("If-Match"); + } + if ( ifNoneMatch ) { + if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); + sb.append("If-None-Match"); + } + if ( ifModifiedSince ) { + if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); + sb.append("If-Modified-Since"); + } + if ( ifUnmodifiedSince ) { + if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); + sb.append("If-UnModified-Since"); + } + if ( ifRange ) { + if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); + sb.append("If-Range"); + } + } else { + sb.append("null"); + } + + return "eTag=" + eTag + ", lastModified=" + lastModified + + sb.toString(); + } + + /** + * Gets the cache context information (ETag, LastModified, predicates) from the Http request. + * @param request + * @return + */ + public static HTTPCacheContext getCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException { + HTTPCacheContext context = new HTTPCacheContext(); + + String eTag = request.getHeader( "If-Match" ); + if ( eTag != null ) { + context.setETag( eTag ); + context.setIfMatch( true ); + } + eTag = request.getHeader( "If-None-Match" ); + if ( eTag != null ) { + context.setETag( eTag ); + context.setIfNoneMatch( true ); + } + String lastModifiedString = request.getHeader( "If-Modified-Since" ); + if ( lastModifiedString != null ) { + context.setLastModified( lastModifiedString ); + context.setIfModifiedSince( true ); + } + lastModifiedString = request.getHeader( "If-Unmodified-Since" ); + if ( lastModifiedString != null ) { + context.setLastModified( lastModifiedString ); + context.setIfUnmodifiedSince( true ); + } + lastModifiedString = request.getHeader( "If-Range" ); + if ( lastModifiedString != null ) { + context.setLastModified( lastModifiedString ); + context.setIfRange( true ); + } + return context; + } + /** + * Enabled is true whenever ETag, LastModified, or predicate is set. + * @return the enabled + */ + public boolean isEnabled() { + return enabled; + } + /** + * @param enabled the enabled to set + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPHeader.java b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPHeader.java new file mode 100644 index 0000000000..69e44cf35c --- /dev/null +++ b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/HTTPHeader.java @@ -0,0 +1,51 @@ +/* + * 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.http; + +public class HTTPHeader { + private String name; + private Object value; + + public HTTPHeader() { + + } + + public HTTPHeader(String name, Object value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + +} -- cgit v1.2.3