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:
And the game is done.
Thanks to Pedro Assuncao blog post.
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.