Source Code Cross Referenced for Request.java in  » Web-Server » HttpdBase4J » net » homeip » donaldm » httpdbase4j » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » HttpdBase4J » net.homeip.donaldm.httpdbase4j 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:        HttpdBase4J: An embeddable Java web server framework that supports HTTP, HTTPS, 
003:        templated content and serving content from inside a jar or archive.
004:        Copyright (C) 2007 Donald Munro
005:
006:        This library is free software; you can redistribute it and/or
007:        modify it under the terms of the GNU Lesser General Public
008:        License as published by the Free Software Foundation; either
009:        version 2.1 of the License, or (at your option) any later version.
010:
011:        This library is distributed in the hope that it will be useful,
012:        but WITHOUT ANY WARRANTY; without even the implied warranty of
013:        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:        Lesser General Public License for more details.
015:
016:        You should have received a copy of the GNU Lesser General Public
017:        License along with this library; if not,see http://www.gnu.org/licenses/lgpl.txt
018:         */
019:
020:        package net.homeip.donaldm.httpdbase4j;
021:
022:        import com.sun.net.httpserver.Headers;
023:        import com.sun.net.httpserver.HttpExchange;
024:        import java.io.BufferedInputStream;
025:        import java.io.BufferedOutputStream;
026:        import java.io.File;
027:        import java.io.FileOutputStream;
028:        import java.io.IOException;
029:        import java.io.InputStream;
030:        import java.io.UnsupportedEncodingException;
031:        import java.net.URI;
032:        import java.net.URLDecoder;
033:        import java.util.ArrayList;
034:        import java.util.Arrays;
035:        import java.util.Date;
036:        import java.util.Iterator;
037:        import java.util.List;
038:        import java.util.Map;
039:        import java.util.Set;
040:        import java.util.StringTokenizer;
041:        import java.util.TreeSet;
042:        import java.util.regex.Matcher;
043:        import java.util.regex.Pattern;
044:        import java.util.zip.DeflaterOutputStream;
045:        import java.util.zip.GZIPOutputStream;
046:        import net.homeip.donaldm.httpdbase4j.Httpd.LogLevel;
047:        import org.mozilla.intl.chardet.nsDetector;
048:        import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
049:
050:        /**
051:         * Abstraction of an HTTP request
052:         * @see ArchiveRequest
053:         * @see FileRequest
054:         * @see CombinedRequest
055:         * @author Donald Munro
056:         */
057:        abstract public class Request implements  DirItemInterface
058:        //=======================================================
059:        {
060:            /**
061:             * Enumeration of HTTP methods
062:             */
063:            static public enum HTTP_METHOD {
064:                GET, HEAD, POST, PUT, DELETE, UNKNOWN
065:            }
066:
067:            /**
068:             The HttpExchange instance for this request.
069:             * @see com.sun.net.httpserver.HttpExchange
070:             */
071:            protected HttpExchange m_ex = null;
072:
073:            /**
074:             The Httpd instance within which the request occurred.
075:             @see net.homeip.donaldm.httpdbase4j.Httpd
076:             */
077:            protected Httpd m_httpd = null;
078:
079:            /**
080:             The request URI
081:             @see net.homeip.donaldm.httpdbase4j.Httpd
082:             */
083:            protected URI m_uri = null;
084:
085:            /**
086:             The request headers
087:             */
088:            protected CloneableHeaders m_requestHeaders = null;
089:
090:            /**
091:             The HTTP method
092:             */
093:            protected HTTP_METHOD m_method = null;
094:
095:            /**
096:             The HTTP method as a String
097:             */
098:            protected String m_methodString = null;
099:
100:            /**
101:             * Request URI path
102:             */
103:            protected String m_path = null;
104:
105:            /**
106:             * Request GET parameters 
107:             */
108:            protected CloneableHeaders m_getParameters = null;
109:
110:            /**
111:             * Request POST parameters 
112:             */
113:            protected CloneableHeaders m_postParameters = null;
114:
115:            protected String m_encoding = null;
116:
117:            protected long m_contentLength = Long.MIN_VALUE;
118:
119:            /**
120:             *  If true then the output will be compressed with gzip/deflate if the 
121:             *  client indicates that it supports compression.
122:             */
123:            protected boolean m_compress = true;
124:
125:            protected File m_compressedFile = null;
126:
127:            protected String m_eTag = null;
128:
129:            protected File m_cacheFile = null;
130:
131:            static protected File m_cacheDir;
132:
133:            static {
134:                File tmpDir = new File(System.getProperty("java.io.tmpdir"));
135:                if ((tmpDir.exists()) && (tmpDir.canWrite())) {
136:                    tmpDir = new File(tmpDir, "HttpdBase4J");
137:                    tmpDir.mkdirs();
138:                    if ((!tmpDir.exists()) || (!tmpDir.canWrite())) {
139:                        tmpDir = new File(System.getProperty("java.io.tmpdir"));
140:                        m_cacheDir = new File(tmpDir, "HttpdBase4J-Cache");
141:                    } else
142:                        m_cacheDir = new File(tmpDir, "Cache");
143:                    m_cacheDir.mkdirs();
144:                }
145:                if ((!m_cacheDir.exists()) || (!m_cacheDir.canWrite()))
146:                    m_cacheDir = null;
147:            }
148:
149:            private boolean m_isGet = false;
150:
151:            /**
152:             * Create a Request instance.
153:             * @param httpd The Httpd instance within which the request occurred.
154:             * @see net.homeip.donaldm.httpdbase4j.Httpd
155:             * @param ex The HttpExchange instance for this request.
156:             * @see com.sun.net.httpserver.HttpExchange
157:             * @throws UnsupportedEncodingException
158:             * @throws IOException
159:             */
160:            public Request(Httpd httpd, HttpExchange ex)
161:                    throws UnsupportedEncodingException, IOException
162:            //-----------------------------------------------------------------
163:            {
164:                m_httpd = httpd;
165:                m_ex = ex;
166:                m_methodString = ex.getRequestMethod().trim().toUpperCase();
167:                if (m_methodString.compareTo("GET") == 0)
168:                    m_method = HTTP_METHOD.GET;
169:                else if (m_methodString.compareTo("HEAD") == 0)
170:                    m_method = HTTP_METHOD.HEAD;
171:                else if (m_methodString.compareTo("POST") == 0)
172:                    m_method = HTTP_METHOD.POST;
173:                else if (m_methodString.compareTo("PUT") == 0)
174:                    m_method = HTTP_METHOD.PUT;
175:                else if (m_methodString.compareTo("DELETE") == 0)
176:                    m_method = HTTP_METHOD.DELETE;
177:                else
178:                    m_method = HTTP_METHOD.UNKNOWN;
179:                m_uri = ex.getRequestURI().normalize();
180:                m_path = m_uri.getPath();
181:                if (m_path.startsWith("/"))
182:                    m_path = m_path.substring(1);
183:                m_requestHeaders = new CloneableHeaders(ex.getRequestHeaders());
184:                m_getParameters = processParameters(m_uri.getQuery());
185:                String requestBody = getRequestString(ex.getRequestBody(),
186:                        m_requestHeaders);
187:                switch (m_method) {
188:                case GET:
189:                case HEAD:
190:                    m_isGet = true;
191:                    break;
192:
193:                default:
194:                    String contentType = getContentType();
195:                    if ((contentType != null)
196:                            && (contentType.trim().toLowerCase()
197:                                    .startsWith("application/x-www-form-urlencoded")))
198:                        ;
199:                    m_postParameters = processParameters(requestBody);
200:                }
201:
202:            }
203:
204:            public Request(Request request)
205:            //-----------------------------
206:            {
207:                m_httpd = request.m_httpd;
208:                m_ex = request.m_ex;
209:                m_method = request.m_method;
210:                m_methodString = request.m_methodString;
211:                m_uri = request.m_uri;
212:                m_path = request.m_path;
213:
214:                try {
215:                    m_requestHeaders = (CloneableHeaders) request.m_requestHeaders
216:                            .clone();
217:                    m_getParameters = (CloneableHeaders) request.m_getParameters
218:                            .clone();
219:                    switch (m_method) {
220:                    case GET:
221:                    case HEAD:
222:                        m_isGet = true;
223:                        break;
224:
225:                    default:
226:                        m_postParameters = (CloneableHeaders) request.m_postParameters
227:                                .clone();
228:                    }
229:                } catch (CloneNotSupportedException e) {
230:                    e.printStackTrace(System.err);
231:                }
232:            }
233:
234:            /**
235:             * Check whether the resource exists.
236:             * @return <i>true</i> if the resource exists, <i>false</i> if it does not
237:             */
238:            abstract public boolean exists();
239:
240:            /**
241:             * Check whether the resource is readable
242:             * @return <i>true</i> if the resource is readable, 
243:             * <i>false</i> if it is not.
244:             */
245:            abstract public boolean isReadable();
246:
247:            /**
248:             * Check whether the resource is a directory
249:             * @return <i>true</i> if the resource is a directory, 
250:             * <i>false</i> if it is not.
251:             */
252:            abstract public boolean isDirectory();
253:
254:            /**
255:             * Return the length of the resource.
256:             * @return the resource length or -1 if the length could not
257:             * be determined.
258:             */
259:            abstract public long getContentLength();
260:
261:            /**
262:             * Return the full path of the resource
263:             * @return the full path of the resource
264:             */
265:            abstract public String getAbsolutePath();
266:
267:            /**
268:             * Return the name of the resource (ie the final component in the path after 
269:             * the final /)
270:             * @return the name of the resource
271:             */
272:            abstract public String getName();
273:
274:            /**
275:             * Return the file extension of the resource (ie the text after the final . 
276:             * in the path)
277:             * @return the extension of the resource
278:             */
279:            abstract public String getExtension();
280:
281:            /**
282:             * Return the date of the resource
283:             * @return the name of the resource
284:             */
285:            abstract public Date getDate();
286:
287:            /**
288:             * Return the directory of the resource (ie all components of the path before 
289:             * the final /)
290:             * @return the path of the resource
291:             */
292:            abstract public String getDir();
293:
294:            /**
295:             * Return the directory of the resource (ie all components of the path before 
296:             * the final / as a Request contructed from this Request)
297:             * @return A Request for the directory containing this request
298:             */
299:            abstract public Request getDirRequest();
300:
301:            /**
302:             * Create a request from the current directory request combined with a 
303:             * file or directory in the current directory
304:             * 
305:             * @param name The name of a file or directory in the current request if the
306:             * current request is a directory
307:             * @return A new Request or null if request is not a directory
308:             */
309:            abstract public Request getChildRequest(String name);
310:
311:            /**
312:             * Return the handler for this request (a class implementing the 
313:             * HttpHandleable interface).
314:             * @return The request handler
315:             * @see net.homeip.donaldm.httpdbase4j.HttpHandleable
316:             */
317:            abstract protected HttpHandleable getHandler();
318:
319:            /**
320:             * Return the POST handler for this request (a class implementing the 
321:             * Postable interface).
322:             * @return The request POST handler or null if no POST handler is defined
323:             * @see Postable
324:             */
325:            abstract protected Postable getPostHandler();
326:
327:            /**
328:             * Return a list of files in a resource directory.
329:             * @param sortBy Specify how the files should be sorted. This is an instance
330:             * of DirItemInterface.SORTBY ie NAME, DATE or SIZE).
331:             * @return A TreeSet (sortable set) of DirItemInterface implementing
332:             * instances. Returns null if the resource is not a directory.
333:             * @see net.homeip.donaldm.httpdbase4j.DirItemInterface
334:             */
335:            abstract public TreeSet<DirItemInterface> getDirListFiles(
336:                    DirItemInterface.SORTBY sortBy);
337:
338:            /**
339:             * Return a list of directories in a resource directory.
340:             * @param sortBy Specify how the files should be sorted. This is an instance
341:             * of DirItemInterface.SORTBY ie NAME, DATE or SIZE).
342:             * @return A TreeSet (sortable set) of DirItemInterface implementing
343:             * instances. Returns null if the resource is not a directory.
344:             * @see net.homeip.donaldm.httpdbase4j.DirItemInterface
345:             */
346:            abstract public TreeSet<DirItemInterface> getDirListDirectories(
347:                    DirItemInterface.SORTBY sortBy);
348:
349:            /**
350:             * Return a stream of the resource contents. 
351:             * @param isEncoded If true will return a stream for the encoded (eg gzip or
352:             * deflate) resource or if cacheing is allowed for this request and the 
353:             * encoded resource is in the cache then a stream for the cached version. 
354:             * If false returns a stream for the unencoded resource. If there is no
355:             * encoding ie the client does not support encoding then both true and
356:             * false return a stream for the unencoded resource.
357:             * @return A stream of the resource contents. 
358:             */
359:            abstract public InputStream getStream(boolean isEncoded);
360:
361:            /**
362:             * @return A stream of the resource contents (encoded content is returned if
363:             * available). 
364:             */
365:
366:            /**
367:             * @return A stream of the resource contents (encoded content is returned if
368:             * available). 
369:             */
370:            public InputStream getStream()
371:            //----------------------------
372:            {
373:                return getStream(true);
374:            }
375:
376:            /**
377:             * @param refresh If true recalculate the tag hash even if it has already
378:             * been calculated, if false reuse the cached value
379:             * @return The ETag cacheing hash for this request
380:             */
381:            abstract public String getETag(boolean refresh);
382:
383:            public boolean checkClientCache()
384:            //-------------------------
385:            {
386:                if (!m_httpd.getCaching())
387:                    return false;
388:                String modDateStr = m_requestHeaders
389:                        .getFirst("If-Modified-Since");
390:                if (modDateStr != null) {
391:                    Date modDate = Http.getDate(modDateStr);
392:                    if (modDate != null) {
393:                        Date reqDate = getDate();
394:                        System.out.println(modDate.getTime() + " "
395:                                + reqDate.getTime());
396:                        if (reqDate != null)
397:                            if (modDate.after(reqDate))
398:                                return true;
399:                            else
400:                                return false;
401:                    }
402:                }
403:
404:                String clientEtag = m_requestHeaders.getFirst("If-None-Match");
405:                if (clientEtag != null) {
406:                    clientEtag = clientEtag.replaceAll("\"", "");
407:                    getETag(false);
408:                    if (m_eTag.trim().compareTo(clientEtag.trim()) == 0)
409:                        return true;
410:                }
411:
412:                return false;
413:            }
414:
415:            /**
416:             * @return The request URI
417:             */
418:            public URI getURI() {
419:                return m_uri;
420:            }
421:
422:            /**
423:             * @return true if the Request result should be cached (checks for
424:             * Cache-Control and Pragma:NoCache headers)
425:             */
426:            public boolean isCacheable()
427:            //--------------------------
428:            {
429:                List<String> pragmas = m_requestHeaders.get("Pragma");
430:                if (pragmas != null) {
431:                    for (Iterator<String> it = pragmas.iterator(); it.hasNext();) {
432:                        String s = it.next().trim();
433:                        if (s.compareToIgnoreCase("no-cache") == 0)
434:                            return false;
435:                    }
436:                }
437:                List<String> controls = m_requestHeaders.get("Cache-Control");
438:                if (controls != null) {
439:                    for (Iterator<String> it = controls.iterator(); it
440:                            .hasNext();) {
441:                        String control = it.next().trim();
442:                        if ((control != null)
443:                                && (control.compareToIgnoreCase("no-cache") == 0))
444:                            return false;
445:                        if ((control != null)
446:                                && (control.compareToIgnoreCase("private") == 0))
447:                            return false;
448:                    }
449:                }
450:                /*
451:                if ( (m_requestHeaders.containsKey("If-None-Match")) ||
452:                     (m_requestHeaders.containsKey("If-Modified-Since")) )
453:                   return true;      */
454:                return true;
455:            }
456:
457:            static private Pattern IE_PATTERN = Pattern
458:                    .compile("Mozilla/.*MSIE ([0-9]\\.[0-9]).*");
459:
460:            /**
461:             * Determine the compression encodings supported by the client.
462:             * @return A String array with the encodings accepted by the client, 
463:             * ordered by most desired encoding:
464:             * gzip = GZip encoded
465:             * deflate = Deflate encoded
466:             * txt = No compression
467:             */
468:            public String[] compressEncoding()
469:            //--------------------------------
470:            {
471:                String encoding = m_requestHeaders.getFirst("Accept-Encoding");
472:                if (encoding != null)
473:                    encoding = encoding.toLowerCase();
474:                String[] encodings = null;
475:                String agent = m_requestHeaders.getFirst("User-Agent");
476:                if ((agent != null)
477:                        && (agent.toLowerCase().indexOf("opera") < 0)) {
478:                    Matcher matcher = IE_PATTERN.matcher(agent);
479:                    String ver = null;
480:                    if (matcher.matches())
481:                        ver = matcher.group(1);
482:                    double version = 0;
483:                    if (ver != null) {
484:                        try {
485:                            version = Double.parseDouble(ver);
486:                        } catch (Exception e) {
487:                        }
488:                    }
489:                    if ((version < 6)
490:                            || ((version == 6) && (agent.toUpperCase().indexOf(
491:                                    "EV1") < 0)))
492:                        encoding = null;
493:                }
494:                if (encoding == null) {
495:                    encodings = new String[1];
496:                    encodings[0] = "txt";
497:                } else {
498:                    String[] encs = encoding.split(",");
499:                    encodings = new String[encs.length + 1];
500:                    System.arraycopy(encs, 0, encodings, 0, encs.length);
501:                    encodings[encs.length] = "txt";
502:                }
503:                return encodings;
504:            }
505:
506:            public boolean getContent(long id, HttpHandleable handler)
507:            //--------------------------------------------------------
508:            {
509:                m_compressedFile = m_cacheFile = null;
510:                m_encoding = null;
511:                String[] encodings = compressEncoding();
512:                if ((encodings.length == 1)
513:                        && (encodings[0].compareTo("txt") == 0))
514:                    return true;
515:
516:                try {
517:                    if (m_cacheDir != null)
518:                        m_compressedFile = File.createTempFile("content",
519:                                ".tmp", m_cacheDir);
520:                } catch (Exception e) {
521:                    m_compressedFile = null;
522:                }
523:                if (m_compressedFile == null)
524:                    return true;
525:                ;
526:                BufferedInputStream bis = null;
527:                BufferedOutputStream bos = null;
528:                byte[] buffer = new byte[4096];
529:                try {
530:                    for (int i = 0; i < encodings.length; i++) {
531:                        m_encoding = encodings[i];
532:                        m_cacheFile = new File(m_cacheDir,
533:                                ((m_eTag == null) ? Long.toString(id) : m_eTag)
534:                                        + "." + m_encoding);
535:                        if (handler.onIsCacheable(-1, m_ex, this )) {
536:                            File f = handler.onGetCachedFile(id, m_ex, this );
537:                            if ((f == null) && (m_cacheFile.exists())) {
538:                                m_compressedFile = m_cacheFile;
539:                                break;
540:                            }
541:                            if (f != null) {
542:                                m_compressedFile = f;
543:                                break;
544:                            }
545:                        }
546:                        if (bis == null)
547:                            bis = new BufferedInputStream(getStream(false));
548:                        try {
549:                            if ((m_encoding.compareTo("gzip") == 0)
550:                                    && (m_compressedFile != null)) {
551:                                bos = new BufferedOutputStream(
552:                                        new GZIPOutputStream(
553:                                                new FileOutputStream(
554:                                                        m_compressedFile)));
555:                                while (true) {
556:                                    int cb = bis.read(buffer);
557:                                    if (cb == -1)
558:                                        break;
559:                                    bos.write(buffer, 0, cb);
560:                                }
561:                                bos.close();
562:                                bos = null;
563:                                break;
564:                            }
565:
566:                            if ((m_encoding.compareTo("deflate") == 0)
567:                                    && (m_compressedFile != null)) {
568:                                bos = new BufferedOutputStream(
569:                                        new DeflaterOutputStream(
570:                                                new FileOutputStream(
571:                                                        m_compressedFile)));
572:                                while (true) {
573:                                    int cb = bis.read(buffer);
574:                                    if (cb == -1)
575:                                        break;
576:                                    bos.write(buffer, 0, cb);
577:                                }
578:                                bos.close();
579:                                bos = null;
580:                                break;
581:                            }
582:                            if ((m_encoding.compareTo("txt") == 0)
583:                                    || (m_compressedFile == null)) {
584:                                m_compressedFile = m_cacheFile = null;
585:                                return true;
586:                            }
587:                        } catch (IOException e) {
588:                            m_compressedFile = null;
589:                        }
590:                        m_cacheFile = null;
591:                    }
592:                } catch (Exception e) {
593:                    Httpd.Log(Httpd.LogLevel.ERROR, "Request content encoding",
594:                            e);
595:                }
596:
597:                finally {
598:                    if (bis != null)
599:                        try {
600:                            bis.close();
601:                        } catch (Exception e) {
602:                        }
603:                    if (bos != null)
604:                        try {
605:                            bos.close();
606:                        } catch (Exception e) {
607:                        }
608:                }
609:                if (handler.onIsCacheable(-1, m_ex, this )) {
610:                    if (m_cacheFile == null)
611:                        return false;
612:                    m_cacheFile.delete();
613:                    m_compressedFile.renameTo(m_cacheFile);
614:                    m_compressedFile = null;
615:                } else {
616:                    m_cacheFile = m_compressedFile;
617:                    //m_cacheFile.deleteOnExit();
618:                }
619:                return true;
620:            }
621:
622:            /**
623:             * Return whether this request is an HTTP GET or HEAD
624:             * @return true if this request is an HTTP GET or HEAD
625:             */
626:            public boolean isGETorHEAD() {
627:                return m_isGet;
628:            }
629:
630:            /**
631:             * @return The request method as an HTTP_METHOD enumeration
632:             */
633:            public HTTP_METHOD getMethod() {
634:                return m_method;
635:            }
636:
637:            /**
638:             * @return The request method as a String
639:             */
640:            public String getMethodString() {
641:                return m_methodString;
642:            }
643:
644:            /**
645:             * @return The request URI path 
646:             */
647:            public String getPath() {
648:                return m_path;
649:            }
650:
651:            /**
652:             * @return The request GET parameters
653:             */
654:            public CloneableHeaders getGETParameters() {
655:                return m_getParameters;
656:            }
657:
658:            /**
659:             * @return The request POST parameters
660:             */
661:            public CloneableHeaders getPOSTParameters() {
662:                return m_postParameters;
663:            }
664:
665:            /**
666:             * @return The content type of the request 
667:             */
668:            public String getContentType()
669:            //----------------------------
670:            {
671:                return m_requestHeaders.getFirst("Content-Type");
672:            }
673:
674:            protected byte[] m_postData = null;
675:
676:            /**
677:             * Get request contents (eg a POST request contents) as a String
678:             * @param is InputStream of request contents
679:             * @param headers Request headers
680:             * @return A String representation of the request contents or an empty string
681:             * @throws IOException
682:             * <b>Note:</b>Uses jchardet for charset detection (http://jchardet.sourceforge.net/)
683:             */
684:            protected String getRequestString(InputStream is, Headers headers)
685:                    throws IOException
686:            //-----------------------------------------------------------
687:            {
688:                if (m_postData == null)
689:                    m_postData = getRequestBytes(is, headers);
690:                if (m_postData == null)
691:                    return "";
692:                int len = m_postData.length;
693:                nsDetector charSetDetector = new nsDetector();
694:                final ArrayList<String> charsets = new ArrayList<String>();
695:                charSetDetector.Init(new nsICharsetDetectionObserver() {
696:                    @Override
697:                    public void Notify(String charset) {
698:                        charsets.add(charset);
699:                    }
700:                });
701:                charSetDetector.DoIt(m_postData, len, false);
702:                boolean isAscii = charSetDetector.isAscii(m_postData, len);
703:                charSetDetector.DataEnd();
704:
705:                if (isAscii)
706:                    return new String(m_postData);
707:                else if (charsets.size() <= 0)
708:                    return new String(m_postData);
709:                else {
710:                    for (int i = 0; i < charsets.size(); i++) {
711:                        try {
712:                            return new String(m_postData, charsets.get(i));
713:                        } catch (UnsupportedEncodingException e) {
714:                            Httpd.Log(LogLevel.INFO,
715:                                    "Could not create a String with "
716:                                            + " charset " + charsets.get(i), e);
717:                            continue;
718:                        } catch (Exception e) {
719:                            Httpd
720:                                    .Log(
721:                                            LogLevel.ERROR,
722:                                            "Error decoding request body. Could"
723:                                                    + "not create a String with charset "
724:                                                    + charsets.get(i), e);
725:                        }
726:                    }
727:                }
728:                return new String(m_postData);
729:            }
730:
731:            /**
732:             * Get request contents (eg a POST request contents) into a byte array.
733:             * @param is InputStream of request contents
734:             * @param headers Request headers
735:             * @return An array of bytes of the request contents or null 
736:             * @throws IOException
737:             * <b>Note:</b>Uses jchardet for charset detection (http://jchardet.sourceforge.net/)
738:             */
739:            protected byte[] getRequestBytes(InputStream is, Headers headers)
740:                    throws IOException
741:            //-----------------------------------------------------------
742:            {
743:                String contentLen = headers.getFirst("Content-Length");
744:                if (contentLen == null)
745:                    return null;
746:                int len = -1;
747:                try {
748:                    len = Integer.parseInt(contentLen);
749:                } catch (Exception e) {
750:                    len = -1;
751:                }
752:                if (len <= 0)
753:                    return null;
754:
755:                byte data[] = null;
756:                byte[] ret = data = new byte[len];
757:                int l = Http.readStream(is, data, len);
758:                if ((l >= 0) && (l != len))
759:                    ret = Arrays.copyOf(data, l);
760:                return ret;
761:            }
762:
763:            /**
764:             * Parses parameters in the form key=value&key2=value2)
765:             * @param queryString
766:             * @return A key-value Map of the parameters 
767:             * @throws UnsupportedEncodingException
768:             */
769:            protected CloneableHeaders processParameters(String queryString)
770:                    throws UnsupportedEncodingException
771:            //--------------------------------------------------------------------
772:            {
773:                CloneableHeaders parameters = new CloneableHeaders();
774:                if (queryString == null)
775:                    return parameters;
776:                queryString = queryString.replace('+', ' ');
777:                StringTokenizer st = new StringTokenizer(queryString, "&");
778:                while (st.hasMoreTokens()) {
779:                    String field = st.nextToken();
780:                    String k = null, v = "";
781:                    int index = field.indexOf('=');
782:                    if (index > 0) {
783:                        k = URLDecoder.decode(field.substring(0, index),
784:                                "UTF-8");
785:                        v = URLDecoder.decode(field.substring(index + 1),
786:                                "UTF-8").trim();
787:                        if (v.startsWith("\""))
788:                            v = v.substring(1);
789:                        if (v.endsWith("\""))
790:                            v = v.substring(0, v.length() - 1);
791:                    } else
792:                        k = URLDecoder.decode(field, "UTF-8");
793:                    k = k.toLowerCase();
794:                    parameters.add(k, v);
795:                }
796:                return parameters;
797:            }
798:
799:            /**
800:             * Implementation of Cloneable interface for Request
801:             * @return The cloned Request
802:             */
803:            public Object clone() throws CloneNotSupportedException
804:            //-----------------------------------------------------
805:            {
806:                Request klone = (Request) super .clone();
807:
808:                klone.m_ex = m_ex;
809:                klone.m_httpd = m_httpd;
810:                klone.m_requestHeaders = (CloneableHeaders) m_requestHeaders
811:                        .clone();
812:                klone.m_method = m_method;
813:                klone.m_getParameters = (CloneableHeaders) m_getParameters
814:                        .clone();
815:                klone.m_postParameters = (CloneableHeaders) m_postParameters
816:                        .clone();
817:                return klone;
818:            }
819:
820:            private void _appendParams(CloneableHeaders m, StringBuffer sb)
821:            //-------------------------------------------------------------
822:            {
823:                if (m == null) {
824:                    sb.append(Httpd.EOL);
825:                    return;
826:                }
827:                Set<Map.Entry<String, List<String>>> headers = m.entrySet();
828:                for (Iterator<Map.Entry<String, List<String>>> i = headers
829:                        .iterator(); i.hasNext();) {
830:                    Map.Entry<String, List<String>> e = i.next();
831:                    sb.append(e.getKey() + ": ");
832:                    List<String> hv = e.getValue();
833:                    for (Iterator<String> j = hv.iterator(); j.hasNext();)
834:                        sb.append(j.next() + " ");
835:                    sb.append(Httpd.EOL);
836:                }
837:            }
838:
839:            private Object nullv(Object o) {
840:                if (o == null)
841:                    return "";
842:                return o;
843:            }
844:
845:            @Override
846:            public String toString()
847:            //----------------------
848:            {
849:                StringBuffer sb = new StringBuffer();
850:                sb.append("m_path: ");
851:                sb.append(nullv(m_path));
852:                sb.append(Httpd.EOL);
853:                sb.append("m_methodString: ");
854:                sb.append(nullv(m_methodString));
855:                sb.append(Httpd.EOL);
856:                sb.append("m_encoding: ");
857:                sb.append(nullv(m_encoding));
858:                sb.append(Httpd.EOL);
859:                sb.append("m_cacheDir: ");
860:                sb.append(nullv(m_cacheDir));
861:                sb.append(Httpd.EOL);
862:                sb.append("m_cacheFile: ");
863:                sb.append(nullv(m_cacheFile));
864:                sb.append(Httpd.EOL);
865:                sb.append("m_contentLength: ");
866:                sb.append(m_contentLength);
867:                sb.append(Httpd.EOL);
868:                sb.append("Exchange:");
869:                sb.append(Httpd.EOL);
870:                if (m_ex != null)
871:                    sb.append(Http.strExchange(m_ex));
872:                sb.append("GET Parameters:");
873:                sb.append(Httpd.EOL);
874:                _appendParams(m_getParameters, sb);
875:                sb.append("POST Parameters:");
876:                sb.append(Httpd.EOL);
877:                _appendParams(m_postParameters, sb);
878:
879:                return super .toString() + sb.toString();
880:            }
881:
882:            protected void finalize() throws Throwable
883:            //----------------------------------------
884:            {
885:                if ((m_cacheFile == m_compressedFile) && (m_cacheFile != null))
886:                    m_cacheFile.delete();
887:            }
888:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.