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.AbstractMessageAwareTransformer;
19 import org.mule.transport.NullPayload;
20 import org.mule.transport.http.HttpConnector;
21 import org.mule.transport.http.HttpConstants;
22 import org.mule.transport.http.HttpResponse;
23 import org.mule.util.StringUtils;
24
25 import java.io.IOException;
26 import java.text.SimpleDateFormat;
27 import java.util.Collection;
28 import java.util.Date;
29 import java.util.Iterator;
30 import java.util.Locale;
31 import java.util.Map;
32
33 import org.apache.commons.httpclient.Header;
34 import org.apache.commons.httpclient.HttpVersion;
35
36
37
38
39
40
41 public class MuleMessageToHttpResponse extends AbstractMessageAwareTransformer
42 {
43 public static final String CUSTOM_HEADER_PREFIX = "";
44
45
46 private SimpleDateFormat format;
47 private String server;
48
49 public MuleMessageToHttpResponse()
50 {
51 registerSourceType(Object.class);
52 setReturnClass(HttpResponse.class);
53 }
54
55
56
57 public void initialise() throws InitialisationException
58 {
59 format = new SimpleDateFormat(HttpConstants.DATE_FORMAT, Locale.US);
60
61
62
63 if (MuleManifest.getProductName() == null)
64 {
65 server = "Mule/SNAPSHOT";
66 }
67 else
68 {
69 server = MuleManifest.getProductName() + "/"
70 + MuleManifest.getProductVersion();
71 }
72 }
73
74 public Object transform(MuleMessage msg, String outputEncoding) throws TransformerException
75 {
76 Object src = msg.getPayload();
77
78 if (msg.getExceptionPayload() != null)
79 {
80
81 }
82
83
84
85
86 if (src instanceof NullPayload)
87 {
88 src = StringUtils.EMPTY;
89 }
90
91 try
92 {
93 HttpResponse response;
94 if (src instanceof HttpResponse)
95 {
96 response = (HttpResponse)src;
97 }
98 else
99 {
100 response = createResponse(src, outputEncoding, msg);
101 }
102
103
104 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_TYPE))
105 {
106 response.addHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE,
107 HttpConstants.DEFAULT_CONTENT_TYPE));
108 }
109
110
111 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_LENGTH)
112 && !response.containsHeader(HttpConstants.HEADER_TRANSFER_ENCODING))
113 {
114 if (response.hasBody())
115 {
116 long len = response.getContentLength();
117 if (len < 0)
118 {
119 if (response.getHttpVersion().lessEquals(HttpVersion.HTTP_1_0))
120 {
121 throw new IOException("Chunked encoding not supported for HTTP version "
122 + response.getHttpVersion());
123 }
124 Header header = new Header(HttpConstants.HEADER_TRANSFER_ENCODING, "chunked");
125 response.addHeader(header);
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 if (!response.containsHeader(HttpConstants.HEADER_CONNECTION))
141 {
142
143 String connHeader = msg.getStringProperty(HttpConstants.HEADER_CONNECTION, null);
144 if (connHeader != null)
145 {
146 if (connHeader.equalsIgnoreCase("keep-alive"))
147 {
148 Header header = new Header(HttpConstants.HEADER_CONNECTION, "keep-alive");
149 response.addHeader(header);
150 response.setKeepAlive(true);
151 }
152 if (connHeader.equalsIgnoreCase("close"))
153 {
154 Header header = new Header(HttpConstants.HEADER_CONNECTION, "close");
155 response.addHeader(header);
156 response.setKeepAlive(false);
157 }
158 }
159 else
160 {
161
162 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1))
163 {
164 response.setKeepAlive(true);
165 }
166 else
167 {
168 response.setKeepAlive(false);
169 }
170 }
171 }
172 if ("HEAD".equalsIgnoreCase(msg.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, null)))
173 {
174
175 response.setBody((MuleMessage) null);
176 }
177 return response;
178 }
179 catch (IOException e)
180 {
181 throw new TransformerException(this, e);
182 }
183
184 }
185
186 protected HttpResponse createResponse(Object src, String encoding, MuleMessage msg)
187 throws IOException, TransformerException
188 {
189 HttpResponse response = new HttpResponse();
190
191 int status = msg.getIntProperty(HttpConnector.HTTP_STATUS_PROPERTY, HttpConstants.SC_OK);
192 String version = msg.getStringProperty(HttpConnector.HTTP_VERSION_PROPERTY, HttpConstants.HTTP11);
193 String etag = msg.getStringProperty(HttpConstants.HEADER_ETAG, null);
194
195 String date;
196 synchronized (format)
197 {
198 date = format.format(new Date());
199 }
200
201 String contentType = msg.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE,
202 HttpConstants.DEFAULT_CONTENT_TYPE);
203
204 response.setStatusLine(HttpVersion.parse(version), status);
205 response.setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, contentType));
206 response.setHeader(new Header(HttpConstants.HEADER_DATE, date));
207 response.setHeader(new Header(HttpConstants.HEADER_SERVER, server));
208 if (msg.getProperty(HttpConstants.HEADER_EXPIRES) == null)
209 {
210 response.setHeader(new Header(HttpConstants.HEADER_EXPIRES, date));
211 }
212 if (etag != null)
213 {
214 response.setHeader(new Header(HttpConstants.HEADER_ETAG, etag));
215 }
216 response.setFallbackCharset(encoding);
217
218 Collection headerNames = HttpConstants.RESPONSE_HEADER_NAMES.values();
219 String headerName, value;
220 for (Iterator iterator = headerNames.iterator(); iterator.hasNext();)
221 {
222 headerName = (String)iterator.next();
223 value = msg.getStringProperty(headerName, null);
224 if (value != null)
225 {
226 response.setHeader(new Header(headerName, value));
227 }
228 }
229
230
231 Map customHeaders = (Map)msg.getProperty(HttpConnector.HTTP_CUSTOM_HEADERS_MAP_PROPERTY);
232 if (customHeaders != null)
233 {
234 Map.Entry entry;
235 for (Iterator iterator = customHeaders.entrySet().iterator(); iterator.hasNext();)
236 {
237 entry = (Map.Entry)iterator.next();
238 if (entry.getValue() != null)
239 {
240 response.setHeader(new Header(entry.getKey().toString(), entry.getValue().toString()));
241 }
242 }
243 }
244
245
246 String user = msg.getStringProperty(MuleProperties.MULE_USER_PROPERTY, null);
247 if (user != null)
248 {
249 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_USER_PROPERTY, user));
250 }
251 if (msg.getCorrelationId() != null)
252 {
253 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_CORRELATION_ID_PROPERTY,
254 msg.getCorrelationId()));
255 response.setHeader(new Header(CUSTOM_HEADER_PREFIX
256 + MuleProperties.MULE_CORRELATION_GROUP_SIZE_PROPERTY,
257 String.valueOf(msg.getCorrelationGroupSize())));
258 response.setHeader(new Header(CUSTOM_HEADER_PREFIX
259 + MuleProperties.MULE_CORRELATION_SEQUENCE_PROPERTY,
260 String.valueOf(msg.getCorrelationSequence())));
261 }
262 if (msg.getReplyTo() != null)
263 {
264 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_REPLY_TO_PROPERTY,
265 msg.getReplyTo().toString()));
266 }
267
268 response.setBody(msg);
269
270 return response;
271 }
272
273 public boolean isAcceptNull()
274 {
275 return true;
276 }
277 }