001: /**********************************************************************************
002: *
003: * Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
004: * Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
005: *
006: * Licensed under the Educational Community License Version 1.0 (the "License");
007: * By obtaining, using and/or copying this Original Work, you agree that you have read,
008: * understand, and will comply with the terms and conditions of the Educational Community License.
009: * You may obtain a copy of the License at:
010: *
011: * http://cvs.sakaiproject.org/licenses/license_1_0.html
012: *
013: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
014: * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
015: * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
016: * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
017: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
018: *
019: **********************************************************************************/package edu.indiana.lib.twinpeaks.util;
020:
021: import java.io.*;
022: import java.net.*;
023: import java.util.*;
024:
025: import javax.servlet.*;
026: import javax.servlet.http.*;
027:
028: /**
029: * HTTP utilites
030: */
031: public class HttpTransactionUtils {
032: private static org.apache.commons.logging.Log _log = LogUtils
033: .getLog(HttpTransactionUtils.class);
034:
035: private HttpTransactionUtils() {
036: }
037:
038: /**
039: * Default HTTP character set
040: */
041: public static final String DEFAULTCS = "ISO-8859-1";
042:
043: /*
044: * Parameter handling
045: */
046:
047: /**
048: * Format one HTTP parameter
049: * @param name Parameter name
050: * @param value Parameter value (URLEncoded using default chracter set)
051: * @return Parameter text (ampersand+name=url-encoded-value)
052: */
053: public static String formatParameter(String name, String value) {
054: return formatParameter(name, value, "&", DEFAULTCS);
055: }
056:
057: /**
058: * Format one HTTP parameter
059: * @param name Parameter name
060: * @param value Parameter value (will be URLEncoded)
061: * @param separator Character to separate parameters
062: * @param cs Character set specification (utf-8, etc)
063: * @return Parameter text (separator+name=url-encoded-value)
064: */
065: public static String formatParameter(String name, String value,
066: String separator, String cs) {
067: StringBuffer parameter = new StringBuffer();
068:
069: if (!StringUtils.isNull(value)) {
070:
071: parameter.append(separator);
072: parameter.append(name);
073: parameter.append('=');
074:
075: try {
076: parameter.append(URLEncoder.encode(value, cs));
077: } catch (UnsupportedEncodingException exception) {
078: throw new IllegalArgumentException(
079: "Invalid character set: \"" + cs + "\"");
080: }
081: }
082: return parameter.toString();
083: }
084:
085: /*
086: * HTTP status values
087: */
088:
089: /**
090: * Informational status?
091: * @return true if so
092: */
093: public static boolean isHttpInfo(int status) {
094: return ((status / 100) == 1);
095: }
096:
097: /**
098: * HTTP redirect?
099: * @return true if so
100: */
101: public static boolean isHttpRedirect(int status) {
102: return ((status / 100) == 3);
103: }
104:
105: /**
106: * Success status?
107: * @return true if so
108: */
109: public static boolean isHttpSuccess(int status) {
110: return ((status / 100) == 2);
111: }
112:
113: /**
114: * Error in request?
115: * @return true if so
116: */
117: public static boolean isHttpRequestError(int status) {
118: return ((status / 100) == 4);
119: }
120:
121: /**
122: * Server error?
123: * @return true if so
124: */
125: public static boolean isHttpServerError(int status) {
126: return ((status / 100) == 5);
127: }
128:
129: /**
130: * General "did an error occur"?
131: * @return true if so
132: */
133: public static boolean isHttpError(int status) {
134: return isHttpRequestError(status) || isHttpServerError(status);
135: }
136:
137: /**
138: * Set up a simple Map of HTTP request parameters (assumes no duplicate names)
139: * @param request HttpServletRequest object
140: * @return Map of name=value pairs
141: */
142: public static Map getAttributesAsMap(HttpServletRequest request) {
143: Enumeration enumeration = request.getParameterNames();
144: HashMap map = new HashMap();
145:
146: while (enumeration.hasMoreElements()) {
147: String name = (String) enumeration.nextElement();
148:
149: map.put(name, request.getParameter(name));
150: }
151: return map;
152: }
153:
154: /**
155: * Format a base URL string ( protocol://server[:port] )
156: * @param url URL to format
157: * @return URL string
158: */
159: public static String formatUrl(URL url)
160: throws MalformedURLException {
161: return formatUrl(url, false);
162: }
163:
164: /**
165: * Format a base URL string ( protocol://server[:port][/file-specification] )
166: * @param url URL to format
167: * @param preserveFile Keep the /directory/filename portion of the URL?
168: * @return URL string
169: */
170: public static String formatUrl(URL url, boolean preserveFile)
171: throws MalformedURLException {
172: StringBuffer result;
173: int port;
174:
175: result = new StringBuffer(url.getProtocol());
176:
177: result.append("://");
178: result.append(url.getHost());
179:
180: if ((port = url.getPort()) != -1) {
181: result.append(":");
182: result.append(String.valueOf(port));
183: }
184:
185: if (preserveFile) {
186: String file = url.getFile();
187:
188: if (file != null) {
189: result.append(file);
190: }
191: }
192: return result.toString();
193: }
194:
195: /**
196: * Pull the server [and port] from a URL specification
197: * @param url URL string
198: * @return server[:port]
199: */
200: public static String getServer(String url) {
201: String server = url;
202: int protocol, slash;
203:
204: if ((protocol = server.indexOf("//")) != -1) {
205: if ((slash = server.substring(protocol + 2).indexOf("/")) != -1) {
206: server = server.substring(0, protocol + 2 + slash);
207: }
208: }
209: return server;
210: }
211:
212: /*
213: * urlEncodeParameters(): URL component specifications
214: */
215:
216: /**
217: * protocol://server
218: */
219: public static final String SERVER = "server";
220: /**
221: * /file/specification
222: */
223: public static final String FILE = "file";
224: /**
225: * ?parameter1=value1¶meter2=value2
226: */
227: public static final String PARAMETERS = "parameters";
228: /**
229: * /file/specification?parameter1=value1¶meter2=value2
230: */
231: public static final String FILEANDPARAMS = "fileandparameters";
232:
233: /**
234: * Fetch a component from a URL string
235: * @param url URL String
236: * @param component name (one of server, file, parameters, fileandparameters)
237: * @return URL component string (null if none)
238: */
239: public static String getUrlComponent(String url, String component)
240: throws MalformedURLException {
241: String file;
242: int index;
243:
244: if (component.equalsIgnoreCase(SERVER)) {
245: return getServer(url);
246: }
247:
248: if (!component.equalsIgnoreCase(FILE)
249: && !component.equalsIgnoreCase(PARAMETERS)
250: && !component.equalsIgnoreCase(FILEANDPARAMS)) {
251: throw new IllegalArgumentException(component);
252: }
253:
254: file = new URL(url).getFile();
255: if (file == null) {
256: return null;
257: }
258: /*
259: * Fetch file and parameters?
260: */
261: if (component.equalsIgnoreCase(FILEANDPARAMS)) {
262: return file;
263: }
264: /*
265: * File portion only?
266: */
267: index = file.indexOf('?');
268:
269: if (component.equalsIgnoreCase(FILE)) {
270: switch (index) {
271: case -1: // No parameters
272: return file;
273: case 0: // Only parameters (no file)
274: return null;
275: default:
276: return file.substring(0, index);
277: }
278: }
279: /*
280: * Isolate parameters
281: */
282: return (index == -1) ? null : file.substring(index);
283: }
284:
285: /**
286: * URLEncode parameter names and values
287: * @param original Full URL specification (http://example.com/xxx?a=b&c=d)
288: * @return Original URL with (possibly) encoded parameters
289: */
290: public static String urlEncodeFullUrl(String original) {
291: StringBuffer encoded;
292: String base, file, params;
293:
294: try {
295: base = getUrlComponent(original, SERVER);
296: file = getUrlComponent(original, FILE);
297: params = getUrlComponent(original, PARAMETERS);
298:
299: } catch (MalformedURLException exception) {
300: _log.warn("Invalid URL provided: " + original);
301: return original;
302: }
303:
304: if (StringUtils.isNull(params)) {
305: return original;
306: }
307:
308: encoded = new StringBuffer();
309: encoded.append(base);
310:
311: if (!StringUtils.isNull(file)) {
312: encoded.append(file);
313: }
314: encoded.append(urlEncodeParameters(params));
315: return encoded.toString();
316: }
317:
318: /**
319: * URLEncode parameter names and values
320: * @param original Original parameter list (?a=b&c=d)
321: * @return Possibly encoded parameter list
322: */
323: public static String urlEncodeParameters(String original) {
324: StringBuffer encoded = new StringBuffer();
325:
326: for (int i = 0; i < original.length(); i++) {
327: String c = original.substring(i, i + 1);
328:
329: if (!c.equals("&") && !c.equals("=") && !c.equals("?")) {
330: c = URLEncoder.encode(c);
331: }
332: encoded.append(c);
333: }
334: return encoded.toString();
335: }
336:
337: /*
338: * Test
339: */
340: public static void main(String[] args) throws Exception {
341: String u = "http://example.com/dir1/dir2/file.html?parm1=1¶m2=2";
342:
343: System.out.println("Server: " + getUrlComponent(u, "server"));
344: System.out.println("File: " + getUrlComponent(u, "file"));
345: System.out.println("Parameters: "
346: + getUrlComponent(u, "parameters"));
347: System.out.println("File & Parameters: "
348: + getUrlComponent(u, "fileandparameters"));
349: System.out.println("Bad: " + getUrlComponent(u, "bad"));
350: }
351: }
|