Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 9715 invoked from network); 24 Jun 2009 14:06:05 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 24 Jun 2009 14:06:05 -0000 Received: (qmail 43768 invoked by uid 500); 24 Jun 2009 14:06:16 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 43668 invoked by uid 500); 24 Jun 2009 14:06:16 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 43659 invoked by uid 99); 24 Jun 2009 14:06:16 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Jun 2009 14:06:16 +0000 X-ASF-Spam-Status: No, hits=-1998.5 required=10.0 tests=ALL_TRUSTED,WEIRD_PORT X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Jun 2009 14:06:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C549D23888D6; Wed, 24 Jun 2009 14:05:50 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r788030 - in /cxf/trunk: rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/ systests/src/test/java/org/apache/cxf/systest/jaxrs/ systests/src/test/java/org/a... Date: Wed, 24 Jun 2009 14:05:50 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090624140550.C549D23888D6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sergeyb Date: Wed Jun 24 14:05:50 2009 New Revision: 788030 URL: http://svn.apache.org/viewvc?rev=788030&view=rev Log: Updating AbstractCxfServlet to support arbitrary HTTP methods Added: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java (with props) cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt (with props) Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java?rev=788030&r1=788029&r2=788030&view=diff ============================================================================== --- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java (original) +++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java Wed Jun 24 14:05:50 2009 @@ -20,12 +20,16 @@ import java.io.IOException; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.Hashtable; +import java.util.List; import java.util.Map; import java.util.logging.Logger; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -40,9 +44,16 @@ public abstract class AbstractCXFServlet extends HttpServlet { + static final Map> BUS_MAP = new Hashtable>(); static final Logger LOG = getLogger(); + /** + * List of well-known HTTP 1.1 verbs, with POST and GET being the most used verbs at the top + */ + private static final List KNOWN_HTTP_VERBS = + Arrays.asList(new String[]{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE"}); + protected Bus bus; protected ServletTransportFactory servletTransportFactory; protected ServletController controller; @@ -137,11 +148,13 @@ bus.shutdown(true); } - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException { invoke(request, response); } - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException { invoke(request, response); } @@ -152,12 +165,56 @@ } @Override - protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException { + protected void doPut(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + invoke(request, response); + } + + @Override + protected void doHead(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + invoke(request, response); + } + + @Override + protected void doOptions(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { invoke(request, response); } - private void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + + /** + * {@inheritDoc} + * + * javax.http.servlet.HttpServlet does not let to override the code which deals with + * unrecognized HTTP verbs such as PATCH (being standardized), WebDav ones, etc. + * Thus we let CXF servlets process unrecognized HTTP verbs directly, otherwise we delegate + * to HttpService + */ + @Override + public void service(ServletRequest req, ServletResponse res) + throws ServletException, IOException { + + HttpServletRequest request; + HttpServletResponse response; + + try { + request = (HttpServletRequest) req; + response = (HttpServletResponse) res; + } catch (ClassCastException e) { + throw new ServletException("Unrecognized HTTP request or response object"); + } + + String method = request.getMethod(); + if (KNOWN_HTTP_VERBS.contains(method)) { + super.service(request, response); + } else { + invoke(request, response); + } + } + + protected void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { BusFactory.setThreadDefaultBus(getBus()); controller.invoke(request, response); Added: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java?rev=788030&view=auto ============================================================================== --- cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java (added) +++ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java Wed Jun 24 14:05:50 2009 @@ -0,0 +1,163 @@ +/** + * 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.cxf.transport.servlet; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.easymock.classextension.EasyMock; + +import org.junit.Assert; +import org.junit.Test; + +public class AbstractCXFServletTest extends Assert { + + @Test + public void testPost() throws Exception { + testHttpMethod("POST"); + } + + @Test + public void testGet() throws Exception { + testHttpMethod("GET"); + } + + @Test + public void testPut() throws Exception { + testHttpMethod("PUT"); + } + + @Test + public void testDelete() throws Exception { + testHttpMethod("DELETE"); + } + + @Test + public void testHead() throws Exception { + testHttpMethod("HEAD"); + } + + @Test + public void testOptions() throws Exception { + testHttpMethod("OPTIONS"); + } + + @Test + public void testPatch() throws Exception { + testHttpMethod("PATCH", true); + } + + private void testHttpMethod(String method) throws Exception { + testHttpMethod(method, false); + } + + private void testHttpMethod(String method, boolean setMethod) throws Exception { + TestServlet servlet = new TestServlet(); + if (setMethod) { + servlet.setMethod(method); + } + HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class); + HttpServletResponse res = EasyMock.createMock(HttpServletResponse.class); + + req.getMethod(); + EasyMock.expectLastCall().andReturn(method).times(3); + EasyMock.replay(req); + + servlet.service(req, res); + assertTrue(servlet.isInvoked()); + assertEquals(method, servlet.getMethod()); + } + + private static class TestServlet extends AbstractCXFServlet { + + private boolean invoked; + private String method; + @Override + public void loadBus(ServletConfig servletConfig) throws ServletException { + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException { + method = "POST"; + super.doPost(request, response); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException { + method = "GET"; + super.doGet(request, response); + } + + @Override + protected void doPut(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + method = "PUT"; + super.doPut(request, response); + } + + @Override + protected void doDelete(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + method = "DELETE"; + super.doDelete(request, response); + } + + @Override + protected void doHead(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + method = "HEAD"; + super.doHead(request, response); + } + + @Override + protected void doOptions(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + method = "OPTIONS"; + super.doOptions(request, response); + } + + @Override + protected void invoke(HttpServletRequest request, HttpServletResponse response) + throws ServletException { + assertEquals(method, request.getMethod()); + invoked = true; + } + + public boolean isInvoked() { + return invoked; + } + + public String getMethod() { + return method; + } + + public void setMethod(String m) { + method = m; + } + + } + +} Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=788030&r1=788029&r2=788030&view=diff ============================================================================== --- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original) +++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Wed Jun 24 14:05:50 2009 @@ -129,7 +129,7 @@ @RETRIEVE @Path("books/aegis/retrieve") - @Produces({"application/html;q=1.0", "application/xml;q=0.5", "application/json;q=0.5" }) + @Produces({"application/html;q=0.5", "application/xml;q=1.0", "application/json;q=0.5" }) public Book getBookAegisRetrieve() { return getBookAegis(); } Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=788030&r1=788029&r2=788030&view=diff ============================================================================== --- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original) +++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Wed Jun 24 14:05:50 2009 @@ -19,8 +19,11 @@ package org.apache.cxf.systest.jaxrs; +import java.io.BufferedReader; import java.io.File; import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.Socket; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; @@ -31,7 +34,6 @@ import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.FileRequestEntity; -import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.cxf.helpers.IOUtils; @@ -232,20 +234,29 @@ } @Test - @Ignore public void testRetrieveBookAegis3() throws Exception { - GetMethod get = new GetMethod("http://localhost:9080/the/thebooks4/bookstore/books/aegis/retrieve"); - get.setRequestHeader("Content-Type", "*/*"); - get.setRequestHeader("Accept", "application/xml"); - HttpClient httpClient = new HttpClient(); - try { - httpClient.executeMethod(get); - String aegisData = getStringFromInputStream(get.getResponseBodyAsStream()); - InputStream expected = getClass().getResourceAsStream("resources/expected_add_book_aegis.txt"); - assertEquals(getStringFromInputStream(expected), aegisData); - } finally { - get.releaseConnection(); + + Socket s = new Socket("localhost", 9080); + + InputStream is = this.getClass().getResourceAsStream("resources/retrieveRequest.txt"); + byte[] bytes = IOUtils.readBytesFromStream(is); + s.getOutputStream().write(bytes); + s.getOutputStream().flush(); + + BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream())); + StringBuilder sb = new StringBuilder(); + String str = null; + while ((str = r.readLine()) != null) { + sb.append(str); } + + String aegisData = sb.toString(); + s.getInputStream().close(); + s.close(); + String expected = getStringFromInputStream( + getClass().getResourceAsStream("resources/expected_add_book_aegis.txt")); + assertTrue(aegisData.contains(expected)); + } @Test Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt?rev=788030&view=auto ============================================================================== --- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt (added) +++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt Wed Jun 24 14:05:50 2009 @@ -0,0 +1,7 @@ +RETRIEVE /the/thebooks4/bookstore/books/aegis/retrieve HTTP/1.1 +Content-Type: */* +Accept: application/xml +User-Agent: Java/1.5.0_12 +Host: localhost:9080 +Connection: close + Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt ------------------------------------------------------------------------------ svn:mime-type = text/plain