1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.fcgi.server.proxy;
20
21 import java.net.URI;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24 import javax.servlet.RequestDispatcher;
25 import javax.servlet.ServletConfig;
26 import javax.servlet.ServletException;
27 import javax.servlet.http.HttpServletRequest;
28
29 import org.eclipse.jetty.client.HttpClient;
30 import org.eclipse.jetty.client.api.Request;
31 import org.eclipse.jetty.fcgi.FCGI;
32 import org.eclipse.jetty.fcgi.client.http.HttpClientTransportOverFCGI;
33 import org.eclipse.jetty.http.HttpFields;
34 import org.eclipse.jetty.http.HttpScheme;
35 import org.eclipse.jetty.proxy.AsyncProxyServlet;
36 import org.eclipse.jetty.proxy.ProxyServlet;
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 public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
64 {
65 public static final String SCRIPT_ROOT_INIT_PARAM = "scriptRoot";
66 public static final String SCRIPT_PATTERN_INIT_PARAM = "scriptPattern";
67 public static final String FASTCGI_HTTPS_INIT_PARAM = "fastCGI.HTTPS";
68
69 private static final String REMOTE_ADDR_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".remoteAddr";
70 private static final String REMOTE_PORT_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".remotePort";
71 private static final String SERVER_NAME_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".serverName";
72 private static final String SERVER_ADDR_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".serverAddr";
73 private static final String SERVER_PORT_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".serverPort";
74 private static final String SCHEME_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".scheme";
75 private static final String REQUEST_URI_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".requestURI";
76
77 private Pattern scriptPattern;
78 private boolean fcgiHTTPS;
79
80 @Override
81 public void init() throws ServletException
82 {
83 super.init();
84
85 String value = getInitParameter(SCRIPT_PATTERN_INIT_PARAM);
86 if (value == null)
87 value = "(.+?\\.php)";
88 scriptPattern = Pattern.compile(value);
89
90 fcgiHTTPS = Boolean.parseBoolean(getInitParameter(FASTCGI_HTTPS_INIT_PARAM));
91 }
92
93 @Override
94 protected HttpClient newHttpClient()
95 {
96 ServletConfig config = getServletConfig();
97 String scriptRoot = config.getInitParameter(SCRIPT_ROOT_INIT_PARAM);
98 if (scriptRoot == null)
99 throw new IllegalArgumentException("Mandatory parameter '" + SCRIPT_ROOT_INIT_PARAM + "' not configured");
100 return new HttpClient(new ProxyHttpClientTransportOverFCGI(scriptRoot), null);
101 }
102
103 @Override
104 protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request)
105 {
106 proxyRequest.attribute(REMOTE_ADDR_ATTRIBUTE, request.getRemoteAddr());
107 proxyRequest.attribute(REMOTE_PORT_ATTRIBUTE, String.valueOf(request.getRemotePort()));
108 proxyRequest.attribute(SERVER_NAME_ATTRIBUTE, request.getServerName());
109 proxyRequest.attribute(SERVER_ADDR_ATTRIBUTE, request.getLocalAddr());
110 proxyRequest.attribute(SERVER_PORT_ATTRIBUTE, String.valueOf(request.getLocalPort()));
111
112 proxyRequest.attribute(SCHEME_ATTRIBUTE, request.getScheme());
113
114
115 String originalPath = (String)request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
116 String originalQuery = (String)request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
117 if (originalPath == null)
118 {
119 originalPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
120 originalQuery = (String)request.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING);
121 }
122 if (originalPath != null)
123 {
124 String originalURI = originalPath;
125 if (originalQuery != null)
126 originalURI += "?" + originalQuery;
127 proxyRequest.attribute(REQUEST_URI_ATTRIBUTE, originalURI);
128 }
129
130 super.customizeProxyRequest(proxyRequest, request);
131 }
132
133 protected void customizeFastCGIHeaders(Request proxyRequest, HttpFields fastCGIHeaders)
134 {
135 fastCGIHeaders.put(FCGI.Headers.REMOTE_ADDR, (String)proxyRequest.getAttributes().get(REMOTE_ADDR_ATTRIBUTE));
136 fastCGIHeaders.put(FCGI.Headers.REMOTE_PORT, (String)proxyRequest.getAttributes().get(REMOTE_PORT_ATTRIBUTE));
137 fastCGIHeaders.put(FCGI.Headers.SERVER_NAME, (String)proxyRequest.getAttributes().get(SERVER_NAME_ATTRIBUTE));
138 fastCGIHeaders.put(FCGI.Headers.SERVER_ADDR, (String)proxyRequest.getAttributes().get(SERVER_ADDR_ATTRIBUTE));
139 fastCGIHeaders.put(FCGI.Headers.SERVER_PORT, (String)proxyRequest.getAttributes().get(SERVER_PORT_ATTRIBUTE));
140
141 if (fcgiHTTPS || HttpScheme.HTTPS.is((String)proxyRequest.getAttributes().get(SCHEME_ATTRIBUTE)))
142 fastCGIHeaders.put(FCGI.Headers.HTTPS, "on");
143
144 URI proxyRequestURI = proxyRequest.getURI();
145 String rawPath = proxyRequestURI.getRawPath();
146 String rawQuery = proxyRequestURI.getRawQuery();
147
148 String requestURI = (String)proxyRequest.getAttributes().get(REQUEST_URI_ATTRIBUTE);
149 if (requestURI == null)
150 {
151 requestURI = rawPath;
152 if (rawQuery != null)
153 requestURI += "?" + rawQuery;
154 }
155 fastCGIHeaders.put(FCGI.Headers.REQUEST_URI, requestURI);
156
157 String scriptName = rawPath;
158 Matcher matcher = scriptPattern.matcher(rawPath);
159 if (matcher.matches())
160 {
161
162 scriptName = matcher.group(1);
163
164
165 if (matcher.groupCount() > 1)
166 fastCGIHeaders.put(FCGI.Headers.PATH_INFO, matcher.group(2));
167 }
168 fastCGIHeaders.put(FCGI.Headers.SCRIPT_NAME, scriptName);
169
170 String root = fastCGIHeaders.get(FCGI.Headers.DOCUMENT_ROOT);
171 fastCGIHeaders.put(FCGI.Headers.SCRIPT_FILENAME, root + scriptName);
172 }
173
174 private class ProxyHttpClientTransportOverFCGI extends HttpClientTransportOverFCGI
175 {
176 public ProxyHttpClientTransportOverFCGI(String scriptRoot)
177 {
178 super(scriptRoot);
179 }
180
181 @Override
182 protected void customize(Request request, HttpFields fastCGIHeaders)
183 {
184 super.customize(request, fastCGIHeaders);
185 customizeFastCGIHeaders(request, fastCGIHeaders);
186 }
187 }
188 }