1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20
21 package org.apache.axis2.transport.http;
22
23 import org.apache.axiom.om.OMElement;
24 import org.apache.axiom.om.OMException;
25 import org.apache.axiom.om.OMNamespace;
26 import org.apache.axiom.soap.SOAP11Constants;
27 import org.apache.axiom.soap.SOAP12Constants;
28 import org.apache.axiom.soap.SOAPEnvelope;
29 import org.apache.axiom.soap.SOAPFactory;
30 import org.apache.axiom.soap.SOAPProcessingException;
31 import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
32 import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
33 import org.apache.axis2.AxisFault;
34 import org.apache.axis2.Constants;
35 import org.apache.axis2.addressing.EndpointReference;
36 import org.apache.axis2.builder.BuilderUtil;
37 import org.apache.axis2.context.ConfigurationContext;
38 import org.apache.axis2.context.MessageContext;
39 import org.apache.axis2.context.OperationContext;
40 import org.apache.axis2.description.AxisService;
41 import org.apache.axis2.description.Parameter;
42 import org.apache.axis2.engine.AxisEngine;
43 import org.apache.axis2.engine.Handler.InvocationResponse;
44 import org.apache.axis2.transport.TransportUtils;
45 import org.apache.axis2.util.JavaUtils;
46 import org.apache.axis2.util.Utils;
47
48 import javax.xml.parsers.FactoryConfigurationError;
49 import javax.xml.stream.XMLStreamException;
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.io.OutputStream;
53 import java.util.Iterator;
54 import java.util.Map;
55 import java.util.zip.GZIPInputStream;
56
57 public class HTTPTransportUtils {
58
59
60 /**
61 * @deprecated This was used only by the now deprecated processHTTPGetRequest() method.
62 */
63 public static SOAPEnvelope createEnvelopeFromGetRequest(String requestUrl,
64 Map map, ConfigurationContext configCtx)
65 throws AxisFault {
66 String[] values =
67 Utils.parseRequestURLForServiceAndOperation(requestUrl,
68 configCtx.getServiceContextPath());
69 if (values == null) {
70 return new SOAP11Factory().getDefaultEnvelope();
71 }
72
73 if ((values[1] != null) && (values[0] != null)) {
74 String srvice = values[0];
75 AxisService service = configCtx.getAxisConfiguration().getService(srvice);
76 if (service == null) {
77 throw new AxisFault("service not found: " + srvice);
78 }
79 String operation = values[1];
80 SOAPFactory soapFactory = new SOAP11Factory();
81 SOAPEnvelope envelope = soapFactory.getDefaultEnvelope();
82 OMNamespace omNs = soapFactory.createOMNamespace(service.getSchemaTargetNamespace(),
83 service.getSchemaTargetNamespacePrefix());
84 soapFactory.createOMNamespace(service.getSchemaTargetNamespace(),
85 service.getSchemaTargetNamespacePrefix());
86 OMElement opElement = soapFactory.createOMElement(operation, omNs);
87 Iterator it = map.keySet().iterator();
88
89 while (it.hasNext()) {
90 String name = (String) it.next();
91 String value = (String) map.get(name);
92 OMElement omEle = soapFactory.createOMElement(name, omNs);
93
94 omEle.setText(value);
95 opElement.addChild(omEle);
96 }
97
98 envelope.getBody().addChild(opElement);
99
100 return envelope;
101 } else {
102 return null;
103 }
104 }
105
106 /**
107 * @param msgContext - The MessageContext of the Request Message
108 * @param out - The output stream of the response
109 * @param soapAction - SoapAction of the request
110 * @param requestURI - The URL that the request came to
111 * @param configurationContext - The Axis Configuration Context
112 * @param requestParameters - The parameters of the request message
113 * @return - boolean indication whether the operation was succesfull
114 * @throws AxisFault - Thrown in case a fault occurs
115 * @deprecated use RESTUtil.processURLRequest(MessageContext msgContext, OutputStream out, String contentType) instead
116 */
117
118 public static boolean processHTTPGetRequest(MessageContext msgContext,
119 OutputStream out, String soapAction,
120 String requestURI,
121 ConfigurationContext configurationContext,
122 Map requestParameters)
123 throws AxisFault {
124 if ((soapAction != null) && soapAction.startsWith("\"") && soapAction.endsWith("\"")) {
125 soapAction = soapAction.substring(1, soapAction.length() - 1);
126 }
127
128 msgContext.setSoapAction(soapAction);
129 msgContext.setTo(new EndpointReference(requestURI));
130 msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
131 msgContext.setServerSide(true);
132 SOAPEnvelope envelope = HTTPTransportUtils.createEnvelopeFromGetRequest(requestURI,
133 requestParameters,
134 configurationContext);
135
136 if (envelope == null) {
137 return false;
138 } else {
139 msgContext.setDoingREST(true);
140 msgContext.setEnvelope(envelope);
141 AxisEngine.receive(msgContext);
142 return true;
143 }
144 }
145
146 private static final int VERSION_UNKNOWN = 0;
147 private static final int VERSION_SOAP11 = 1;
148 private static final int VERSION_SOAP12 = 2;
149
150 public static InvocationResponse processHTTPPostRequest(MessageContext msgContext,
151 InputStream in,
152 OutputStream out,
153 String contentType,
154 String soapActionHeader,
155 String requestURI)
156 throws AxisFault {
157 int soapVersion = VERSION_UNKNOWN;
158 try {
159 soapVersion = initializeMessageContext(msgContext, soapActionHeader, requestURI, contentType);
160 msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
161
162 msgContext.setEnvelope(
163 TransportUtils.createSOAPMessage(
164 msgContext,
165 handleGZip(msgContext, in),
166 contentType));
167 return AxisEngine.receive(msgContext);
168 } catch (SOAPProcessingException e) {
169 throw AxisFault.makeFault(e);
170 } catch (AxisFault e) {
171 throw e;
172 } catch (IOException e) {
173 throw AxisFault.makeFault(e);
174 } catch (OMException e) {
175 throw AxisFault.makeFault(e);
176 } catch (XMLStreamException e) {
177 throw AxisFault.makeFault(e);
178 } catch (FactoryConfigurationError e) {
179 throw AxisFault.makeFault(e);
180 } finally {
181 if ((msgContext.getEnvelope() == null) && soapVersion != VERSION_SOAP11) {
182 msgContext.setEnvelope(new SOAP12Factory().getDefaultEnvelope());
183 }
184 }
185 }
186
187 public static int initializeMessageContext(MessageContext msgContext,
188 String soapActionHeader,
189 String requestURI,
190 String contentType) {
191 int soapVersion = VERSION_UNKNOWN;
192 // remove the starting and trailing " from the SOAP Action
193 if ((soapActionHeader != null)
194 && soapActionHeader.length() > 0
195 && soapActionHeader.charAt(0) == '\"'
196 && soapActionHeader.endsWith("\"")) {
197 soapActionHeader = soapActionHeader.substring(1, soapActionHeader.length() - 1);
198 }
199
200 // fill up the Message Contexts
201 msgContext.setSoapAction(soapActionHeader);
202 msgContext.setTo(new EndpointReference(requestURI));
203 msgContext.setServerSide(true);
204
205 // get the type of char encoding
206 String charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
207 if (charSetEnc == null) {
208 charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
209 }
210 msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEnc);
211
212 if (contentType != null) {
213 if (contentType.indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1) {
214 soapVersion = VERSION_SOAP12;
215 TransportUtils.processContentTypeForAction(contentType, msgContext);
216 } else if (contentType
217 .indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1) {
218 soapVersion = VERSION_SOAP11;
219 } else if (isRESTRequest(contentType)) {
220 // If REST, construct a SOAP11 envelope to hold the rest message and
221 // indicate that this is a REST message.
222 soapVersion = VERSION_SOAP11;
223 msgContext.setDoingREST(true);
224 }
225 if (soapVersion == VERSION_SOAP11) {
226 // TODO Keith : Do we need this anymore
227 // Deployment configuration parameter
228 Parameter enableREST = msgContext
229 .getParameter(Constants.Configuration.ENABLE_REST);
230 if ((soapActionHeader == null) && (enableREST != null)) {
231 if (Constants.VALUE_TRUE.equals(enableREST.getValue())) {
232 // If the content Type is text/xml (BTW which is the
233 // SOAP 1.1 Content type ) and the SOAP Action is
234 // absent it is rest !!
235 msgContext.setDoingREST(true);
236 }
237 }
238 }
239 }
240 return soapVersion;
241 }
242
243 public static InputStream handleGZip(MessageContext msgContext, InputStream in)
244 throws IOException {
245 Map headers = (Map) msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
246
247 if (headers != null) {
248 if (HTTPConstants.COMPRESSION_GZIP
249 .equals(headers.get(HTTPConstants.HEADER_CONTENT_ENCODING)) ||
250 HTTPConstants.COMPRESSION_GZIP.equals(headers.get(
251 HTTPConstants.HEADER_CONTENT_ENCODING_LOWERCASE))) {
252 in = new GZIPInputStream(in);
253 }
254 }
255 return in;
256 }
257
258 /**
259 * This will match for content types that will be regarded as REST in WSDL2.0.
260 * This contains,
261 * 1. application/xml
262 * 2. application/x-www-form-urlencoded
263 * 3. multipart/form-data
264 * <p/>
265 * If the request doesnot contain a content type; this will return true.
266 *
267 * @param contentType content type to check
268 * @return Boolean
269 */
270 public static boolean isRESTRequest(String contentType) {
271 return contentType != null &&
272 (contentType.indexOf(HTTPConstants.MEDIA_TYPE_APPLICATION_XML) > -1 ||
273 contentType.indexOf(HTTPConstants.MEDIA_TYPE_X_WWW_FORM) > -1 ||
274 contentType.indexOf(HTTPConstants.MEDIA_TYPE_MULTIPART_FORM_DATA) > -1);
275 }
276 }