Magnolia CMS Proxy Servlet


Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /membri/maips21/wp-content/plugins/wp-syntax/wp-syntax.php on line 380

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

Matteo Pelucco Written by:

One Comment

  1. Grégory Joseph
    November 19

    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.

Leave a Reply

Your email address will not be published. Required fields are marked *


7 × two =