001    package railo.commons.net;
002    
003    import java.io.ByteArrayOutputStream;
004    import java.io.IOException;
005    import java.io.UnsupportedEncodingException;
006    import java.net.MalformedURLException;
007    import java.net.URI;
008    import java.net.URISyntaxException;
009    import java.net.URL;
010    import java.util.HashMap;
011    import java.util.Map;
012    
013    import javax.servlet.RequestDispatcher;
014    import javax.servlet.ServletContext;
015    import javax.servlet.ServletException;
016    import javax.servlet.ServletRequest;
017    import javax.servlet.ServletResponse;
018    
019    import railo.commons.io.IOUtil;
020    import railo.commons.lang.StringList;
021    import railo.commons.lang.StringUtil;
022    import railo.commons.lang.mimetype.ContentType;
023    import railo.commons.lang.mimetype.MimeType;
024    import railo.commons.net.http.HTTPEngine;
025    import railo.commons.net.http.HTTPResponse;
026    import railo.runtime.PageContext;
027    import railo.runtime.PageContextImpl;
028    import railo.runtime.PageSource;
029    import railo.runtime.PageSourceImpl;
030    import railo.runtime.config.Config;
031    import railo.runtime.engine.ThreadLocalPageContext;
032    import railo.runtime.exp.ApplicationException;
033    import railo.runtime.exp.PageServletException;
034    import railo.runtime.net.http.HTTPServletRequestWrap;
035    import railo.runtime.net.http.HttpServletResponseWrap;
036    import railo.runtime.net.http.ReqRspUtil;
037    import railo.runtime.type.util.ListUtil;
038    
039    /**
040     * 
041     */
042    public final class HTTPUtil {
043    
044        /**
045         * Field <code>ACTION_POST</code>
046         */
047        public static final short ACTION_POST=0;
048        
049        /**
050         * Field <code>ACTION_GET</code>
051         */
052        public static final short ACTION_GET=1;
053    
054            /**
055             * Field <code>STATUS_OK</code>
056             */
057            public static final int STATUS_OK=200;
058            //private static final String NO_MIMETYPE="Unable to determine MIME type of file.";
059    
060            public static final int MAX_REDIRECT = 15;
061        
062        /*public static HttpMethod invoke(URL url, String username, String password, long timeout, 
063                String charset, String useragent,
064                String proxyserver, int proxyport, String proxyuser, 
065                String proxypassword, Header[] headers) throws IOException {
066    
067            HttpClient client = new HttpClient();
068            HttpMethod httpMethod=new GetMethod(url.toExternalForm());
069            HostConfiguration config = client.getHostConfiguration();
070            
071            HttpState state = client.getState();
072            
073            setHeader(httpMethod,headers);
074            setContentType(httpMethod,charset);
075            setUserAgent(httpMethod,useragent);
076            setTimeout(client,timeout);
077            setCredentials(client,httpMethod,username,password);  
078            setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword);
079            
080            
081                    httpMethod = HttpClientUtil.execute(client,httpMethod,true);
082            
083            return httpMethod;
084        }*/
085        
086        /*public static HttpMethod post(URL url, String username, String password, long timeout, 
087                String charset, String useragent,
088                String proxyserver, int proxyport, String proxyuser, 
089                String proxypassword, Header[] headers) throws IOException {
090    
091            HttpClient client = new HttpClient();
092            HttpMethod httpMethod=new PostMethod(url.toExternalForm());
093            HostConfiguration config = client.getHostConfiguration();
094            
095            HttpState state = client.getState();
096            
097            setHeader(httpMethod,headers);
098            setContentType(httpMethod,charset);
099            setUserAgent(httpMethod,useragent);
100            setTimeout(client,timeout);
101            setCredentials(client,httpMethod,username,password);  
102            setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword);
103            
104            httpMethod = HttpClientUtil.execute(client,httpMethod,true);
105            
106            return httpMethod;
107        }*/
108        
109    
110        /**
111         * cast a string to a url
112         * @param strUrl string represent a url
113         * @return url from string
114         * @throws MalformedURLException
115         */
116             public static URL toURL(String strUrl) throws MalformedURLException {
117                     return toURL(strUrl,-1);
118             }
119             
120             public static URL toURL(String strUrl,URL defaultValue){
121                     try {
122                            return toURL(strUrl,-1);
123                    } catch (MalformedURLException e) {
124                            return defaultValue;
125                    }
126             }
127             
128    
129             public static String validateURL(String strUrl,String defaultValue){
130                     try {
131                            return toURL(strUrl,-1).toExternalForm();
132                    } catch (MalformedURLException e) {
133                            return defaultValue;
134                    }
135             }
136        
137        /**
138         * cast a string to a url
139         * @param strUrl string represent a url
140         * @return url from string
141         * @throws MalformedURLException
142         */
143    
144              public static URL toURL(String strUrl, int port) throws MalformedURLException {
145                      URL url;
146                      try {
147                        url=new URL(strUrl);
148                    }
149                    catch(MalformedURLException mue) {
150                        url=new URL("http://"+strUrl);
151                    }
152                      return toURL(url, port);
153              }
154             
155             
156        private static URL toURL(URL url, int port) throws MalformedURLException {
157            
158            
159            
160            
161            
162            
163            // file
164            String path=url.getPath();
165            //String file=url.getFile();
166            String query = url.getQuery();
167            String ref = url.getRef();
168            String user=url.getUserInfo();
169            if(port<=0) port=url.getPort();
170    
171            // decode path
172            if(!StringUtil.isEmpty(path)) {
173                    int sqIndex=path.indexOf(';');
174                    String q=null;
175                    if(sqIndex!=-1) {
176                            q=path.substring(sqIndex+1);
177                            path=path.substring(0,sqIndex);
178                    } 
179                    
180                    StringBuilder res=new StringBuilder();
181                    
182                    StringList list = ListUtil.toListTrim(path, '/');
183                    String str;
184                    
185                    while(list.hasNext()){
186                            str=list.next();
187                            //str=URLDecoder.decode(str);
188                            
189                            if(StringUtil.isEmpty(str)) continue;
190                            res.append("/");
191                            res.append(escapeQSValue(str));
192                    }
193                    if(StringUtil.endsWith(path, '/')) res.append('/');                     
194                    path=res.toString();
195                    
196                    if(sqIndex!=-1) {
197                            path+=decodeQuery(q,';');
198                    }
199                    
200            }
201            
202            // decode query 
203            query=decodeQuery(query,'?');
204           
205            
206            
207            String file=path+query;
208            
209         // decode ref/anchor       
210            if(ref!=null) {
211                    file+="#"+escapeQSValue(ref);
212            }
213            
214            // user/pasword
215            if(!StringUtil.isEmpty(user)) {
216                    int index=user.indexOf(':');
217                    if(index!=-1) {
218                            user=escapeQSValue(user.substring(0,index))+":"+escapeQSValue(user.substring(index+1));
219                    }
220                    else user=escapeQSValue(user);
221                    
222                    String strUrl = getProtocol(url)+"://"+user+"@"+url.getHost();
223                    if(port>0)strUrl+=":"+port;
224                    strUrl+=file;
225                    return new URL(strUrl);
226            }
227           
228           
229            
230           // port
231           if(port<=0) return new URL(url.getProtocol(),url.getHost(),file);
232           return new URL(url.getProtocol(),url.getHost(),port,file);
233           
234                           
235        }
236        
237        private static String decodeQuery(String query,char startDelimiter) {
238            if(!StringUtil.isEmpty(query)) {
239                    StringBuilder res=new StringBuilder();
240                    
241                    StringList list = ListUtil.toList(query, '&');
242                    String str;
243                    int index;
244                    char del=startDelimiter;
245                    while(list.hasNext()){
246                            res.append(del);
247                            del='&';
248                            str=list.next();
249                            index=str.indexOf('=');
250                            if(index==-1)res.append(escapeQSValue(str));
251                            else {
252                                    res.append(escapeQSValue(str.substring(0,index)));
253                                    res.append('=');
254                                    res.append(escapeQSValue(str.substring(index+1)));
255                            }
256                    }
257                    query=res.toString();
258            }
259            else query="";
260            return query;
261            }
262    
263    
264            public static URI toURI(String strUrl) throws URISyntaxException {
265                     return toURI(strUrl,-1);
266             }
267        
268        public static URI toURI(String strUrl, int port) throws URISyntaxException {
269            
270            //print.o((strUrl));
271            URI uri = new URI(strUrl);
272            
273            String host = uri.getHost();
274            String fragment = uri.getRawFragment();
275            String path = uri.getRawPath();
276            String query= uri.getRawQuery();
277            
278            String scheme = uri.getScheme();
279            String userInfo = uri.getRawUserInfo();
280            if(port<=0) port=uri.getPort();
281    
282        
283            // decode path
284            if(!StringUtil.isEmpty(path)) {
285                    
286                    int sqIndex=path.indexOf(';');
287                    String q=null;
288                    if(sqIndex!=-1) {
289                            q=path.substring(sqIndex+1);
290                            path=path.substring(0,sqIndex);
291                    } 
292                    
293                    
294                    StringBuilder res=new StringBuilder();
295                    
296                    StringList list = ListUtil.toListTrim(path, '/');
297                    String str;
298                    
299                    while(list.hasNext()){
300                            str=list.next();
301                            //str=URLDecoder.decode(str);
302                            
303                            if(StringUtil.isEmpty(str)) continue;
304                            res.append("/");
305                            res.append(escapeQSValue(str));
306                    }
307                    if(StringUtil.endsWith(path, '/')) res.append('/');                     
308                    path=res.toString();
309                    
310                    if(sqIndex!=-1) {
311                            path+=decodeQuery(q,';');
312                    }
313            }
314            
315            // decode query 
316            query=decodeQuery(query,'?');
317        
318            
319            
320         // decode ref/anchor       
321            if(!StringUtil.isEmpty(fragment)) {
322                    fragment=escapeQSValue(fragment);
323            }
324            
325            // user/pasword
326            if(!StringUtil.isEmpty(userInfo)) {
327                    int index=userInfo.indexOf(':');
328                    if(index!=-1) {
329                            userInfo=escapeQSValue(userInfo.substring(0,index))+":"+escapeQSValue(userInfo.substring(index+1));
330                    }
331                    else userInfo=escapeQSValue(userInfo);
332            }
333            
334            /*print.o("- fragment:"+fragment);
335            print.o("- host:"+host);
336            print.o("- path:"+path);
337            print.o("- query:"+query);
338            print.o("- scheme:"+scheme);
339            print.o("- userInfo:"+userInfo);
340            print.o("- port:"+port);
341            print.o("- absolute:"+uri.isAbsolute());
342            print.o("- opaque:"+uri.isOpaque());*/
343            
344            StringBuilder rtn=new StringBuilder();
345            if(scheme!=null) {
346                    rtn.append(scheme);
347                    rtn.append("://");
348            }
349            if(userInfo!=null) {
350                    rtn.append(userInfo);
351                    rtn.append("@");
352            }
353            if(host!=null) {
354                    rtn.append(host);
355            }
356            if(port>0) {
357                    rtn.append(":");
358                    rtn.append(port);
359            }
360            if(path!=null) {
361                    rtn.append(path);
362            }
363            if(query!=null) {
364                    //rtn.append("?");
365                    rtn.append(query);
366            }
367            if(fragment!=null) {
368                    rtn.append("#");
369                    rtn.append(fragment);
370            }
371            
372            return new URI(rtn.toString()); 
373        }
374    
375            /*private static String getProtocol(URI uri) {
376            String p=uri.getRawSchemeSpecificPart();
377            if(p==null) return null;
378                    if(p.indexOf('/')==-1) return p;
379                    if(p.indexOf("https")!=-1) return "https";
380                    if(p.indexOf("http")!=-1) return "http";
381                    return p;
382            }*/
383        
384        private static String getProtocol(URL url) {
385                    String p=url.getProtocol().toLowerCase();
386                    if(p.indexOf('/')==-1) return p;
387                    if(p.indexOf("https")!=-1) return "https";
388                    if(p.indexOf("http")!=-1) return "http";
389                    return p;
390            }
391        
392    
393        
394        public static String escapeQSValue(String str) {
395            if(!ReqRspUtil.needEncoding(str,true)) return str;
396            Config config = ThreadLocalPageContext.getConfig();
397            if(config!=null){
398                    try {
399                            return URLEncoder.encode(str,config.getWebCharset());
400                    } 
401                    catch (UnsupportedEncodingException e) {}
402            }
403            return URLEncoder.encode(str);
404            }
405    
406            /*public static HttpMethod put(URL url, String username, String password, int timeout, 
407                String charset, String useragent,
408                String proxyserver, int proxyport, String proxyuser, 
409                String proxypassword, Header[] headers, Object body) throws IOException {
410                    
411                    
412                    HttpClient client = new HttpClient();
413                    PutMethod httpMethod=new PutMethod(url.toExternalForm());
414            HostConfiguration config = client.getHostConfiguration();
415            
416            HttpState state = client.getState();
417            
418            setHeader(httpMethod,headers);
419            setContentType(httpMethod,charset);
420            setUserAgent(httpMethod,useragent);
421            setTimeout(client,timeout);
422            setCredentials(client,httpMethod,username,password);    
423            setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword);
424            setBody(httpMethod,body);
425            
426            
427            return HttpClientUtil.execute(client,httpMethod,true);
428             
429            }*/
430        
431        /*public static HttpMethod delete(URL url, String username, String password, int timeout, 
432                String charset, String useragent,
433                String proxyserver, int proxyport, String proxyuser, 
434                String proxypassword, Header[] headers) throws IOException {
435                    
436                    
437                    HttpClient client = new HttpClient();
438                    DeleteMethod httpMethod=new DeleteMethod(url.toExternalForm());
439            HostConfiguration config = client.getHostConfiguration();
440            
441            HttpState state = client.getState();
442            
443            setHeader(httpMethod,headers);
444            setContentType(httpMethod,charset);
445            setUserAgent(httpMethod,useragent);
446            setTimeout(client,timeout);
447            setCredentials(client,httpMethod,username,password);    
448            setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword);
449            
450            
451            return HttpClientUtil.execute(client,httpMethod,true);
452             
453            }*/
454    
455        /*public static HttpMethod head(URL url, String username, String password, int timeout, 
456                String charset, String useragent,
457                String proxyserver, int proxyport, String proxyuser, 
458                String proxypassword, Header[] headers) throws IOException {
459                    
460                    
461                    HttpClient client = new HttpClient();
462                    HeadMethod httpMethod=new HeadMethod(url.toExternalForm());
463            HostConfiguration config = client.getHostConfiguration();
464            
465            HttpState state = client.getState();
466            
467            setHeader(httpMethod,headers);
468            setContentType(httpMethod,charset);
469            setUserAgent(httpMethod,useragent);
470            setTimeout(client,timeout);
471            setCredentials(client,httpMethod,username,password);    
472            setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword);
473            
474            
475            return HttpClientUtil.execute(client,httpMethod,true);
476             
477            }*/
478    
479        
480    
481            
482    
483            /*public static RequestEntity toRequestEntity(Object value) throws PageException {
484            if(value instanceof RequestEntity) return (RequestEntity) value;
485            else if(value instanceof InputStream) {
486                            return new InputStreamRequestEntity((InputStream)value,"application/octet-stream");
487                    }
488                    else if(Decision.isCastableToBinary(value,false)){
489                            return new ByteArrayRequestEntity(Caster.toBinary(value));
490                    }
491                    else {
492                            return new StringRequestEntity(Caster.toString(value));
493                    }
494        }*/
495        
496            
497            public static URL removeRef(URL url) throws MalformedURLException{
498                    int port=url.getPort();
499                    if(port==80 && url.getProtocol().equalsIgnoreCase("http"))
500                            port=-1;
501                    else if(port==443 && url.getProtocol().equalsIgnoreCase("https"))
502                            port=-1;
503                    
504                    
505                    
506                    URL u=new URL(url.getProtocol(),url.getHost(),port,url.getFile());
507                    return u;
508            }
509            
510            public static String removeRef(String url) throws MalformedURLException{
511                    return removeRef(new URL(url)).toExternalForm();
512            }
513            
514                            
515    
516            /*public static URL toURL(HttpMethod httpMethod) {
517                    HostConfiguration config = httpMethod.getHostConfiguration();
518                    
519                    try {
520                            String qs = httpMethod.getQueryString();
521                            if(StringUtil.isEmpty(qs))
522                                    return new URL(config.getProtocol().getScheme(),config.getHost(),config.getPort(),httpMethod.getPath());
523                            return new URL(config.getProtocol().getScheme(),config.getHost(),config.getPort(),httpMethod.getPath()+"?"+qs);
524                    } catch (MalformedURLException e) {
525                            return null;
526                    }
527            }*/
528    
529            public static String optimizeRealPath(PageContext pc,String realPath) {
530                    int index;
531                    String requestURI=realPath,queryString=null;
532                    if((index=realPath.indexOf('?'))!=-1){
533                            requestURI=realPath.substring(0,index);
534                            queryString=realPath.substring(index+1);
535                    }
536                    PageSource ps = PageSourceImpl.best(((PageContextImpl)pc).getRelativePageSources(requestURI));
537                    requestURI=ps.getFullRealpath();
538                    if(queryString!=null) return requestURI+"?"+queryString;
539                    return requestURI;
540            }
541    
542            public static void forward(PageContext pc,String realPath) throws ServletException, IOException {
543                    ServletContext context = pc.getServletContext();
544                    realPath=HTTPUtil.optimizeRealPath(pc,realPath);
545                    
546                    try{
547                            pc.getHttpServletRequest().setAttribute("railo.forward.request_uri", realPath);
548                            
549                    RequestDispatcher disp = context.getRequestDispatcher(realPath);
550                    if(disp==null)
551                            throw new PageServletException(new ApplicationException("Page "+realPath+" not found"));
552                
553                    //populateRequestAttributes();
554                    disp.forward(removeWrap(pc.getHttpServletRequest()),pc.getHttpServletResponse());
555                    }
556            finally{
557                    ThreadLocalPageContext.register(pc);
558            }
559            }
560            
561            public static ServletRequest removeWrap(ServletRequest req) {
562                    while(req instanceof HTTPServletRequestWrap)
563                            return ((HTTPServletRequestWrap)req).getOriginalRequest();
564                    return req;
565            }
566            
567    
568            public static void include(PageContext pc,String realPath) throws ServletException,IOException  {
569                    include(pc, pc.getHttpServletRequest(),pc.getHttpServletResponse(),realPath);
570            }
571    
572            public static void include(PageContext pc,ServletRequest req, ServletResponse rsp, String realPath) throws ServletException,IOException  {
573                    realPath=optimizeRealPath(pc,realPath);
574                    boolean inline=HttpServletResponseWrap.get();
575                    //print.out(rsp+":"+pc.getResponse());
576                    RequestDispatcher disp = getRequestDispatcher(pc,realPath);
577                    
578                    if(inline)      {
579                            //RequestDispatcher disp = getRequestDispatcher(pc,realPath);
580                            disp.include(req,rsp);
581                            return;
582                    }
583                    
584                    try     {
585                            ByteArrayOutputStream baos=new ByteArrayOutputStream();
586                            HttpServletResponseWrap hsrw=new HttpServletResponseWrap(pc.getHttpServletResponse(),baos);
587                            HttpServletResponseWrap.set(true);
588                            
589                            //RequestDispatcher disp = getRequestDispatcher(pc,realPath);
590                            
591                    disp.include(req,hsrw);
592                    if(!hsrw.isCommitted())hsrw.flushBuffer();
593                    pc.write(IOUtil.toString(baos.toByteArray(), hsrw.getCharacterEncoding()));
594            }
595            finally{
596                    HttpServletResponseWrap.release();
597                    ThreadLocalPageContext.register(pc);
598            }
599            }
600    
601            private static RequestDispatcher getRequestDispatcher(PageContext pc,String realPath) throws PageServletException {
602                    RequestDispatcher disp = pc.getServletContext().getRequestDispatcher(realPath);
603            if(disp==null) throw new PageServletException(new ApplicationException("Page "+realPath+" not found"));
604            return disp;
605            }
606            
607            
608            // MUST create a copy from toURL and rename toURI and rewrite for URI, pherhaps it is possible to merge them somehow
609            public static String encode(String realpath) {
610            
611            
612                    int qIndex=realpath.indexOf('?');
613                    
614                    if(qIndex==-1) return realpath;
615                    
616                    String file=realpath.substring(0,qIndex);
617                    String query=realpath.substring(qIndex+1);
618                    int sIndex=query.indexOf('#');
619                    
620                    String anker=null;
621                    if(sIndex!=-1){
622                            //print.o(sIndex);
623                            anker=query.substring(sIndex+1);
624                            query=query.substring(0,sIndex);
625                    }
626                    
627                    StringBuilder res=new StringBuilder(file);
628            
629                    
630            // query
631            if(!StringUtil.isEmpty(query)){
632                    
633                    StringList list = ListUtil.toList(query, '&');
634                    String str;
635                    int index;
636                    char del='?';
637                    while(list.hasNext()){
638                            res.append(del);
639                            del='&';
640                            str=list.next();
641                            index=str.indexOf('=');
642                            if(index==-1)res.append(escapeQSValue(str));
643                            else {
644                                    res.append(escapeQSValue(str.substring(0,index)));
645                                    res.append('=');
646                                    res.append(escapeQSValue(str.substring(index+1)));
647                            }
648                    }       
649            }
650           
651            // anker
652            if(anker!=null) {
653                    res.append('#');
654                    res.append(escapeQSValue(anker));
655            }
656           
657            
658           return res.toString();                  
659        }
660    
661    
662            public static int getPort(URL url) {
663                    if(url.getPort()!=-1) return url.getPort();
664                    if("https".equalsIgnoreCase(url.getProtocol()))
665                            return 443;
666                    return 80;
667            }
668    
669            
670            /**
671             * return the length of a file defined by a url.
672             * @param dataUrl
673             * @return
674             * @throws IOException 
675             */
676            public static long length(URL url) throws IOException {
677                    HTTPResponse http = HTTPEngine.head(url, null, null, -1,HTTPEngine.MAX_REDIRECT,null, "Railo", null,null);
678                    return http.getContentLength(); 
679            }
680    
681            /*public static ContentType getContentType(HttpMethod http) {
682                    Header[] headers = http.getResponseHeaders();
683                    for(int i=0;i<headers.length;i++){
684                            if("Content-Type".equalsIgnoreCase(headers[i].getName())){
685                                    String[] mimeCharset = splitMimeTypeAndCharset(headers[i].getValue());
686                                    String[] typeSub = splitTypeAndSubType(mimeCharset[0]);
687                                    return new ContentTypeImpl(typeSub[0],typeSub[1],mimeCharset[1]);
688                            }
689                    }
690                    return null;
691            }*/
692            
693            
694    
695            public static Map<String, String> parseParameterList(String _str, boolean decode,String charset) {
696                    //return railo.commons.net.HTTPUtil.toURI(strUrl,port);
697                    Map<String,String> data=new HashMap<String, String>();
698                    StringList list = ListUtil.toList(_str, '&');
699            String str;
700            int index;
701            while(list.hasNext()){
702                    str=list.next();
703                    index=str.indexOf('=');
704                    if(index==-1){
705                            data.put(decode(str,decode), "");
706                    }
707                    else {
708                            data.put(
709                                            decode(str.substring(0,index),decode), 
710                                            decode(str.substring(index+1),decode));
711                    }
712            }       
713                    return data;
714            }
715    
716            private static String decode(String str, boolean encode) {
717                    // TODO Auto-generated method stub
718                    return str;
719            }
720            
721    
722            public static ContentType toContentType(String str, ContentType defaultValue) {
723                    if( StringUtil.isEmpty(str,true)) return defaultValue;
724                    String[] types=str.split(";");
725                    ContentType ct=null;
726                    if(types.length>0){
727                    ct=new ContentType(types[0]);
728                    if(types.length>1) {
729                        String tmp=types[types.length-1].trim();
730                        int index=tmp.indexOf("charset=");
731                        if(index!=-1) {
732                            ct.setCharset(StringUtil.removeQuotes(tmp.substring(index+8),true));
733                        }
734                    }
735            }
736            return ct;
737            }
738            
739            public static String[] splitMimeTypeAndCharset(String mimetype, String[] defaultValue) {
740                    if( StringUtil.isEmpty(mimetype,true)) return defaultValue;
741                    String[] types=mimetype.split(";");
742                    String[] rtn=new String[2];
743            
744            if(types.length>0){
745                    rtn[0]=types[0].trim();
746                    if(types.length>1) {
747                        String tmp=types[types.length-1].trim();
748                        int index=tmp.indexOf("charset=");
749                        if(index!=-1) {
750                            rtn[1]= StringUtil.removeQuotes(tmp.substring(index+8),true);
751                        }
752                    }
753            }
754            return rtn;
755            }
756            
757    
758            public static String[] splitTypeAndSubType(String mimetype) {
759                    String[] types=ListUtil.listToStringArray(mimetype, '/');
760                    String[] rtn=new String[2];
761            
762            if(types.length>0){
763                    rtn[0]=types[0].trim();
764                    if(types.length>1) {
765                            rtn[1]=types[1].trim();
766                    }
767            }
768            return rtn;
769            }
770    
771            public static boolean isTextMimeType(String mimetype) {
772                    if(mimetype==null)mimetype="";
773                    else mimetype=mimetype.trim().toLowerCase();
774                    return StringUtil.startsWithIgnoreCase(mimetype,"text")  || 
775            StringUtil.startsWithIgnoreCase(mimetype,"application/xml")  || 
776            StringUtil.startsWithIgnoreCase(mimetype,"application/atom+xml")  || 
777            StringUtil.startsWithIgnoreCase(mimetype,"application/xhtml")  ||  
778            StringUtil.startsWithIgnoreCase(mimetype,"application/json")  || 
779            StringUtil.startsWithIgnoreCase(mimetype,"message") || 
780            StringUtil.startsWithIgnoreCase(mimetype,"application/octet-stream") || 
781            StringUtil.indexOfIgnoreCase(mimetype, "xml")!=-1 || 
782            StringUtil.indexOfIgnoreCase(mimetype, "json")!=-1 || 
783            StringUtil.indexOfIgnoreCase(mimetype, "rss")!=-1 || 
784            StringUtil.indexOfIgnoreCase(mimetype, "atom")!=-1 || 
785            StringUtil.indexOfIgnoreCase(mimetype, "text")!=-1;
786                    
787                    // "application/x-www-form-urlencoded" ???
788            }
789            
790            public static boolean isTextMimeType(MimeType mimetype) {
791                    if(mimetype==null) return false;
792                    if(MimeType.APPLICATION_JSON.same(mimetype)) return true;
793                    if(MimeType.APPLICATION_PLAIN.same(mimetype)) return true;
794                    if(MimeType.APPLICATION_CFML.same(mimetype)) return true;
795                    if(MimeType.APPLICATION_WDDX.same(mimetype)) return true;
796                    if(MimeType.APPLICATION_XML.same(mimetype)) return true;
797                    
798                    return isTextMimeType(mimetype.toString());
799            }
800    
801            public static boolean isSecure(URL url) {
802                    return StringUtil.indexOfIgnoreCase(url.getProtocol(),"https")!=-1;
803            }
804    }