package glaze.client.wire.tasks; import glaze.util.RequestUtil; import java.io.IOException; import java.io.Serializable; import java.net.URI; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParamsNames; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.ListMultimap; /** * Convenience class for HttpRequest serialization. * */ public class SerializableRequest implements Serializable { private static final Logger LOGGER = LoggerFactory.getLogger(SerializableRequest.class); private static final long serialVersionUID = 8168045456490905320L; public static SerializableRequest from(HttpRequestBase request) { return new SerializableRequest(request); } public static SerializableRequest from(HttpUriRequest req) { return from((HttpRequestBase) req); } private String method; private ListMultimap<String, String> headers; private Map<String, Object> params; private URI uri; private byte[] entityData; private String entityContentType; private String entityEncoding; public SerializableRequest(HttpRequestBase request) { this.uri = request.getURI(); this.method = request.getRequestLine().getMethod(); copyHeaders(request); copyParams(request); copyEntityData(request); } public boolean hasData() { return entityData != null; } public HttpRequestBase materialize() { HttpRequestBase req = extractRequest(); req.setURI(uri); addHeaders(req); addParams(req); return req; } private void addHeaders(HttpRequestBase req) { for (Map.Entry<String, String> entry : headers.entries()) { req.addHeader(entry.getKey(), entry.getValue()); } } private void addParams(HttpRequestBase req) { for (Map.Entry<String, Object> entry : params.entrySet()) { req.getParams().setParameter(entry.getKey(), entry.getValue()); } } private void copyEntity(HttpEntity entity) throws IOException { this.entityData = EntityUtils.toByteArray(entity); Header contentType = entity.getContentType(); if (contentType != null) { this.entityContentType = contentType.getValue(); } Header contentEncoding = entity.getContentEncoding(); if (contentEncoding != null) { this.entityEncoding = contentEncoding.getValue(); } } private void copyEntityData(HttpRequestBase request) { // TODO handle multipart try { HttpEntity entity = RequestUtil.getEntity(request); if (entity != null) { copyEntity(entity); } } catch (IOException e) { LOGGER.error(e.getMessage(), e); } } private void copyHeaders(HttpRequestBase request) { this.headers = LinkedListMultimap.create(); Header[] allHeaders = request.getAllHeaders(); for (Header h : allHeaders) { this.headers.put(h.getName(), h.getValue()); } } private void copyParams(HttpRequestBase request) { this.params = new HashMap<String, Object>(); HttpParams rp = request.getParams(); HttpParamsNames names = (HttpParamsNames) rp; for (String name : names.getNames()) { params.put(name, rp.getParameter(name)); } } private HttpRequestBase extractEntityEnclosingRequest() { HttpRequestBase req; req = new HttpEntityEnclosingRequestBase() { @Override public String getMethod() { return method; } }; ByteArrayEntity entity = new ByteArrayEntity(entityData); if (entityEncoding != null) { entity.setContentEncoding(entityEncoding); } if (entityContentType != null) { entity.setContentType(entityContentType); } ((HttpEntityEnclosingRequest) req).setEntity(entity); return req; } private HttpRequestBase extractRequest() { HttpRequestBase req; if (hasData()) { req = extractEntityEnclosingRequest(); } else { req = new HttpRequestBase() { @Override public String getMethod() { return method; } }; } return req; } }