001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.http.helper;
018
019 import java.io.IOException;
020 import java.io.InputStream;
021 import java.io.ObjectInputStream;
022 import java.io.ObjectOutputStream;
023 import java.io.OutputStream;
024 import java.net.URI;
025 import javax.servlet.ServletResponse;
026 import javax.servlet.http.HttpServletRequest;
027
028 import org.apache.camel.Exchange;
029 import org.apache.camel.RuntimeCamelException;
030 import org.apache.camel.component.http.HttpConstants;
031 import org.apache.camel.component.http.HttpConverter;
032 import org.apache.camel.component.http.HttpEndpoint;
033 import org.apache.camel.component.http.HttpMethods;
034 import org.apache.camel.converter.IOConverter;
035 import org.apache.camel.converter.stream.CachedOutputStream;
036 import org.apache.camel.util.IOHelper;
037
038 public final class HttpHelper {
039
040 private HttpHelper() {
041 // Helper class
042 }
043
044 public static void setCharsetFromContentType(String contentType, Exchange exchange) {
045 if (contentType != null) {
046 // find the charset and set it to the Exchange
047 int index = contentType.indexOf("charset=");
048 if (index > 0) {
049 String charset = contentType.substring(index + 8);
050 exchange.setProperty(Exchange.CHARSET_NAME, IOConverter.normalizeCharset(charset));
051 }
052 }
053 }
054
055 /**
056 * Writes the given object as response body to the servlet response
057 * <p/>
058 * The content type will be set to {@link HttpConstants#CONTENT_TYPE_JAVA_SERIALIZED_OBJECT}
059 *
060 * @param response servlet response
061 * @param target object to write
062 * @throws IOException is thrown if error writing
063 */
064 public static void writeObjectToServletResponse(ServletResponse response, Object target) throws IOException {
065 response.setContentType(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
066 writeObjectToStream(response.getOutputStream(), target);
067 }
068
069 /**
070 * Writes the given object as response body to the output stream
071 *
072 * @param stream output stream
073 * @param target object to write
074 * @throws IOException is thrown if error writing
075 */
076 public static void writeObjectToStream(OutputStream stream, Object target) throws IOException {
077 ObjectOutputStream oos = new ObjectOutputStream(stream);
078 oos.writeObject(target);
079 oos.flush();
080 IOHelper.close(oos);
081 }
082
083 /**
084 * Deserializes the input stream to a Java object
085 *
086 * @param is input stream for the Java object
087 * @return the java object, or <tt>null</tt> if input stream was <tt>null</tt>
088 * @throws ClassNotFoundException is thrown if class not found
089 * @throws IOException can be thrown
090 */
091 public static Object deserializeJavaObjectFromStream(InputStream is) throws ClassNotFoundException, IOException {
092 if (is == null) {
093 return null;
094 }
095
096 Object answer = null;
097 ObjectInputStream ois = new ObjectInputStream(is);
098 try {
099 answer = ois.readObject();
100 } finally {
101 IOHelper.close(ois);
102 }
103
104 return answer;
105 }
106
107 /**
108 * Reads the response body from the given http servlet request.
109 *
110 * @param request http servlet request
111 * @param exchange the exchange
112 * @return the response body, can be <tt>null</tt> if no body
113 * @throws IOException is thrown if error reading response body
114 */
115 public static Object readResponseBodyFromServletRequest(HttpServletRequest request, Exchange exchange) throws IOException {
116 InputStream is = HttpConverter.toInputStream(request, exchange);
117 return readResponseBodyFromInputStream(is, exchange);
118 }
119
120 /**
121 * Reads the response body from the given input stream.
122 *
123 * @param is the input stream
124 * @param exchange the exchange
125 * @return the response body, can be <tt>null</tt> if no body
126 * @throws IOException is thrown if error reading response body
127 */
128 public static Object readResponseBodyFromInputStream(InputStream is, Exchange exchange) throws IOException {
129 if (is == null) {
130 return null;
131 }
132
133 // convert the input stream to StreamCache if the stream cache is not disabled
134 if (exchange.getProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.FALSE, Boolean.class)) {
135 return is;
136 } else {
137 CachedOutputStream cos = new CachedOutputStream(exchange);
138 IOHelper.copyAndCloseInput(is, cos);
139 return cos.getStreamCache();
140 }
141 }
142
143 /**
144 * Creates the URL to invoke.
145 *
146 * @param exchange the exchange
147 * @param endpoint the endpoint
148 * @return the URL to invoke
149 */
150 public static String createURL(Exchange exchange, HttpEndpoint endpoint) {
151 String uri = null;
152 if (!(endpoint.isBridgeEndpoint())) {
153 uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
154 }
155 if (uri == null) {
156 uri = endpoint.getHttpUri().toASCIIString();
157 }
158
159 // append HTTP_PATH to HTTP_URI if it is provided in the header
160 String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
161 if (path != null) {
162 if (path.startsWith("/")) {
163 URI baseURI;
164 String baseURIString = exchange.getIn().getHeader(Exchange.HTTP_BASE_URI, String.class);
165 try {
166 if (baseURIString == null) {
167 if (exchange.getFromEndpoint() != null) {
168 baseURIString = exchange.getFromEndpoint().getEndpointUri();
169 } else {
170 // will set a default one for it
171 baseURIString = "/";
172 }
173 }
174 baseURI = new URI(baseURIString);
175 String basePath = baseURI.getRawPath();
176 if (path.startsWith(basePath)) {
177 path = path.substring(basePath.length());
178 if (path.startsWith("/")) {
179 path = path.substring(1);
180 }
181 } else {
182 throw new RuntimeCamelException("Cannot analyze the Exchange.HTTP_PATH header, due to: cannot find the right HTTP_BASE_URI");
183 }
184 } catch (Throwable t) {
185 throw new RuntimeCamelException("Cannot analyze the Exchange.HTTP_PATH header, due to: "
186 + t.getMessage(), t);
187 }
188
189 }
190 if (path.length() > 0) {
191 // make sure that there is exactly one "/" between HTTP_URI and
192 // HTTP_PATH
193 if (!uri.endsWith("/")) {
194 uri = uri + "/";
195 }
196 uri = uri.concat(path);
197 }
198 }
199 return uri;
200 }
201
202 /**
203 * Creates the HttpMethod to use to call the remote server, often either its GET or POST.
204 *
205 * @param exchange the exchange
206 * @return the created method
207 */
208 public static HttpMethods createMethod(Exchange exchange, HttpEndpoint endpoint, boolean hasPayload) {
209 // is a query string provided in the endpoint URI or in a header (header
210 // overrules endpoint)
211 String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
212 if (queryString == null) {
213 queryString = endpoint.getHttpUri().getQuery();
214 }
215
216 // compute what method to use either GET or POST
217 HttpMethods answer;
218 HttpMethods m = exchange.getIn().getHeader(Exchange.HTTP_METHOD, HttpMethods.class);
219 if (m != null) {
220 // always use what end-user provides in a header
221 answer = m;
222 } else if (queryString != null) {
223 // if a query string is provided then use GET
224 answer = HttpMethods.GET;
225 } else {
226 // fallback to POST if we have payload, otherwise GET
227 answer = hasPayload ? HttpMethods.POST : HttpMethods.GET;
228 }
229
230 return answer;
231 }
232 }