001package votorola.g.web; // Copyright 2011-2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. 002 003import java.net.*; 004import java.util.*; 005import javax.servlet.*; 006import javax.servlet.http.*; 007import votorola.g.lang.*; 008 009 010/** Servlet request utilities. 011 * 012 * @see HttpServletRequest 013 */ 014public @ThreadSafe final class HTTPServletRequestX 015{ 016 017 018 private HTTPServletRequestX() {} 019 020 021 022 /** Constructs a standard log message summarizing the request, and returns it in a 023 * string builder. 024 */ 025 public static StringBuilder buildRequestSummary( final HttpServletRequest reqHS ) 026 { 027 final StringBuilder b = getRequestURLFull( reqHS ); 028 b.insert( 0, ": " ); 029 b.insert( 0, reqHS.getRemoteAddr() ); 030 b.insert( 0, "Request from " ); 031 return b; 032 } 033 034 035 036 /** Returns the boolean value of a request parameter, where true is encoded as a 'Y', 037 * 'y' or empty value '', and false as an 'N', 'n' or omitted value (null). 038 * 039 * @throws HTTPRequestException if the value is present and malformed. 040 */ 041 public static boolean getBooleanParameter( final String key, final ServletRequest reqS ) 042 throws HTTPRequestException 043 { 044 final String value = reqS.getParameter( key ); 045 if( value == null || "N".equals(value) || "n".equals(value) ) return false; 046 047 if( "".equals(value) || "Y".equals(value) || "y".equals(value) ) return true; 048 049 throw new HTTPRequestException( HttpServletResponse.SC_BAD_REQUEST, // 400 050 "Unrecognized '" + key + "' value: " + value ); 051 } 052 053 054 055 /** Returns the apparent address of the remote client after taking into account any 056 * proxying declared in the <code>x-forwarded-for</code> header. No attempt is made 057 * to authenticate the proxying declaration, which may easily be bogus. Therefore do 058 * not depend on the returned value being correct, or even well formed. 059 */ 060 public static String getForwardedRemoteAddr( final HttpServletRequest reqHS ) 061 { 062 // http://johannburkard.de/blog/programming/java/x-forwarded-for-http-header.html 063 String a = reqHS.getHeader( "X-Forwarded-For" ); 064 if( a == null ) a = reqHS.getRemoteAddr(); 065 else 066 { 067 final int c = a.indexOf( ',' ); 068 if( c >= 0 ) a = a.substring( 0, c ); // first address in list is most remote 069 } 070 return a; 071 } 072 073 074 075 // /** Returns the value of a request parameter, or a default value if the parameter is 076 // * not specified. 077 // * 078 // * @param defaultValue the value to return in the event the parameter is not 079 // * specified. 080 // * 081 // * @throws HTTPRequestException if the actual value is the empty string "". 082 // */ 083 // public static String getParameter( final String key, final String defaultValue, 084 // final ServletRequest reqS ) throws HTTPRequestException 085 // { 086 // String value = getParameterNonEmpty( key, reqS ); 087 // if( value == null ) value = defaultValue; 088 // return value; 089 // } 090 091 092 093 /** Returns the non-empty value of a request parameter, or null if the parameter is 094 * not specified. 095 * 096 * @throws HTTPRequestException if the value is the empty string "". 097 * 098 * @see votorola.a.web.wic.VPage#stringNonEmpty(org.apache.wicket.request.mapper.parameter.PageParameters,String) 099 * @see votorola.g.web.wic.PageParametersX#getStringNonEmpty(org.apache.wicket.request.mapper.parameter.PageParameters,String) 100 */ 101 public static String getParameterNonEmpty( final String key, final ServletRequest reqS ) 102 throws HTTPRequestException 103 { 104 final String value = reqS.getParameter( key ); 105 if( !"".equals( value )) return value; 106 107 throw new HTTPRequestException( HttpServletResponse.SC_BAD_REQUEST, // 400 108 "Empty request parameter '" + key + "'" ); 109 } 110 111 112 113 /** Returns the non-null, non-empty value of a request parameter. 114 * 115 * @throws HTTPRequestException if the value is either null or the empty string "". 116 * 117 * @see votorola.a.web.wic.VPage#stringRequired(org.apache.wicket.request.mapper.parameter.PageParameters,String) 118 * @see votorola.g.web.wic.PageParametersX#getStringRequired(org.apache.wicket.request.mapper.parameter.PageParameters,String) 119 */ 120 public static String getParameterRequired( final String key, final ServletRequest reqS ) 121 throws HTTPRequestException 122 { 123 final String value = reqS.getParameter( key ); 124 if( value != null && !"".equals( value )) return value; 125 126 throw new HTTPRequestException( HttpServletResponse.SC_BAD_REQUEST, // 400 127 "Missing request parameter '" + key + "'" ); 128 } 129 130 131 132 /** Reconstructs the full URL the client used to make the request, including any query 133 * portion, and returns it in a string builder. 134 * 135 * @see HttpServletRequest#getRequestURL() 136 */ 137 public static StringBuilder getRequestURLFull( final HttpServletRequest reqHS ) 138 { 139 final StringBuilder b = new StringBuilder( reqHS.getRequestURL().toString() ); 140 final String q = reqHS.getQueryString(); 141 if( q != null ) b.append( '?' ).append( q ); 142 return b; 143 } 144 145 146 147 /** Copies headers of the specified name from an incoming client request (reqHS) to an 148 * outgoing server request (http). 149 */ 150 public static void relayHeaders( final String name, final HttpServletRequest reqHS, 151 final URLConnection http ) 152 { 153 final Enumeration<?> values = reqHS.getHeaders( name ); 154 while( values.hasMoreElements() ) 155 { 156 http.setRequestProperty( name, values.nextElement().toString() ); 157 } 158 } 159 160 161}