001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.transport.http;
021:
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.OutputStream;
025: import java.util.HashMap;
026: import java.util.Map;
027: import java.util.Iterator;
028:
029: import org.apache.axis2.Constants;
030: import org.apache.axis2.context.ConfigurationContext;
031: import org.apache.axis2.context.MessageContext;
032: import org.apache.axis2.context.OperationContext;
033: import org.apache.axis2.deployment.DeploymentConstants;
034: import org.apache.axis2.description.AxisService;
035: import org.apache.axis2.engine.Handler.InvocationResponse;
036: import org.apache.axis2.transport.RequestResponseTransport;
037: import org.apache.axis2.transport.TransportUtils;
038: import org.apache.axis2.transport.http.server.AxisHttpRequest;
039: import org.apache.axis2.transport.http.server.AxisHttpResponse;
040: import org.apache.axis2.transport.http.server.HttpUtils;
041: import org.apache.axis2.transport.http.server.Worker;
042: import org.apache.axis2.transport.http.util.RESTUtil;
043: import org.apache.http.Header;
044: import org.apache.http.HttpException;
045: import org.apache.http.HttpStatus;
046: import org.apache.http.MethodNotSupportedException;
047: import org.apache.http.message.BasicHeader;
048: import org.apache.http.protocol.HTTP;
049: import org.apache.http.util.EncodingUtils;
050: import org.apache.ws.commons.schema.XmlSchema;
051:
052: public class HTTPWorker implements Worker {
053:
054: public HTTPWorker() {
055: }
056:
057: public void service(final AxisHttpRequest request,
058: final AxisHttpResponse response,
059: final MessageContext msgContext) throws HttpException,
060: IOException {
061:
062: ConfigurationContext configurationContext = msgContext
063: .getConfigurationContext();
064: final String servicePath = configurationContext
065: .getServiceContextPath();
066: final String contextPath = (servicePath.startsWith("/") ? servicePath
067: : "/" + servicePath)
068: + "/";
069:
070: String uri = request.getRequestURI();
071: String method = request.getMethod();
072: String soapAction = HttpUtils.getSoapAction(request);
073: InvocationResponse pi;
074:
075: if (method.equals(HTTPConstants.HEADER_GET)) {
076: if (uri.equals("/favicon.ico")) {
077: response.setStatus(HttpStatus.SC_MOVED_PERMANENTLY);
078: response.addHeader(new BasicHeader("Location",
079: "http://ws.apache.org/favicon.ico"));
080: return;
081: }
082: if (!uri.startsWith(contextPath)) {
083: response.setStatus(HttpStatus.SC_MOVED_PERMANENTLY);
084: response.addHeader(new BasicHeader("Location",
085: contextPath));
086: return;
087: }
088: if (uri.endsWith("axis2/services/")) {
089: String s = HTTPTransportReceiver
090: .getServicesHTML(configurationContext);
091: response.setStatus(HttpStatus.SC_OK);
092: response.setContentType("text/html");
093: OutputStream out = response.getOutputStream();
094: out.write(EncodingUtils.getBytes(s, HTTP.ISO_8859_1));
095: return;
096: }
097: if (uri.indexOf("?") < 0) {
098: if (!uri.endsWith(contextPath)) {
099: if (uri.endsWith(".xsd") || uri.endsWith(".wsdl")) {
100: HashMap services = configurationContext
101: .getAxisConfiguration().getServices();
102: String file = uri.substring(uri
103: .lastIndexOf("/") + 1, uri.length());
104: if ((services != null) && !services.isEmpty()) {
105: Iterator i = services.values().iterator();
106: while (i.hasNext()) {
107: AxisService service = (AxisService) i
108: .next();
109: InputStream stream = service
110: .getClassLoader()
111: .getResourceAsStream(
112: "META-INF/" + file);
113: if (stream != null) {
114: OutputStream out = response
115: .getOutputStream();
116: response.setContentType("text/xml");
117: ListingAgent.copy(stream, out);
118: out.flush();
119: out.close();
120: return;
121: }
122: }
123: }
124: } else {
125: String serviceName = uri.replaceAll(
126: contextPath, "");
127: if (serviceName.indexOf("/") < 0) {
128: String s = HTTPTransportReceiver
129: .printServiceHTML(serviceName,
130: configurationContext);
131: response.setStatus(HttpStatus.SC_OK);
132: response.setContentType("text/html");
133: OutputStream out = response
134: .getOutputStream();
135: out.write(EncodingUtils.getBytes(s,
136: HTTP.ISO_8859_1));
137: return;
138: }
139: }
140: }
141: }
142: if (uri.endsWith("?wsdl2")) {
143: String serviceName = uri.substring(
144: uri.lastIndexOf("/") + 1, uri.length() - 6);
145: HashMap services = configurationContext
146: .getAxisConfiguration().getServices();
147: AxisService service = (AxisService) services
148: .get(serviceName);
149: if (service != null) {
150: response.setStatus(HttpStatus.SC_OK);
151: response.setContentType("text/xml");
152: service.printWSDL2(response.getOutputStream(),
153: getHost(request));
154: return;
155: }
156: }
157: if (uri.endsWith("?wsdl")) {
158: String serviceName = uri.substring(
159: uri.lastIndexOf("/") + 1, uri.length() - 5);
160: HashMap services = configurationContext
161: .getAxisConfiguration().getServices();
162: AxisService service = (AxisService) services
163: .get(serviceName);
164: if (service != null) {
165: response.setStatus(HttpStatus.SC_OK);
166: response.setContentType("text/xml");
167: service.printWSDL(response.getOutputStream(),
168: getHost(request));
169: return;
170: }
171: }
172: if (uri.endsWith("?xsd")) {
173: String serviceName = uri.substring(
174: uri.lastIndexOf("/") + 1, uri.length() - 4);
175: HashMap services = configurationContext
176: .getAxisConfiguration().getServices();
177: AxisService service = (AxisService) services
178: .get(serviceName);
179: if (service != null) {
180: response.setStatus(HttpStatus.SC_OK);
181: response.setContentType("text/xml");
182: service.printSchema(response.getOutputStream());
183: return;
184: }
185: }
186: //cater for named xsds - check for the xsd name
187: if (uri.indexOf("?xsd=") > 0) {
188: String serviceName = uri.substring(
189: uri.lastIndexOf("/") + 1, uri
190: .lastIndexOf("?xsd="));
191: String schemaName = uri
192: .substring(uri.lastIndexOf("=") + 1);
193:
194: HashMap services = configurationContext
195: .getAxisConfiguration().getServices();
196: AxisService service = (AxisService) services
197: .get(serviceName);
198: if (service != null) {
199: //run the population logic just to be sure
200: service.populateSchemaMappings();
201: //write out the correct schema
202: Map schemaTable = service.getSchemaMappingTable();
203: XmlSchema schema = (XmlSchema) schemaTable
204: .get(schemaName);
205: if (schema == null) {
206: int dotIndex = schemaName.indexOf('.');
207: if (dotIndex > 0) {
208: String schemaKey = schemaName.substring(0,
209: dotIndex);
210: schema = (XmlSchema) schemaTable
211: .get(schemaKey);
212: }
213: }
214: //schema found - write it to the stream
215: if (schema != null) {
216: response.setStatus(HttpStatus.SC_OK);
217: response.setContentType("text/xml");
218: schema.write(response.getOutputStream());
219: return;
220: } else {
221: InputStream instream = service.getClassLoader()
222: .getResourceAsStream(
223: DeploymentConstants.META_INF
224: + "/" + schemaName);
225:
226: if (instream != null) {
227: response.setStatus(HttpStatus.SC_OK);
228: response.setContentType("text/xml");
229: OutputStream outstream = response
230: .getOutputStream();
231: boolean checkLength = true;
232: int length = Integer.MAX_VALUE;
233: int nextValue = instream.read();
234: if (checkLength)
235: length--;
236: while (-1 != nextValue && length >= 0) {
237: outstream.write(nextValue);
238: nextValue = instream.read();
239: if (checkLength)
240: length--;
241: }
242: outstream.flush();
243: return;
244: } else {
245: // no schema available by that name - send 404
246: response.sendError(HttpStatus.SC_NOT_FOUND,
247: "Schema Not Found!");
248: return;
249: }
250: }
251: }
252: }
253: if (uri.indexOf("?wsdl2=") > 0) {
254: String serviceName = uri.substring(
255: uri.lastIndexOf("/") + 1, uri
256: .lastIndexOf("?wsdl2="));
257: if (processInternalWSDL(uri, configurationContext,
258: serviceName, response))
259: return;
260: }
261: if (uri.indexOf("?wsdl=") > 0) {
262: String serviceName = uri.substring(
263: uri.lastIndexOf("/") + 1, uri
264: .lastIndexOf("?wsdl="));
265: if (processInternalWSDL(uri, configurationContext,
266: serviceName, response))
267: return;
268: }
269:
270: String contentType = null;
271: Header[] headers = request
272: .getHeaders(HTTPConstants.HEADER_CONTENT_TYPE);
273: if (headers != null && headers.length > 0) {
274: contentType = headers[0].getValue();
275: int index = contentType.indexOf(';');
276: if (index > 0) {
277: contentType = contentType.substring(0, index);
278: }
279: }
280:
281: // deal with GET request
282: pi = RESTUtil.processURLRequest(msgContext, response
283: .getOutputStream(), contentType);
284:
285: } else if (method.equals(HTTPConstants.HEADER_POST)) {
286: // deal with POST request
287:
288: String contentType = request.getContentType();
289:
290: if (HTTPTransportUtils.isRESTRequest(contentType)) {
291: pi = RESTUtil.processXMLRequest(msgContext, request
292: .getInputStream(), response.getOutputStream(),
293: contentType);
294: } else {
295: String ip = (String) msgContext
296: .getProperty(MessageContext.TRANSPORT_ADDR);
297: if (ip != null) {
298: uri = ip + uri;
299: }
300: pi = HTTPTransportUtils.processHTTPPostRequest(
301: msgContext, request.getInputStream(), response
302: .getOutputStream(), contentType,
303: soapAction, uri);
304: }
305:
306: } else if (method.equals(HTTPConstants.HEADER_PUT)) {
307:
308: String contentType = request.getContentType();
309: msgContext.setProperty(
310: Constants.Configuration.CONTENT_TYPE, contentType);
311:
312: pi = RESTUtil.processXMLRequest(msgContext, request
313: .getInputStream(), response.getOutputStream(),
314: contentType);
315:
316: } else if (method.equals(HTTPConstants.HEADER_DELETE)) {
317:
318: pi = RESTUtil.processURLRequest(msgContext, response
319: .getOutputStream(), null);
320:
321: } else {
322: throw new MethodNotSupportedException(method
323: + " method not supported");
324: }
325:
326: Boolean holdResponse = (Boolean) msgContext
327: .getProperty(RequestResponseTransport.HOLD_RESPONSE);
328: if (pi.equals(InvocationResponse.SUSPEND)
329: || (holdResponse != null && Boolean.TRUE
330: .equals(holdResponse))) {
331: try {
332: ((RequestResponseTransport) msgContext
333: .getProperty(RequestResponseTransport.TRANSPORT_CONTROL))
334: .awaitResponse();
335: } catch (InterruptedException e) {
336: throw new IOException(
337: "We were interrupted, so this may not function correctly:"
338: + e.getMessage());
339: }
340: }
341:
342: // Finalize response
343: OperationContext operationContext = msgContext
344: .getOperationContext();
345: Object isTwoChannel = null;
346: if (operationContext != null) {
347: isTwoChannel = operationContext
348: .getProperty(Constants.DIFFERENT_EPR);
349: }
350:
351: if (TransportUtils.isResponseWritten(msgContext)) {
352: if ((isTwoChannel != null)
353: && Constants.VALUE_TRUE.equals(isTwoChannel)) {
354: response.setStatus(HttpStatus.SC_ACCEPTED);
355: }
356: } else {
357: response.setStatus(HttpStatus.SC_ACCEPTED);
358: }
359: }
360:
361: private boolean processInternalWSDL(String uri,
362: ConfigurationContext configurationContext,
363: String serviceName, AxisHttpResponse response)
364: throws IOException {
365: String wsdlName = uri.substring(uri.lastIndexOf("=") + 1);
366:
367: HashMap services = configurationContext.getAxisConfiguration()
368: .getServices();
369: AxisService service = (AxisService) services.get(serviceName);
370:
371: if (service != null) {
372: response.setStatus(HttpStatus.SC_OK);
373: response.setContentType("text/xml");
374: service.printUserWSDL(response.getOutputStream(), wsdlName);
375: response.getOutputStream().flush();
376: return true;
377:
378: } else {
379: // no schema available by that name - send 404
380: response.sendError(HttpStatus.SC_NOT_FOUND,
381: "Schema Not Found!");
382: return true;
383: }
384:
385: }
386:
387: public String getHost(AxisHttpRequest request)
388: throws java.net.SocketException {
389: String host = null;
390: Header hostHeader = request.getFirstHeader("host");
391: if (hostHeader != null) {
392: String parts[] = hostHeader.getValue().split("[:]");
393: if (parts.length > 0) {
394: host = parts[0].trim();
395: }
396: }
397: return host;
398: }
399:
400: }
|