View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.http.client;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.Enumeration;
22  import javax.servlet.GenericServlet;
23  import javax.servlet.ServletException;
24  import javax.servlet.ServletRequest;
25  import javax.servlet.ServletResponse;
26  import javax.servlet.http.HttpServlet;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.eclipse.jetty.server.Server;
31  import org.eclipse.jetty.servlet.ServletContextHandler;
32  import org.eclipse.jetty.servlet.ServletHolder;
33  import org.junit.AfterClass;
34  import static org.junit.Assert.assertEquals;
35  import org.junit.BeforeClass;
36  
37  import org.springframework.util.SocketUtils;
38  import org.springframework.util.StreamUtils;
39  
40  /** @author Arjen Poutsma */
41  public class AbstractJettyServerTestCase {
42  
43  	protected static String baseUrl;
44  
45  	private static Server jettyServer;
46  
47  	@BeforeClass
48  	public static void startJettyServer() throws Exception {
49  		int port = SocketUtils.findAvailableTcpPort();
50  		jettyServer = new Server(port);
51  		baseUrl = "http://localhost:" + port;
52  
53  		ServletContextHandler handler = new ServletContextHandler();
54  		handler.setContextPath("/");
55  
56  		handler.addServlet(new ServletHolder(new EchoServlet()), "/echo");
57  		handler.addServlet(new ServletHolder(new StatusServlet(200)), "/status/ok");
58  		handler.addServlet(new ServletHolder(new StatusServlet(404)), "/status/notfound");
59  		handler.addServlet(new ServletHolder(new MethodServlet("DELETE")), "/methods/delete");
60  		handler.addServlet(new ServletHolder(new MethodServlet("GET")), "/methods/get");
61  		handler.addServlet(new ServletHolder(new MethodServlet("HEAD")), "/methods/head");
62  		handler.addServlet(new ServletHolder(new MethodServlet("OPTIONS")), "/methods/options");
63  		handler.addServlet(new ServletHolder(new PostServlet()), "/methods/post");
64  		handler.addServlet(new ServletHolder(new MethodServlet("PUT")), "/methods/put");
65  		handler.addServlet(new ServletHolder(new MethodServlet("PATCH")), "/methods/patch");
66  
67  		jettyServer.setHandler(handler);
68  		jettyServer.start();
69  	}
70  
71  	@AfterClass
72  	public static void stopJettyServer() throws Exception {
73  		if (jettyServer != null) {
74  			jettyServer.stop();
75  		}
76  	}
77  
78  	/**
79  	 * Servlet that sets a given status code.
80  	 */
81  	@SuppressWarnings("serial")
82  	private static class StatusServlet extends GenericServlet {
83  
84  		private final int sc;
85  
86  		private StatusServlet(int sc) {
87  			this.sc = sc;
88  		}
89  
90  		@Override
91  		public void service(ServletRequest request, ServletResponse response) throws
92  				ServletException, IOException {
93  			((HttpServletResponse) response).setStatus(sc);
94  		}
95  	}
96  
97  	@SuppressWarnings("serial")
98  	private static class MethodServlet extends GenericServlet {
99  
100 		private final String method;
101 
102 		private MethodServlet(String method) {
103 			this.method = method;
104 		}
105 
106 		@Override
107 		public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
108 			HttpServletRequest httpReq = (HttpServletRequest) req;
109 			assertEquals("Invalid HTTP method", method, httpReq.getMethod());
110 			res.setContentLength(0);
111 			((HttpServletResponse) res).setStatus(200);
112 		}
113 	}
114 
115 	@SuppressWarnings("serial")
116 	private static class PostServlet extends MethodServlet {
117 
118 		private PostServlet() {
119 			super("POST");
120 		}
121 
122 		@Override
123 		public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
124 			super.service(req, res);
125 			long contentLength = req.getContentLength();
126 			if (contentLength != -1) {
127 				InputStream in = req.getInputStream();
128 				long byteCount = 0;
129 				byte[] buffer = new byte[4096];
130 				int bytesRead;
131 				while ((bytesRead = in.read(buffer)) != -1) {
132 					byteCount += bytesRead;
133 				}
134 				assertEquals("Invalid content-length", contentLength, byteCount);
135 			}
136 		}
137 	}
138 
139 	@SuppressWarnings("serial")
140 	private static class EchoServlet extends HttpServlet {
141 
142 		@Override
143 		protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
144 			echo(req, resp);
145 		}
146 
147 		private void echo(HttpServletRequest request, HttpServletResponse response) throws IOException {
148 			response.setStatus(HttpServletResponse.SC_OK);
149 			response.setContentType(request.getContentType());
150 			response.setContentLength(request.getContentLength());
151 			for (Enumeration<String> e1 = request.getHeaderNames(); e1.hasMoreElements();) {
152 				String headerName = e1.nextElement();
153 				for (Enumeration<String> e2 = request.getHeaders(headerName); e2.hasMoreElements();) {
154 					String headerValue = e2.nextElement();
155 					response.addHeader(headerName, headerValue);
156 				}
157 			}
158 			StreamUtils.copy(request.getInputStream(), response.getOutputStream());
159 		}
160 	}
161 }