Magnolia CMS Proxy Servlet

Need to proxy something using Magnolia? VirtualURIMapping won’t help you if you need to proxy something on a different server..
Quick solution: servlet!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.tinext.aa.core.servlet;
 
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URLDecoder;
import java.util.Enumeration;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class ProxyServlet extends HttpServlet {
 
	private static final Logger log = LoggerFactory.getLogger(ProxyServlet.class);
 
	@Override
	public void doGet(final HttpServletRequest request, final HttpServletResponse response) {
		doPost(request, response);
	}
 
	@Override
	public void doPost(final HttpServletRequest request, final HttpServletResponse response) {
 
		String originalUrlString = request.getRequestURL().toString();
		log.info("Original Url: > {}", originalUrlString);
 
		String urlString = getInitParameter("url");
		String queryString = request.getQueryString();
 
		urlString += queryString == null ? "" : "?" + queryString;
		log.info("Fetching > {}", urlString);
 
		try {
			proxyCall(urlString, request, response);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
	private void proxyCall(String url, final HttpServletRequest request, final HttpServletResponse response) throws IOException {
 
		// URL needs to be url decoded
		url = URLDecoder.decode(url, "utf-8");
 
		OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
		HttpClient client = new HttpClient();
		try {
 
			HttpMethod method = null;
 
			// Split this according to the type of request
			if (request.getMethod().equals("GET")) {
 
				method = new GetMethod(url);
 
			} else if (request.getMethod().equals("POST")) {
 
				method = new PostMethod(url);
 
				// Set any eventual parameters that came with our original
				// request (POST params, for instance)
				Enumeration paramNames = request.getParameterNames();
				while (paramNames.hasMoreElements()) {
 
					String paramName = paramNames.nextElement();
					((PostMethod) method).setParameter(paramName, request.getParameter(paramName));
				}
 
			} else {
				throw new NotImplementedException("This proxy only supports GET and POST methods.");
			}
 
			// Execute the method
			client.executeMethod(method);
 
			// Set the content type, as it comes from the server
			Header[] headers = method.getResponseHeaders();
			for (Header header : headers) {
				if ("Content-Type".equalsIgnoreCase(header.getName())) {
					response.setContentType(header.getValue());
				}
			}
 
			// Write the body, flush and close
			writer.write(method.getResponseBodyAsString());
			writer.flush();
			writer.close();
 
		} catch (HttpException e) {
			// log.error("Oops, something went wrong in the HTTP proxy", null, e);
			writer.write(e.toString());
			throw e;
		} catch (IOException e) {
			e.printStackTrace();
			writer.write(e.toString());
			throw e;
		}
	}
}

Now configure the servlet:

proxy servlet

And the game is done.
Thanks to Pedro Assuncao blog post.

Latest articles

Written by:

One Comment

  1. Grégory Joseph
    11/19/2012
    Reply

    Consider security when exposing this! As it is, this servlet would allow any user to force your server to download any arbitrary content available on the web ! (as well as potentially expose resources that aren’t meant to be exposed, i.e internal servers).
    The plus-side with this solution is that the content can be cached in Magnolia though 🙂
    One thing I’ve been considering is to have “proxyable” URLs in the data module for example.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


5 + sei =