Package muntjac :: Package terminal :: Package gwt :: Package server :: Module communication_manager
[hide private]
[frames] | no frames]

Source Code for Module muntjac.terminal.gwt.server.communication_manager

  1  # Copyright (C) 2012 Vaadin Ltd.  
  2  # Copyright (C) 2012 Richard Lincoln 
  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  """Processes changes and paints for single application instance.""" 
 17   
 18  import uuid 
 19   
 20  from warnings import warn 
 21   
 22  from muntjac.terminal.gwt.server.abstract_communication_manager import \ 
 23      AbstractCommunicationManager, ICallback, IRequest, IResponse, \ 
 24      InvalidUIDLSecurityKeyException, ISession 
 25   
 26  from muntjac.terminal.gwt.server.abstract_application_servlet import \ 
 27      AbstractApplicationServlet 
 28   
 29   
30 -class CommunicationManager(AbstractCommunicationManager):
31 """Application manager processes changes and paints for single application 32 instance. 33 34 This class handles applications running as servlets. 35 36 @see: L{AbstractCommunicationManager} 37 @author: Vaadin Ltd. 38 @author: Richard Lincoln 39 @version: 1.1.2 40 """ 41
42 - def __init__(self, application, applicationServlet=None):
43 """@deprecated: use L{CommunicationManager} instead 44 """ 45 if applicationServlet is not None: 46 warn("deprecated", DeprecationWarning) 47 48 super(CommunicationManager, self).__init__(application) 49 50 self._pidToNameToStreamVariable = None 51 self._streamVariableToSeckey = None
52 53
54 - def handleFileUpload(self, request, response, applicationServlet):
55 """Handles file upload request submitted via Upload component. 56 57 @see: L{getStreamVariableTargetUrl} 58 @raise L{IOException}: 59 @raise L{InvalidUIDLSecurityKeyException}: 60 """ 61 # URI pattern: APP/UPLOAD/[PID]/[NAME]/[SECKEY] See #createReceiverUrl 62 63 pathInfo = applicationServlet.getPathInfo(request) 64 # strip away part until the data we are interested starts 65 startOfData = \ 66 pathInfo.find(AbstractApplicationServlet.UPLOAD_URL_PREFIX) \ 67 + len(AbstractApplicationServlet.UPLOAD_URL_PREFIX) 68 uppUri = pathInfo[startOfData:] 69 parts = uppUri.split('/', 3) # 0 = pid, 1= name, 2 = sec key 70 variableName = parts[1] 71 paintableId = parts[0] 72 73 streamVariable = self._pidToNameToStreamVariable.get( 74 paintableId).get(variableName) 75 secKey = self._streamVariableToSeckey.get(streamVariable) 76 if secKey == parts[2]: 77 78 source = self.getVariableOwner(paintableId) 79 contentType = applicationServlet.getContentType(request) 80 if 'boundary' in applicationServlet.getContentType(request): 81 # Multipart requests contain boundary string 82 self.doHandleSimpleMultipartFileUpload( 83 HttpServletRequestWrapper(request, 84 applicationServlet), 85 HttpServletResponseWrapper(response, 86 applicationServlet), 87 streamVariable, 88 variableName, 89 source, 90 contentType.split('boundary=')[1]) 91 else: 92 # if boundary string does not exist, the posted file is from 93 # XHR2.post(File) 94 self.doHandleXhrFilePost( 95 HttpServletRequestWrapper(request, 96 applicationServlet), 97 HttpServletResponseWrapper(response, 98 applicationServlet), 99 streamVariable, 100 variableName, 101 source, 102 applicationServlet.getContentType(request)) 103 else: 104 raise InvalidUIDLSecurityKeyException, \ 105 'Security key in upload post did not match!'
106 107
108 - def handleUidlRequest(self, request, response, applicationServlet, window):
109 """Handles UIDL request. 110 111 @param request: 112 @param response: 113 @param applicationServlet: 114 @param window: 115 target window of the UIDL request, can be null if window 116 not found 117 @raise IOException: 118 @raise ServletException: 119 """ 120 self.doHandleUidlRequest( 121 HttpServletRequestWrapper(request, applicationServlet), 122 HttpServletResponseWrapper(response, applicationServlet), 123 AbstractApplicationServletWrapper(applicationServlet), 124 window)
125 126
127 - def getApplicationWindow(self, request, applicationServlet, 128 application, assumedWindow):
129 """Gets the existing application or creates a new one. Get a window 130 within an application based on the requested URI. 131 132 @param request: 133 the HTTP Request. 134 @param application: 135 the Application to query for window. 136 @param assumedWindow: 137 if the window has been already resolved once, this 138 parameter must contain the window. 139 @return: Window matching the given URI or null if not found. 140 @raise ServletException: 141 if an exception has occurred that interferes with the 142 servlet's normal operation. 143 """ 144 return self.doGetApplicationWindow( 145 HttpServletRequestWrapper(request, applicationServlet), 146 AbstractApplicationServletWrapper(applicationServlet), 147 application, 148 assumedWindow)
149 150
151 - def handleURI(self, window, request, response, applicationServlet):
152 """Calls the Window URI handler for a request and returns the 153 L{DownloadStream} returned by the handler. 154 155 If the window is the main window of an application, the deprecated 156 L{Application.handleURI} is called first to handle 157 L{ApplicationResource}s and the window handler is only called if 158 it returns C{None}. 159 160 @see: L{AbstractCommunicationManager.handleURI} 161 """ 162 return AbstractCommunicationManager.handleURI(self, window, 163 HttpServletRequestWrapper(request, applicationServlet), 164 HttpServletResponseWrapper(response, applicationServlet), 165 AbstractApplicationServletWrapper(applicationServlet))
166 167
168 - def unregisterPaintable(self, p):
169 # Cleanup possible receivers 170 if self._pidToNameToStreamVariable is not None: 171 removed = self._pidToNameToStreamVariable.pop( 172 self.getPaintableId(p), None) 173 if removed is not None: 174 self._streamVariableToSeckey.pop(removed, None) 175 176 super(CommunicationManager, self).unregisterPaintable(p)
177 178
179 - def getStreamVariableTargetUrl(self, owner, name, value):
180 # We will use the same APP/* URI space as ApplicationResources but 181 # prefix url with UPLOAD 182 # 183 # eg. APP/UPLOAD/[PID]/[NAME]/[SECKEY] 184 # 185 # SECKEY is created on each paint to make URL's unpredictable (to 186 # prevent CSRF attacks). 187 # 188 # NAME and PID from URI forms a key to fetch StreamVariable when 189 # handling post 190 paintableId = self.getPaintableId(owner) 191 key = paintableId + '/' + name 192 193 if self._pidToNameToStreamVariable is None: 194 self._pidToNameToStreamVariable = dict() 195 196 nameToStreamVariable = self._pidToNameToStreamVariable.get(paintableId) 197 if nameToStreamVariable is None: 198 nameToStreamVariable = dict() 199 self._pidToNameToStreamVariable[paintableId] = nameToStreamVariable 200 nameToStreamVariable[name] = value 201 202 if self._streamVariableToSeckey is None: 203 self._streamVariableToSeckey = dict() 204 205 seckey = self._streamVariableToSeckey.get(value) 206 if seckey is None: 207 seckey = str(uuid.uuid4()) 208 self._streamVariableToSeckey[value] = seckey 209 210 return ('app://' + AbstractApplicationServlet.UPLOAD_URL_PREFIX 211 + key + '/' + seckey)
212 213
214 - def cleanStreamVariable(self, owner, name):
215 nameToStreamVar = self._pidToNameToStreamVariable.get( 216 self.getPaintableId(owner)) 217 if 'name' in nameToStreamVar: 218 del nameToStreamVar['name'] 219 if len(nameToStreamVar) == 0: 220 if self.getPaintableId(owner) in self._pidToNameToStreamVariable: 221 del self._pidToNameToStreamVariable[self.getPaintableId(owner)]
222 223
224 -class HttpServletRequestWrapper(IRequest):
225 """Concrete wrapper class for L{HttpServletRequest}. 226 227 @see: L{IRequest} 228 """ 229
230 - def __init__(self, request, applicationServlet):
231 self._request = request 232 self.servlet = applicationServlet
233 234
235 - def getAttribute(self, name, default=''):
236 return self.servlet.getParameter(self._request, name, default)
237 238
239 - def getContentLength(self):
240 return self.servlet.getContentLength(self._request)
241 242
243 - def getInputStream(self):
244 return self.servlet.getInputStream(self._request)
245 246
247 - def getParameter(self, name):
248 return self.servlet.getParameter(self._request, name, None)
249 250
251 - def getRequestID(self):
252 return 'RequestURL:' + self.servlet.getRequestUri(self._request)
253 254
255 - def getSession(self):
256 session = self.servlet.getSession(self._request) 257 return HttpSessionWrapper(session, self.servlet)
258 259
260 - def getWrappedRequest(self):
261 return self._request
262 263
264 - def getWrappedServlet(self):
265 return self.servlet
266 267
268 - def isRunningInPortlet(self):
269 return False
270 271
272 - def setAttribute(self, name, o):
273 self.servlet.setParameter(self._request, name, o)
274 275
276 -class HttpServletResponseWrapper(IResponse):
277 """Concrete wrapper class for L{HttpServletResponse}. 278 279 @see: L{IResponse} 280 """ 281
282 - def __init__(self, response, applicationServlet):
283 self._response = response 284 self.servlet = applicationServlet
285 286
287 - def getOutputStream(self):
288 return self.servlet.getOutputStream(self._response)
289 290
291 - def getWrappedResponse(self):
292 return self._response
293 294
295 - def getWrappedServlet(self):
296 return self.servlet
297 298
299 - def setContentType(self, typ):
300 self.servlet.setHeader(self._response, 'Content-Type', typ)
301 302
303 -class HttpSessionWrapper(ISession):
304 """Concrete wrapper class for L{HttpSession}. 305 306 @see: L{ISession} 307 """ 308
309 - def __init__(self, session, applicationServlet):
310 self._session = session 311 self.servlet = applicationServlet
312 313
314 - def getAttribute(self, name, default=None):
315 return self.servlet.getSessionAttribute(self._session, name, default)
316 317
318 - def getMaxInactiveInterval(self):
319 """maximum time interval, in seconds, between client accesses""" 320 return self.servlet.getMaxInactiveInterval(self._session)
321 322
323 - def getWrappedSession(self):
324 return self._session
325 326
327 - def getWrappedServlet(self):
328 return self.servlet
329 330
331 - def isNew(self):
332 return self.servlet.isSessionNew(self._session)
333 334
335 - def setAttribute(self, name, value):
336 self.servlet.setSessionAttribute(self._session, name, value)
337 338
339 -class AbstractApplicationServletWrapper(ICallback):
340
341 - def __init__(self, servlet):
342 self.servlet = servlet
343 344
345 - def criticalNotification(self, request, response, cap, msg, 346 details, outOfSyncURL):
347 348 self.servlet.criticalNotification(request.getWrappedRequest(), 349 response.getWrappedResponse(), cap, msg, details, outOfSyncURL)
350 351
352 - def getRequestPathInfo(self, request):
353 return self.servlet.getRequestPathInfo(request.getWrappedRequest())
354 355
356 - def getThemeResourceAsStream(self, themeName, resource):
357 return self.servlet.getResourceAsStream( 358 ('/' + AbstractApplicationServlet.THEME_DIRECTORY_PATH 359 + themeName + '/' + resource))
360