001    package railo.runtime.net.http;
002    
003    import java.io.UnsupportedEncodingException;
004    import java.lang.reflect.Method;
005    import java.net.InetAddress;
006    import java.net.URL;
007    import java.util.ArrayList;
008    
009    import javax.servlet.http.Cookie;
010    import javax.servlet.http.HttpServletRequest;
011    import javax.servlet.http.HttpServletResponse;
012    
013    import railo.commons.lang.Pair;
014    import railo.commons.lang.StringUtil;
015    import railo.commons.net.HTTPUtil;
016    import railo.commons.net.URLDecoder;
017    import railo.commons.net.URLEncoder;
018    import railo.runtime.config.Config;
019    import railo.runtime.functions.decision.IsLocalHost;
020    import railo.runtime.op.Caster;
021    import railo.runtime.type.List;
022    
023    public final class ReqRspUtil {
024    
025            public static String get(Pair[] items, String name) {
026                    for(int i=0;i<items.length;i++) {
027                            if(items[i].getName().equalsIgnoreCase(name)) 
028                                    return Caster.toString(items[i].getValue(),null);
029                    }
030                    return null;
031            }
032            
033            public static Pair[] add(Pair[] items, String name, Object value) {
034                    Pair[] tmp = new Pair[items.length+1];
035                    for(int i=0;i<items.length;i++) {
036                            tmp[i]=items[i];
037                    }
038                    tmp[items.length]=new Pair(name,value);
039                    return tmp;
040            }
041            
042            public static Pair[] set(Pair[] items, String name, Object value) {
043                    for(int i=0;i<items.length;i++) {
044                            if(items[i].getName().equalsIgnoreCase(name)) {
045                                    items[i]=new Pair(name,value);
046                                    return items;
047                            }
048                    }
049                     return add(items, name, value);
050            }
051    
052            /**
053             * return path to itself
054             * @param req
055             */
056            public static String self(HttpServletRequest req) {
057                    StringBuffer sb=new StringBuffer(req.getServletPath());
058                    String qs=req.getQueryString();
059                    if(!StringUtil.isEmpty(qs))sb.append('?').append(qs);
060                    return sb.toString();
061            }
062    
063            public static void setContentLength(HttpServletResponse rsp, int length) {
064                    rsp.setContentLength(length);
065            }
066            public static void setContentLength(HttpServletResponse rsp, long length) {
067                    if(length <= Integer.MAX_VALUE){
068                            setContentLength(rsp,(int)length);
069                    }
070                    else{
071                            rsp.addHeader("Content-Length", Caster.toString(length));
072                    }
073            }
074    
075            public static Cookie[] getCookies(Config config,HttpServletRequest req) {
076                    Cookie[] cookies = req.getCookies();
077                    String charset = config.getWebCharset();
078                    
079                    if(cookies!=null) {
080                            Cookie cookie;
081                            String tmp;
082                            for(int i=0;i<cookies.length;i++){
083                                    cookie=cookies[i];      
084                                    // value (is decoded by the servlet engine with iso-8859-1)
085                                    if(!StringUtil.isAscci(cookie.getValue())) {
086                                            tmp=encode(cookie.getValue(), "iso-8859-1");
087                                            cookie.setValue(decode(tmp, charset,false));
088                                    }
089                                    
090                            }
091                    }
092                    else {
093                            String str = req.getHeader("Cookie");
094                            if(str!=null) {
095                                    try{
096                                            String[] arr = List.listToStringArray(str, ';'),tmp;
097                                            java.util.List<Cookie> list=new ArrayList<Cookie>();
098                                            for(int i=0;i<arr.length;i++){
099                                                    tmp=List.listToStringArray(arr[i], '=');
100                                                    if(tmp.length>0) {
101                                                            list.add(new Cookie(dec(tmp[0],charset,false), tmp.length>1?dec(tmp[1],charset,false):""));
102                                                    }
103                                            }
104                                            cookies=list.toArray(new Cookie[list.size()]);
105                                            
106                                    }
107                                    catch(Throwable t){}
108                            }
109                    }
110                    return cookies;
111            }
112    
113    
114            public static void setCharacterEncoding(HttpServletResponse rsp,String charset) {
115                    try {
116                            Method setCharacterEncoding = rsp.getClass().getMethod("setCharacterEncoding", new Class[0]);
117                            setCharacterEncoding.invoke(rsp, new Object[0]);
118                    } 
119                    catch (Throwable t) {}
120            }
121    
122            public static String getHeader(HttpServletRequest request, String name,String defaultValue) {
123                    try {
124                            return request.getHeader(name);
125                    }
126                    catch(Throwable t){
127                            return defaultValue;
128                    }
129            }
130    
131            public static String getScriptName(HttpServletRequest req) {
132                    return StringUtil.emptyIfNull(req.getContextPath())+StringUtil.emptyIfNull(req.getServletPath());
133            }
134            
135            private static String dec(String str, String charset, boolean force) throws UnsupportedEncodingException {
136                    str=str.trim();
137                    if(StringUtil.startsWith(str, '"') && StringUtil.endsWith(str, '"'))
138                            str=str.substring(1,str.length()-1);
139                            
140                    return decode(str,charset,force);//java.net.URLDecoder.decode(str.trim(), charset);
141            }
142    
143    
144        public static String decode(String str,String charset, boolean force) {
145            try {
146                            return URLDecoder.decode(str, charset,force);
147                    } 
148                    catch (UnsupportedEncodingException e) {
149                            return str;
150                    }
151            }
152        public static String encode(String str,String charset) {
153                    try {
154                            return URLEncoder.encode(str, charset);
155                    } 
156                    catch (UnsupportedEncodingException e) {
157                            return str;
158                    }
159            }
160        
161        
162        
163        public static boolean needEncoding(String str, boolean allowPlus){
164            if(StringUtil.isEmpty(str,false)) return false;
165            
166            int len=str.length();
167            char c;
168            for(int i=0;i<len;i++){
169                    c=str.charAt(i);
170                    if(c >='0' && c <= '9') continue;
171                    if(c >='a' && c <= 'z') continue;
172                    if(c >='A' && c <= 'Z') continue;
173                    
174                    // _-.*
175                    if(c =='-') continue;
176                    if(c =='_') continue;
177                    if(c =='.') continue;
178                    if(c =='*') continue;
179                    if(c =='/') continue;
180                    if(allowPlus && c =='+') continue;
181                    
182                    if(c =='%') {
183                            if(i+2>=len) return true;
184                            try{
185                                    Integer.parseInt(str.substring(i+1,i+3),16);
186                            }
187                            catch(NumberFormatException nfe){
188                                    return true;
189                            }
190                            i+=3;
191                            continue;
192                    }
193                    return true;
194            }
195            return false;
196        }
197        
198        public static boolean needDecoding(String str){
199            if(StringUtil.isEmpty(str,false)) return false;
200            
201            boolean need=false;
202            int len=str.length();
203            char c;
204            for(int i=0;i<len;i++){
205                    c=str.charAt(i);
206                    if(c >='0' && c <= '9') continue;
207                    if(c >='a' && c <= 'z') continue;
208                    if(c >='A' && c <= 'Z') continue;
209                    
210                    // _-.*
211                    if(c =='-') continue;
212                    if(c =='_') continue;
213                    if(c =='.') continue;
214                    if(c =='*') continue;
215                    if(c =='+') {
216                            need=true;
217                            continue;
218                    }
219                    
220                    if(c =='%') {
221                            if(i+2>=len) return false;
222                            try{
223                                    Integer.parseInt(str.substring(i+1,i+3),16);
224                            }
225                            catch(NumberFormatException nfe){
226                                    return false;
227                            }
228                            i+=3;
229                            need=true;
230                            continue;
231                    }
232                    return false;
233            }
234            return need;
235        }
236    
237            public static boolean isThis(HttpServletRequest req, String url) { 
238                    try {
239                            return isThis(req, HTTPUtil.toURL(url));
240                    } 
241                    catch (Throwable t) {
242                            return false;
243                    }
244            }
245    
246            public static boolean isThis(HttpServletRequest req, URL url) { 
247                    try {
248                            // Port
249                            int reqPort=req.getServerPort();
250                            int urlPort=url.getPort();
251                            if(urlPort<=0) urlPort=HTTPUtil.isSecure(url)?443:80;
252                            if(reqPort<=0) reqPort=req.isSecure()?443:80;
253                            if(reqPort!=urlPort) return false;
254                            
255                            // host
256                            String reqHost = req.getServerName();
257                            String urlHost = url.getHost();
258                            if(reqHost.equalsIgnoreCase(urlHost)) return true;
259                            if(IsLocalHost.invoke(reqHost) && IsLocalHost.invoke(reqHost)) return true;
260                            
261                            InetAddress urlAddr = InetAddress.getByName(urlHost);
262                            
263                            InetAddress reqAddr = InetAddress.getByName(reqHost);
264                            if(reqAddr.getHostName().equalsIgnoreCase(urlAddr.getHostName())) return true;
265                            if(reqAddr.getHostAddress().equalsIgnoreCase(urlAddr.getHostAddress())) return true;
266                            
267                            reqAddr = InetAddress.getByName(req.getRemoteAddr());
268                            if(reqAddr.getHostName().equalsIgnoreCase(urlAddr.getHostName())) return true;
269                            if(reqAddr.getHostAddress().equalsIgnoreCase(urlAddr.getHostAddress())) return true;
270                    }
271                    catch(Throwable t){}
272                    return false;
273            }
274    }