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