1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.http.transformers;
12
13 import org.mule.api.MuleMessage;
14 import org.mule.api.config.MuleProperties;
15 import org.mule.api.lifecycle.InitialisationException;
16 import org.mule.api.transformer.TransformerException;
17 import org.mule.config.MuleManifest;
18 import org.mule.transformer.AbstractMessageTransformer;
19 import org.mule.transformer.types.DataTypeFactory;
20 import org.mule.transport.NullPayload;
21 import org.mule.transport.http.CookieHelper;
22 import org.mule.transport.http.HttpConnector;
23 import org.mule.transport.http.HttpConstants;
24 import org.mule.transport.http.HttpResponse;
25 import org.mule.transport.http.i18n.HttpMessages;
26 import org.mule.util.StringUtils;
27
28 import java.io.IOException;
29 import java.text.SimpleDateFormat;
30 import java.util.Collection;
31 import java.util.Date;
32 import java.util.Locale;
33 import java.util.Map;
34
35 import org.apache.commons.httpclient.Cookie;
36 import org.apache.commons.httpclient.Header;
37 import org.apache.commons.httpclient.HttpVersion;
38
39
40
41
42 public class MuleMessageToHttpResponse extends AbstractMessageTransformer
43 {
44
45 private String server;
46
47 public MuleMessageToHttpResponse()
48 {
49 registerSourceType(DataTypeFactory.OBJECT);
50 setReturnDataType(DataTypeFactory.create(HttpResponse.class));
51 }
52
53 @Override
54 public void initialise() throws InitialisationException
55 {
56
57
58 if (MuleManifest.getProductName() == null)
59 {
60 server = "Mule/SNAPSHOT";
61 }
62 else
63 {
64 server = MuleManifest.getProductName() + "/" + MuleManifest.getProductVersion();
65 }
66 }
67
68 @Override
69 public Object transformMessage(MuleMessage msg, String outputEncoding) throws TransformerException
70 {
71 Object src = msg.getPayload();
72
73
74
75
76 if (src instanceof NullPayload)
77 {
78 src = StringUtils.EMPTY;
79 }
80
81 try
82 {
83 HttpResponse response;
84 if (src instanceof HttpResponse)
85 {
86 response = (HttpResponse) src;
87 }
88 else
89 {
90 response = createResponse(src, outputEncoding, msg);
91 }
92
93
94 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_TYPE))
95 {
96 response.addHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE,
97 HttpConstants.DEFAULT_CONTENT_TYPE));
98 }
99
100
101 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_LENGTH)
102 && !response.containsHeader(HttpConstants.HEADER_TRANSFER_ENCODING))
103 {
104 if (response.hasBody())
105 {
106 long len = response.getContentLength();
107 if (len < 0)
108 {
109 if (response.getHttpVersion().lessEquals(HttpVersion.HTTP_1_0))
110 {
111
112
113 len = msg.getPayloadAsBytes().length;
114
115 response.setBody(msg);
116
117 Header header = new Header(HttpConstants.HEADER_CONTENT_LENGTH, Long.toString(len));
118 response.setHeader(header);
119 }
120 else
121 {
122 Header header = new Header(HttpConstants.HEADER_TRANSFER_ENCODING, "chunked");
123 response.addHeader(header);
124 }
125 }
126 else
127 {
128 Header header = new Header(HttpConstants.HEADER_CONTENT_LENGTH, Long.toString(len));
129 response.setHeader(header);
130 }
131 }
132 else
133 {
134 Header header = new Header(HttpConstants.HEADER_CONTENT_LENGTH, "0");
135 response.addHeader(header);
136 }
137 }
138
139
140 String connHeader = msg.getOutboundProperty(HttpConstants.HEADER_CONNECTION);
141 if (connHeader != null)
142 {
143 if (connHeader.equalsIgnoreCase("keep-alive"))
144 {
145 response.setKeepAlive(true);
146 }
147 if (connHeader.equalsIgnoreCase("close"))
148 {
149 response.setKeepAlive(false);
150 }
151 }
152
153 final String method = msg.getOutboundProperty(HttpConnector.HTTP_METHOD_PROPERTY);
154 if ("HEAD".equalsIgnoreCase(method))
155 {
156
157 response.setBody((MuleMessage) null);
158 }
159 return response;
160 }
161 catch (Exception e)
162 {
163 throw new TransformerException(this, e);
164 }
165
166 }
167
168 protected HttpResponse createResponse(Object src, String encoding, MuleMessage msg)
169 throws IOException, TransformerException
170 {
171 HttpResponse response = new HttpResponse();
172
173 Object tmp = msg.getOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY);
174 int status = HttpConstants.SC_OK;
175
176 if (tmp != null)
177 {
178 status = Integer.valueOf(tmp.toString());
179 }
180 else if (msg.getExceptionPayload() != null)
181 {
182 status = HttpConstants.SC_INTERNAL_SERVER_ERROR;
183 }
184
185 String version = msg.getInboundProperty(HttpConnector.HTTP_VERSION_PROPERTY);
186 if (version == null)
187 {
188 version = HttpConstants.HTTP11;
189 }
190 String date = new SimpleDateFormat(HttpConstants.DATE_FORMAT, Locale.US).format(new Date());
191
192 String contentType = msg.getInboundProperty(HttpConstants.HEADER_CONTENT_TYPE);
193 if (contentType == null)
194 {
195 contentType = msg.getInvocationProperty(HttpConstants.HEADER_CONTENT_TYPE);
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 response.setStatusLine(HttpVersion.parse(version), status);
212 if (contentType != null)
213 {
214 response.setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, contentType));
215 }
216 response.setHeader(new Header(HttpConstants.HEADER_DATE, date));
217 response.setHeader(new Header(HttpConstants.HEADER_SERVER, server));
218 if (msg.getOutboundProperty(HttpConstants.HEADER_EXPIRES) == null)
219 {
220 response.setHeader(new Header(HttpConstants.HEADER_EXPIRES, date));
221 }
222
223 String etag = msg.getOutboundProperty(HttpConstants.HEADER_ETAG);
224 if (etag != null)
225 {
226 response.setHeader(new Header(HttpConstants.HEADER_ETAG, etag));
227 }
228 response.setFallbackCharset(encoding);
229
230 Collection<String> headerNames = HttpConstants.RESPONSE_HEADER_NAMES.values();
231
232 for (String headerName : headerNames)
233 {
234 if (HttpConstants.HEADER_COOKIE_SET.equals(headerName))
235 {
236
237
238 Object cookiesObject = msg.getInvocationProperty(headerName);
239 if (cookiesObject == null)
240 {
241 cookiesObject = msg.getOutboundProperty(headerName);
242 }
243 if (cookiesObject == null)
244 {
245 cookiesObject = msg.getInboundProperty(headerName);
246 }
247 if (cookiesObject == null)
248 {
249 continue;
250 }
251
252 if (!(cookiesObject instanceof Cookie[]))
253 {
254 response.addHeader(new Header(headerName, cookiesObject.toString()));
255 }
256 else
257 {
258 Cookie[] arrayOfCookies = CookieHelper.asArrayOfCookies(cookiesObject);
259 for (Cookie cookie : arrayOfCookies)
260 {
261 response.addHeader(new Header(headerName,
262 CookieHelper.formatCookieForASetCookieHeader(cookie)));
263 }
264 }
265 }
266 else
267 {
268 String value = msg.getInvocationProperty(headerName);
269 if (value == null)
270 {
271 value = msg.getOutboundProperty(headerName);
272 }
273 if (value != null)
274 {
275 response.setHeader(new Header(headerName, value));
276 }
277 }
278 }
279
280 Map customHeaders = msg.getOutboundProperty(HttpConnector.HTTP_CUSTOM_HEADERS_MAP_PROPERTY);
281 if (customHeaders != null)
282 {
283 throw new TransformerException(HttpMessages.customHeaderMapDeprecated(), this);
284 }
285
286
287 for (String headerName : msg.getOutboundPropertyNames())
288 {
289 Object v = msg.getOutboundProperty(headerName);
290 if (v != null)
291 {
292 if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX))
293 {
294 headerName = HttpConstants.CUSTOM_HEADER_PREFIX + headerName;
295 }
296 response.setHeader(new Header(headerName, v.toString()));
297 }
298 }
299
300 if (msg.getCorrelationId() != null)
301 {
302 response.setHeader(new Header(HttpConstants.CUSTOM_HEADER_PREFIX + MuleProperties.MULE_CORRELATION_ID_PROPERTY,
303 msg.getCorrelationId()));
304 response.setHeader(new Header(HttpConstants.CUSTOM_HEADER_PREFIX
305 + MuleProperties.MULE_CORRELATION_GROUP_SIZE_PROPERTY,
306 String.valueOf(msg.getCorrelationGroupSize())));
307 response.setHeader(new Header(HttpConstants.CUSTOM_HEADER_PREFIX
308 + MuleProperties.MULE_CORRELATION_SEQUENCE_PROPERTY,
309 String.valueOf(msg.getCorrelationSequence())));
310 }
311 if (msg.getReplyTo() != null)
312 {
313 response.setHeader(new Header(HttpConstants.CUSTOM_HEADER_PREFIX + MuleProperties.MULE_REPLY_TO_PROPERTY,
314 msg.getReplyTo().toString()));
315 }
316
317 try
318 {
319 response.setBody(msg);
320 }
321 catch (Exception e)
322 {
323 throw new TransformerException(this, e);
324 }
325
326 return response;
327 }
328
329 @Override
330 public boolean isAcceptNull()
331 {
332 return true;
333 }
334 }