KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > dwrp > Batch


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.dwrp;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import javax.servlet.http.Cookie JavaDoc;
25 import javax.servlet.http.HttpServletRequest JavaDoc;
26
27 import org.directwebremoting.extend.Call;
28 import org.directwebremoting.extend.Calls;
29 import org.directwebremoting.extend.InboundContext;
30 import org.directwebremoting.extend.ServerException;
31 import org.directwebremoting.util.LocalUtil;
32 import org.directwebremoting.util.Logger;
33 import org.directwebremoting.util.Messages;
34
35 /**
36  * A container for all the by-products of an HttpRequest parse
37  * @author Joe Walker [joe at getahead dot ltd dot uk]
38  */

39 public class Batch
40 {
41     /**
42      * Parse an inbound request into a Calls object
43      * @param request The original browser's request
44      * @param crossDomainSessionSecurity Are we checking for CSRF attacks
45      * @param allowGetForSafariButMakeForgeryEasier Do we allow GET?
46      * @param sessionCookieName "JSESSIONID" unless it has been overridden
47      * @throws ServerException If reading from the request body stream fails
48      */

49     public Batch(HttpServletRequest JavaDoc request, boolean crossDomainSessionSecurity, boolean allowGetForSafariButMakeForgeryEasier, String JavaDoc sessionCookieName) throws ServerException
50     {
51         boolean isGet = request.getMethod().equals("GET");
52         if (isGet)
53         {
54             setAllParameters(ParseUtil.parseGet(request));
55         }
56         else
57         {
58             setAllParameters(ParseUtil.parsePost(request));
59         }
60
61         parseParameters();
62
63         if (!allowGetForSafariButMakeForgeryEasier && isGet)
64         {
65             log.error("GET is disallowed because it makes request forgery easier. See http://getahead.org/dwr/security/allowGetForSafariButMakeForgeryEasier for more details.");
66             throw new SecurityException JavaDoc("GET Disalowed");
67         }
68
69         if (crossDomainSessionSecurity)
70         {
71             checkNotCsrfAttack(request, sessionCookieName);
72         }
73     }
74
75     /**
76      * @return the allParameters
77      */

78     public Map JavaDoc getAllParameters()
79     {
80         return new HashMap JavaDoc(allParameters);
81     }
82
83     /**
84      * @param allParameters the allParameters to set
85      */

86     public void setAllParameters(Map JavaDoc allParameters)
87     {
88         this.allParameters = allParameters;
89     }
90
91     /**
92      * @return the inboundContexts
93      */

94     public List JavaDoc getInboundContexts()
95     {
96         return inboundContexts;
97     }
98
99     /**
100      * @param inboundContexts the inboundContexts to set
101      */

102     public void setInboundContexts(List JavaDoc inboundContexts)
103     {
104         this.inboundContexts = inboundContexts;
105     }
106
107     /**
108      * @return the spareParameters
109      */

110     public Map JavaDoc getSpareParameters()
111     {
112         return spareParameters;
113     }
114
115     /**
116      * @param spareParameters the spareParameters to set
117      */

118     public void setSpareParameters(Map JavaDoc spareParameters)
119     {
120         this.spareParameters = spareParameters;
121     }
122
123     /**
124      * @return the page
125      */

126     public String JavaDoc getPage()
127     {
128         return page;
129     }
130
131     /**
132      * @param page the page to set
133      */

134     public void setPage(String JavaDoc page)
135     {
136         this.page = page;
137     }
138
139     /**
140      * @return the scriptSessionId
141      */

142     public String JavaDoc getScriptSessionId()
143     {
144         return scriptSessionId;
145     }
146
147     /**
148      * @param scriptSessionId the scriptSessionId to set
149      */

150     public void setScriptSessionId(String JavaDoc scriptSessionId)
151     {
152         this.scriptSessionId = scriptSessionId;
153     }
154
155     /**
156      * @return the httpSessionId
157      */

158     public String JavaDoc getHttpSessionId()
159     {
160         return httpSessionId;
161     }
162
163     /**
164      * @param httpSessionId the httpSessionId to set
165      */

166     public void setHttpSessionId(String JavaDoc httpSessionId)
167     {
168         this.httpSessionId = httpSessionId;
169     }
170
171     /**
172      * @return the calls
173      */

174     public Calls getCalls()
175     {
176         return calls;
177     }
178
179     /**
180      * @param calls the calls to set
181      */

182     public void setCalls(Calls calls)
183     {
184         this.calls = calls;
185     }
186
187     /**
188      * Check that this request is not subject to a CSRF attack
189      * @param request The original browser's request
190      * @param sessionCookieName "JSESSIONID" unless it has been overridden
191      */

192     private void checkNotCsrfAttack(HttpServletRequest JavaDoc request, String JavaDoc sessionCookieName)
193     {
194         // A check to see that this isn't a csrf attack
195
// http://en.wikipedia.org/wiki/Cross-site_request_forgery
196
// http://www.tux.org/~peterw/csrf.txt
197
if (request.isRequestedSessionIdValid() && request.isRequestedSessionIdFromCookie())
198         {
199             String JavaDoc headerSessionId = request.getRequestedSessionId();
200             if (headerSessionId.length() > 0)
201             {
202                 String JavaDoc bodySessionId = getHttpSessionId();
203
204                 // Normal case; if same session cookie is supplied by DWR and
205
// in HTTP header then all is ok
206
if (headerSessionId.equals(bodySessionId))
207                 {
208                     return;
209                 }
210
211                 // Weblogic adds creation time to the end of the incoming
212
// session cookie string (even for request.getRequestedSessionId()).
213
// Use the raw cookie instead
214
Cookie JavaDoc[] cookies = request.getCookies();
215                 for (int i = 0; i < cookies.length; i++)
216                 {
217                     Cookie JavaDoc cookie = cookies[i];
218                     if (cookie.getName().equals(sessionCookieName) &&
219                             cookie.getValue().equals(bodySessionId))
220                     {
221                         return;
222                     }
223                 }
224
225                 // Otherwise error
226
log.error("A request has been denied as a potential CSRF attack.");
227                 throw new SecurityException JavaDoc("Session Error");
228             }
229         }
230     }
231
232     /**
233      * Fish out the important parameters
234      * @throws ServerException If the parsing of input parameter fails
235      */

236     protected void parseParameters() throws ServerException
237     {
238         Map JavaDoc paramMap = getAllParameters();
239         calls = new Calls();
240
241         // Work out how many calls are in this packet
242
String JavaDoc callStr = (String JavaDoc) paramMap.remove(ProtocolConstants.INBOUND_CALL_COUNT);
243         int callCount;
244         try
245         {
246             callCount = Integer.parseInt(callStr);
247         }
248         catch (NumberFormatException JavaDoc ex)
249         {
250             throw new ServerException(Messages.getString("BaseCallMarshaller.BadCallCount", callStr));
251         }
252
253         // Extract the ids, scriptnames and methodnames
254
for (int callNum = 0; callNum < callCount; callNum++)
255         {
256             Call call = new Call();
257             calls.addCall(call);
258
259             InboundContext inctx = new InboundContext();
260             inboundContexts.add(inctx);
261
262             String JavaDoc prefix = ProtocolConstants.INBOUND_CALLNUM_PREFIX + callNum + ProtocolConstants.INBOUND_CALLNUM_SUFFIX;
263
264             // The special values
265
call.setCallId((String JavaDoc) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_ID));
266             call.setScriptName((String JavaDoc) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_SCRIPTNAME));
267             call.setMethodName((String JavaDoc) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_METHODNAME));
268
269             // Look for parameters to this method
270
for (Iterator JavaDoc it = paramMap.entrySet().iterator(); it.hasNext();)
271             {
272                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
273                 String JavaDoc key = (String JavaDoc) entry.getKey();
274
275                 if (key.startsWith(prefix))
276                 {
277                     String JavaDoc data = (String JavaDoc) entry.getValue();
278                     String JavaDoc[] split = ParseUtil.splitInbound(data);
279
280                     String JavaDoc value = split[LocalUtil.INBOUND_INDEX_VALUE];
281                     String JavaDoc type = split[LocalUtil.INBOUND_INDEX_TYPE];
282                     inctx.createInboundVariable(callNum, key, type, value);
283                     it.remove();
284                 }
285             }
286         }
287
288         calls.setBatchId((String JavaDoc) paramMap.remove(ProtocolConstants.INBOUND_KEY_BATCHID));
289         httpSessionId = (String JavaDoc) paramMap.remove(ProtocolConstants.INBOUND_KEY_HTTP_SESSIONID);
290         scriptSessionId = (String JavaDoc) paramMap.remove(ProtocolConstants.INBOUND_KEY_SCRIPT_SESSIONID);
291         page = (String JavaDoc) paramMap.remove(ProtocolConstants.INBOUND_KEY_PAGE);
292
293         for (Iterator JavaDoc it = paramMap.entrySet().iterator(); it.hasNext();)
294         {
295             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
296             String JavaDoc key = (String JavaDoc) entry.getKey();
297             String JavaDoc value = (String JavaDoc) entry.getValue();
298             if (key.startsWith(ProtocolConstants.INBOUND_KEY_METADATA))
299             {
300                 spareParameters.put(key.substring(ProtocolConstants.INBOUND_KEY_METADATA.length()), value);
301             }
302         }
303     }
304
305     private List JavaDoc inboundContexts = new ArrayList JavaDoc();
306
307     private String JavaDoc scriptSessionId;
308
309     private String JavaDoc httpSessionId;
310
311     private String JavaDoc page;
312
313     private Calls calls;
314
315     private Map JavaDoc allParameters = new HashMap JavaDoc();
316
317     private Map JavaDoc spareParameters = new HashMap JavaDoc();
318
319     /**
320      * The log stream
321      */

322     protected static final Logger log = Logger.getLogger(Batch.class);
323 }
324
Popular Tags