1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
| package org.w3c.jigsaw.frames ;
import java.io.* ;
import java.util.*;
import org.w3c.tools.resources.*;
import org.w3c.jigsaw.forms.*;
import org.w3c.www.mime.* ;
import org.w3c.www.http.* ;
import org.w3c.jigsaw.http.* ;
import org.w3c.jigsaw.html.HtmlGenerator ;
/**
* Handle POST.
*/
public class PostableFrame extends HTTPFrame {
private static HttpTokenList _post_allowed = null;
private static HttpTokenList _put_allowed = null;
static {
String post_allowed[] = { "GET", "HEAD", "OPTIONS", "POST", "TRACE" } ;
_post_allowed = HttpFactory.makeStringList(post_allowed);
String put_allowed[] = { "GET", "HEAD", "OPTIONS", "PUT",
"POST", "TRACE" } ;
_put_allowed = HttpFactory.makeStringList(put_allowed);
}
private static MimeType type = MimeType.APPLICATION_X_WWW_FORM_URLENCODED ;
/**
* Attribute index - Should we override form values when multiple ?
*/
protected static int ATTR_OVERIDE = -1 ;
/**
* Attribute index - Should we silently convert GET to POST methods ?
*/
protected static int ATTR_CONVERT_GET = -1 ;
static {
Attribute a = null ;
Class cls = null ;
try {
cls = Class.forName("org.w3c.jigsaw.frames.PostableFrame") ;
} catch (Exception ex) {
ex.printStackTrace() ;
System.exit(1) ;
}
// The override attribute:
a = new BooleanAttribute("override",
Boolean.FALSE,
Attribute.EDITABLE);
ATTR_OVERIDE = AttributeRegistry.registerAttribute(cls, a) ;
// The convert get attribute:
a = new BooleanAttribute("convert-get",
Boolean.TRUE,
Attribute.EDITABLE) ;
ATTR_CONVERT_GET = AttributeRegistry.registerAttribute(cls, a) ;
}
/**
* Get the 'convert GET to POST' flag.
*/
public boolean getConvertGetFlag() {
return getBoolean(ATTR_CONVERT_GET, false) ;
}
/**
* Get the 'override multiple form field value' flag.
*/
public boolean getOverrideFlag() {
return getBoolean(ATTR_OVERIDE, true) ;
}
/**
* Catch setValue, to maintain cached header values correctness.
* @param idx The index of the attribute to be set.
* @param value The new value for the attribute.
*/
public synchronized void setValue(int idx, Object value) {
super.setValue(idx, value);
if (idx == ATTR_PUTABLE) {
if (value == Boolean.TRUE)
allowed = _put_allowed;
else
allowed = _post_allowed;
}
}
/**
* Get this resource body.
* If we are allowed to convert GET requests to POST, than we first
* check to see if there is some search string in the request, and continue
* with normal POST request processing.
* <p>If there is no search string, or if we are not allowed to convert
* GETs to POSTs, than we just invoke our <code>super</code> method,
* which will perform the appropriate job.
* @param request The request to handle.
* @exception ProtocolException If request couldn't be processed.
*/
public Reply get (Request request)
throws ProtocolException, NotAProtocolException
{
// Check if we should handle it (is it a POST disguised in GET ?)
if ((! getConvertGetFlag()) || ( ! request.hasState("query")))
return super.get (request) ;
// Get the request entity, and decode it:
String query = request.getQueryString() ;
InputStream in = new StringBufferInputStream(query) ;
URLDecoder d = new URLDecoder (in, getOverrideFlag()) ;
try {
d.parse () ;
} catch (URLDecoderException e) {
Reply error = request.makeReply(HTTP.BAD_REQUEST) ;
error.setContent("Invalid request:unable to decode form data.");
throw new HTTPException (error) ;
} catch (IOException e) {
Reply error = request.makeReply(HTTP.BAD_REQUEST) ;
error.setContent("Invalid request: unable to read form data.");
throw new HTTPException (error) ;
}
return handle (request, d) ;
}
public Reply post (Request request)
throws ProtocolException, NotAProtocolException
{
// Check that we are dealing with an application/x-www-form-urlencoded:
if ((! request.hasContentType())
|| (type.match(request.getContentType()) < 0) ) {
Reply error = request.makeReply(HTTP.UNSUPPORTED_MEDIA_TYPE) ;
error.setContent("Invalid request content type.");
throw new HTTPException (error) ;
}
// Get and decode the request entity:
URLDecoder dec = null;
try {
InputStream in = request.getInputStream() ;
// Notify the client that we are willing to continue processing:
Client client = request.getClient();
if ( client != null )
client.sendContinue();
dec = new URLDecoder (in, getOverrideFlag()) ;
dec.parse () ;
} catch (URLDecoderException e) {
Reply error = request.makeReply(HTTP.BAD_REQUEST) ;
error.setContent("Invalid request: unable to decode form data.") ;
throw new HTTPException (error) ;
} catch (IOException ex) {
Reply error = request.makeReply(HTTP.BAD_REQUEST) ;
error.setContent("Invalid request: unable to read form data.") ;
throw new ClientException(request.getClient(), ex) ;
}
// Handle the stuff:
return handle (request, dec) ;
}
/**
* Handle the form submission, after posted data parsing.
* <p>This method ought to be abstract, but for reasonable reason, it
* will just dump (parsed) the form content back to the client, so that it
* can be used for debugging.
* @param request The request proper.
* @param data The parsed data content.
* @exception ProtocolException If form data processing failed.
* @see org.w3c.jigsaw.forms.URLDecoder
*/
public Reply handle (Request request, URLDecoder data)
throws ProtocolException
{
// Now we just dump back the variables we got:
Enumeration e = data.keys() ;
HtmlGenerator g = new HtmlGenerator ("Form decoded values") ;
g.append ("<p>List of variables and values:</p><ul>") ;
while ( e.hasMoreElements () ) {
String name = (String) e.nextElement() ;
g.append ("<li><em>"+
name+"</em> = <b>"+
data.getValue(name)+
"</b></li>");
}
g.append ("</ul>") ;
Reply reply = request.makeReply(HTTP.OK) ;
reply.setStream (g) ;
return reply ;
}
} |