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