001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.quercus.env;
031:
032: import com.caucho.quercus.QuercusRequestAdapter;
033:
034: import javax.servlet.http.HttpServletRequest;
035:
036: import java.util.Enumeration;
037: import java.util.Map;
038: import java.util.Set;
039:
040: /**
041: * Represents the server
042: */
043: public class ServerArrayValue extends ArrayValueImpl {
044: private static final StringValue SERVER_NAME_V = new StringBuilderValue(
045: "SERVER_NAME");
046: private static final StringValue SERVER_PORT_V = new StringBuilderValue(
047: "SERVER_PORT");
048: private static final StringValue REMOTE_HOST_V = new StringBuilderValue(
049: "REMOTE_HOST");
050: private static final StringValue REMOTE_ADDR_V = new StringBuilderValue(
051: "REMOTE_ADDR");
052: private static final StringValue REMOTE_PORT_V = new StringBuilderValue(
053: "REMOTE_PORT");
054:
055: private static final StringValue DOCUMENT_ROOT_V = new StringBuilderValue(
056: "DOCUMENT_ROOT");
057:
058: private static final StringValue SERVER_SOFTWARE_V = new StringBuilderValue(
059: "SERVER_SOFTWARE");
060:
061: private static final StringValue SERVER_PROTOCOL_V = new StringBuilderValue(
062: "SERVER_PROTOCOL");
063: private static final StringValue REQUEST_METHOD_V = new StringBuilderValue(
064: "REQUEST_METHOD");
065: private static final StringValue QUERY_STRING_V = new StringBuilderValue(
066: "QUERY_STRING");
067:
068: private static final StringValue REQUEST_URI_V = new StringBuilderValue(
069: "REQUEST_URI");
070: private static final StringValue SCRIPT_NAME_V = new StringBuilderValue(
071: "SCRIPT_NAME");
072: private static final StringValue SCRIPT_FILENAME_V = new StringBuilderValue(
073: "SCRIPT_FILENAME");
074: private static final StringValue PATH_INFO_V = new StringBuilderValue(
075: "PATH_INFO");
076: private static final StringValue PATH_TRANSLATED_V = new StringBuilderValue(
077: "PATH_TRANSLATED");
078:
079: private static final StringValue PHP_SELF_V = new StringBuilderValue(
080: "PHP_SELF");
081:
082: private static final StringValue HTTPS_V = new StringBuilderValue(
083: "HTTPS");
084:
085: private static final StringValue HTTP_HOST_V = new StringBuilderValue(
086: "HTTP_HOST");
087:
088: private final Env _env;
089:
090: private boolean _isFilled;
091:
092: public ServerArrayValue(Env env) {
093: _env = env;
094: }
095:
096: /**
097: * Converts to an object.
098: */
099: public Object toObject() {
100: return null;
101: }
102:
103: /**
104: * Adds a new value.
105: */
106: public Value put(Value key, Value value) {
107: if (!_isFilled)
108: fillMap();
109:
110: return super .put(key, value);
111: }
112:
113: /**
114: * Adds a new value.
115: */
116: public Value put(Value value) {
117: if (!_isFilled)
118: fillMap();
119:
120: return super .put(value);
121: }
122:
123: /**
124: * Gets a new value.
125: */
126: public Value get(Value key) {
127: if (!_isFilled)
128: fillMap();
129:
130: return super .get(key);
131: }
132:
133: /**
134: * Returns the array ref.
135: */
136: public Var getRef(Value key) {
137: if (!_isFilled)
138: fillMap();
139:
140: return super .getRef(key);
141: }
142:
143: /**
144: * Copy for assignment.
145: */
146: public Value copy() {
147: if (!_isFilled)
148: fillMap();
149:
150: return new ArrayValueImpl(this );
151: }
152:
153: /**
154: * Returns an iterator of the entries.
155: */
156: public Set<Map.Entry<Value, Value>> entrySet() {
157: if (!_isFilled)
158: fillMap();
159:
160: return super .entrySet();
161: }
162:
163: /**
164: * Convenience for lib.
165: */
166: public void put(String key, String value) {
167: if (!_isFilled)
168: fillMap();
169:
170: super .put(_env.createString(key), _env.createString(value));
171: }
172:
173: /**
174: * Prints the value.
175: * @param env
176: */
177: public void print(Env env) {
178: env.print("Array");
179: }
180:
181: /**
182: * Fills the map.
183: */
184: private void fillMap() {
185: if (_isFilled)
186: return;
187:
188: _isFilled = true;
189:
190: for (Map.Entry<String, String> entry : System.getenv()
191: .entrySet()) {
192: super .put(_env.createString(entry.getKey()), _env
193: .createString(entry.getValue()));
194: }
195:
196: for (Map.Entry<Value, Value> entry : _env.getQuercus()
197: .getServerEnvMap().entrySet()) {
198: super .put(entry.getKey(), entry.getValue());
199: }
200:
201: HttpServletRequest request = _env.getRequest();
202:
203: if (request != null) {
204: super .put(SERVER_NAME_V, _env.createString(request
205: .getServerName()));
206:
207: super .put(SERVER_PORT_V, new LongValue(request
208: .getServerPort()));
209: super .put(REMOTE_HOST_V, _env.createString(request
210: .getRemoteHost()));
211: super .put(REMOTE_ADDR_V, _env.createString(request
212: .getRemoteAddr()));
213: super .put(REMOTE_PORT_V, new LongValue(request
214: .getRemotePort()));
215:
216: // Drupal's optional activemenu plugin only works on Apache servers!
217: // bug at http://drupal.org/node/221867
218: super .put(SERVER_SOFTWARE_V, _env
219: .createString("Apache PHP Quercus("
220: + _env.getQuercus().getVersion() + ")"));
221:
222: super .put(SERVER_PROTOCOL_V, _env.createString(request
223: .getProtocol()));
224: super .put(REQUEST_METHOD_V, _env.createString(request
225: .getMethod()));
226:
227: String queryString = QuercusRequestAdapter
228: .getPageQueryString(request);
229: String requestURI = QuercusRequestAdapter
230: .getPageURI(request);
231: String servletPath = QuercusRequestAdapter
232: .getPageServletPath(request);
233: String pathInfo = QuercusRequestAdapter
234: .getPagePathInfo(request);
235: String contextPath = QuercusRequestAdapter
236: .getPageContextPath(request);
237:
238: if (queryString != null) {
239: super .put(QUERY_STRING_V, _env
240: .createString(queryString));
241: }
242:
243: // XXX: a better way?
244: // getRealPath() returns a native path
245: // need to convert windows paths to resin paths
246: String root = request.getRealPath("/");
247: if (root.indexOf('\\') >= 0) {
248: root = root.replace('\\', '/');
249: root = '/' + root;
250: }
251:
252: super .put(DOCUMENT_ROOT_V, _env.createString(root));
253:
254: super .put(SCRIPT_NAME_V, _env.createString(contextPath
255: + servletPath));
256:
257: if (queryString != null)
258: requestURI = requestURI + '?' + queryString;
259:
260: super .put(REQUEST_URI_V, _env.createString(requestURI));
261: super .put(SCRIPT_FILENAME_V, _env.createString(request
262: .getRealPath(servletPath)));
263:
264: if (pathInfo != null) {
265: super .put(PATH_INFO_V, _env.createString(pathInfo));
266: super .put(PATH_TRANSLATED_V, _env.createString(request
267: .getRealPath(pathInfo)));
268: }
269:
270: if (request.isSecure())
271: super .put(HTTPS_V, _env.createString("on"));
272:
273: if (pathInfo == null)
274: super .put(PHP_SELF_V, _env.createString(contextPath
275: + servletPath));
276: else
277: super .put(PHP_SELF_V, _env.createString(contextPath
278: + servletPath + pathInfo));
279:
280: Enumeration e = request.getHeaderNames();
281: while (e.hasMoreElements()) {
282: String key = (String) e.nextElement();
283:
284: String value = request.getHeader(key);
285:
286: if (key.equalsIgnoreCase("Host")) {
287: super .put(HTTP_HOST_V, _env.createString(value));
288: } else {
289: super .put(convertHttpKey(key), _env
290: .createString(value));
291: }
292: }
293: }
294: }
295:
296: /**
297: * Converts a header key to HTTP_
298: */
299: private StringValue convertHttpKey(String key) {
300: StringValue sb = _env.createUnicodeBuilder();
301:
302: sb.append("HTTP_");
303:
304: int len = key.length();
305: for (int i = 0; i < len; i++) {
306: char ch = key.charAt(i);
307:
308: if (Character.isLowerCase(ch))
309: sb.append(Character.toUpperCase(ch));
310: else if (ch == '-')
311: sb.append('_');
312: else
313: sb.append(ch);
314: }
315:
316: return sb;
317: }
318:
319: //
320: // Java serialization code
321: //
322:
323: private Object writeReplace() {
324: if (!_isFilled)
325: fillMap();
326:
327: return new ArrayValueImpl(this);
328: }
329: }
|