KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Request


1 /*
2  * @(#)Request.java 1.3 05/11/17
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 import java.net.*;
38 import java.nio.*;
39 import java.nio.charset.*;
40 import java.util.regex.*;
41
42 /**
43  * An encapsulation of the request received.
44  * <P>
45  * The static method parse() is responsible for creating this
46  * object.
47  *
48  * @author Mark Reinhold
49  * @author Brad R. Wetmore
50  * @version 1.3, 05/11/17
51  */

52 class Request {
53
54     /**
55      * A helper class for parsing HTTP command actions.
56      */

57     static class Action {
58
59     private String JavaDoc name;
60     private Action(String JavaDoc name) { this.name = name; }
61     public String JavaDoc toString() { return name; }
62
63     static Action GET = new Action("GET");
64     static Action PUT = new Action("PUT");
65     static Action POST = new Action("POST");
66     static Action HEAD = new Action("HEAD");
67
68     static Action parse(String JavaDoc s) {
69         if (s.equals("GET"))
70         return GET;
71         if (s.equals("PUT"))
72         return PUT;
73         if (s.equals("POST"))
74         return POST;
75         if (s.equals("HEAD"))
76         return HEAD;
77         throw new IllegalArgumentException JavaDoc(s);
78     }
79     }
80
81     private Action action;
82     private String JavaDoc version;
83     private URI uri;
84
85     Action action() { return action; }
86     String JavaDoc version() { return version; }
87     URI uri() { return uri; }
88
89     private Request(Action a, String JavaDoc v, URI u) {
90     action = a;
91     version = v;
92     uri = u;
93     }
94
95     public String JavaDoc toString() {
96     return (action + " " + version + " " + uri);
97     }
98
99     static boolean isComplete(ByteBuffer bb) {
100     int p = bb.position() - 4;
101     if (p < 0)
102         return false;
103     return (((bb.get(p + 0) == '\r') &&
104          (bb.get(p + 1) == '\n') &&
105          (bb.get(p + 2) == '\r') &&
106          (bb.get(p + 3) == '\n')));
107     }
108
109     private static Charset ascii = Charset.forName("US-ASCII");
110
111     /*
112      * The expected message format is first compiled into a pattern,
113      * and is then compared against the inbound character buffer to
114      * determine if there is a match. This convienently tokenizes
115      * our request into usable pieces.
116      *
117      * This uses Matcher "expression capture groups" to tokenize
118      * requests like:
119      *
120      * GET /dir/file HTTP/1.1
121      * Host: hostname
122      *
123      * into:
124      *
125      * group[1] = "GET"
126      * group[2] = "/dir/file"
127      * group[3] = "1.1"
128      * group[4] = "hostname"
129      *
130      * The text in between the parens are used to captured the regexp text.
131      */

132     private static Pattern requestPattern
133     = Pattern.compile("\\A([A-Z]+) +([^ ]+) +HTTP/([0-9\\.]+)$"
134               + ".*^Host: ([^ ]+)$.*\r\n\r\n\\z",
135               Pattern.MULTILINE | Pattern.DOTALL);
136
137     static Request parse(ByteBuffer bb) throws MalformedRequestException {
138
139     CharBuffer cb = ascii.decode(bb);
140     Matcher m = requestPattern.matcher(cb);
141     if (!m.matches())
142         throw new MalformedRequestException();
143     Action a;
144     try {
145         a = Action.parse(m.group(1));
146     } catch (IllegalArgumentException JavaDoc x) {
147         throw new MalformedRequestException();
148     }
149     URI u;
150     try {
151         u = new URI("http://"
152             + m.group(4)
153             + m.group(2));
154     } catch (URISyntaxException x) {
155         throw new MalformedRequestException();
156     }
157     return new Request(a, m.group(3), u);
158     }
159 }
160
Popular Tags