1 29 30 package com.caucho.server.webapp; 31 32 import com.caucho.server.connection.AbstractHttpResponse; 33 import com.caucho.server.connection.AbstractResponseStream; 34 import com.caucho.server.connection.CauchoRequest; 35 import com.caucho.server.connection.CauchoResponse; 36 import com.caucho.server.dispatch.Invocation; 37 import com.caucho.util.L10N; 38 39 import javax.servlet.RequestDispatcher ; 40 import javax.servlet.ServletException ; 41 import javax.servlet.ServletRequest ; 42 import javax.servlet.ServletResponse ; 43 import javax.servlet.http.HttpServletRequest ; 44 import javax.servlet.http.HttpServletRequestWrapper ; 45 import javax.servlet.http.HttpServletResponse ; 46 import javax.servlet.http.HttpServletResponseWrapper ; 47 import javax.servlet.http.HttpSession ; 48 import java.io.IOException ; 49 import java.io.OutputStream ; 50 import java.io.PrintWriter ; 51 52 public class RequestDispatcherImpl implements RequestDispatcher { 53 private static final L10N L = new L10N(RequestDispatcherImpl.class); 54 55 private static final String REQUEST_URI = 56 "javax.servlet.include.request_uri"; 57 private static final String CONTEXT_PATH = 58 "javax.servlet.include.context_path"; 59 private static final String SERVLET_PATH = 60 "javax.servlet.include.servlet_path"; 61 private static final String PATH_INFO = 62 "javax.servlet.include.path_info"; 63 private static final String QUERY_STRING = 64 "javax.servlet.include.query_string"; 65 66 private static final String FWD_REQUEST_URI = 67 "javax.servlet.forward.request_uri"; 68 private static final String FWD_CONTEXT_PATH = 69 "javax.servlet.forward.context_path"; 70 private static final String FWD_SERVLET_PATH = 71 "javax.servlet.forward.servlet_path"; 72 private static final String FWD_PATH_INFO = 73 "javax.servlet.forward.path_info"; 74 private static final String FWD_QUERY_STRING = 75 "javax.servlet.forward.query_string"; 76 77 private WebApp _webApp; 79 private Invocation _includeInvocation; 80 private Invocation _forwardInvocation; 81 private Invocation _errorInvocation; 82 private boolean _isLogin; 83 84 RequestDispatcherImpl(Invocation includeInvocation, 85 Invocation forwardInvocation, 86 Invocation errorInvocation, 87 WebApp webApp) 88 { 89 _includeInvocation = includeInvocation; 90 _forwardInvocation = forwardInvocation; 91 _errorInvocation = errorInvocation; 92 _webApp = webApp; 93 } 94 95 public void setLogin(boolean isLogin) 96 { 97 _isLogin = isLogin; 98 } 99 100 public boolean isModified() 101 { 102 return _includeInvocation.isModified(); 103 } 104 105 public void forward(ServletRequest request, ServletResponse response) 106 throws ServletException , IOException 107 { 108 forward((HttpServletRequest ) request, (HttpServletResponse ) response, 109 null, _forwardInvocation); 110 } 111 112 public void error(ServletRequest request, ServletResponse response) 113 throws ServletException , IOException 114 { 115 forward((HttpServletRequest ) request, (HttpServletResponse ) response, 116 null, _errorInvocation); 117 } 118 119 126 public void forward(HttpServletRequest req, HttpServletResponse res, 127 String method, Invocation invocation) 128 throws ServletException , IOException 129 { 130 AbstractHttpResponse response = null; 131 DispatchRequest subRequest; 132 HttpSession session = null; 133 134 CauchoResponse cauchoRes = null; 135 136 if (res instanceof CauchoResponse) 137 cauchoRes = (CauchoResponse) res; 138 139 if (res.isCommitted() && method == null) { 140 IllegalStateException exn; 141 exn = new IllegalStateException ("forward() not allowed after buffer has committed."); 142 143 if (cauchoRes == null || ! cauchoRes.hasError()) { 144 if (cauchoRes != null) 145 cauchoRes.setHasError(true); 146 throw exn; 147 } 148 149 _webApp.log(exn.getMessage(), exn); 150 } 151 152 if (res instanceof AbstractHttpResponse) 153 response = (AbstractHttpResponse) res; 154 155 ServletResponse resPtr = res; 156 157 if (method == null) 158 method = req.getMethod(); 159 160 subRequest = DispatchRequest.createDispatch(); 161 162 HttpServletRequest parentRequest = req; 163 HttpServletRequestWrapper reqWrapper = null; 164 HttpServletRequest topRequest = subRequest; 165 166 if (! (req instanceof CauchoRequest)) 167 topRequest = req; 168 169 while (parentRequest instanceof HttpServletRequestWrapper && 170 ! (parentRequest instanceof CauchoRequest)) { 171 reqWrapper = (HttpServletRequestWrapper ) parentRequest; 172 parentRequest = (HttpServletRequest ) reqWrapper.getRequest(); 173 } 174 175 String newQueryString = invocation.getQueryString(); 176 String reqQueryString = req.getQueryString(); 177 178 String queryString; 179 180 181 if (_isLogin) 183 queryString = newQueryString; 184 else if (reqQueryString == null) 185 queryString = newQueryString; 186 else if (newQueryString == null) 187 queryString = reqQueryString; 188 else if (reqQueryString.equals(newQueryString)) 189 queryString = newQueryString; 190 194 else 195 queryString = newQueryString; 196 197 WebApp oldWebApp; 198 199 if (req instanceof CauchoRequest) 200 oldWebApp = ((CauchoRequest) req).getWebApp(); 201 else 202 oldWebApp = (WebApp) _webApp.getContext(req.getContextPath()); 203 204 subRequest.init(invocation.getWebApp(), oldWebApp, 205 parentRequest, res, method, 206 invocation.getURI(), 207 invocation.getServletPath(), 208 invocation.getPathInfo(), 209 queryString, newQueryString); 210 211 212 if (reqWrapper != null) { 213 reqWrapper.setRequest(subRequest); 214 215 if (topRequest == parentRequest) topRequest = reqWrapper; 217 } 218 219 Object oldUri = null; 220 Object oldContextPath = null; 221 Object oldServletPath = null; 222 Object oldPathInfo = null; 223 Object oldQueryString = null; 224 Object oldJSPFile = null; 225 Object oldForward = null; 226 227 oldUri = req.getAttribute(REQUEST_URI); 228 229 if (oldUri != null) { 230 oldContextPath = req.getAttribute(CONTEXT_PATH); 231 oldServletPath = req.getAttribute(SERVLET_PATH); 232 oldPathInfo = req.getAttribute(PATH_INFO); 233 oldQueryString = req.getAttribute(QUERY_STRING); 234 235 req.removeAttribute(REQUEST_URI); 236 req.removeAttribute(CONTEXT_PATH); 237 req.removeAttribute(SERVLET_PATH); 238 req.removeAttribute(PATH_INFO); 239 req.removeAttribute(QUERY_STRING); 240 req.removeAttribute("caucho.jsp.jsp-file"); 241 } 242 243 if (req.getAttribute(FWD_REQUEST_URI) == null) { 244 subRequest.setAttribute(FWD_REQUEST_URI, req.getRequestURI()); 245 subRequest.setAttribute(FWD_CONTEXT_PATH, req.getContextPath()); 246 subRequest.setAttribute(FWD_SERVLET_PATH, req.getServletPath()); 247 subRequest.setAttribute(FWD_PATH_INFO, req.getPathInfo()); 248 subRequest.setAttribute(FWD_QUERY_STRING, req.getQueryString()); 249 } 250 251 oldForward = req.getAttribute("caucho.forward"); 252 req.setAttribute("caucho.forward", "true"); 253 254 subRequest.setPageURI(subRequest.getRequestURI()); 255 subRequest.setPageContextPath(subRequest.getContextPath()); 256 subRequest.setPageServletPath(subRequest.getServletPath()); 257 subRequest.setPagePathInfo(subRequest.getPathInfo()); 258 subRequest.setPageQueryString(subRequest.getQueryString()); 259 260 CauchoRequest oldRequest = null; 261 AbstractResponseStream oldStream = null; 262 if (response != null) { 263 oldRequest = response.getRequest(); 264 oldStream = response.getResponseStream(); 265 } 266 267 Thread thread = Thread.currentThread(); 268 ClassLoader oldLoader = thread.getContextClassLoader(); 269 270 try { 271 if (response != null) { 272 response.setRequest(subRequest); 273 response.setResponseStream(response.getOriginalStream()); 274 } 275 276 res.resetBuffer(); 277 res.setContentLength(-1); 278 279 invocation.service(topRequest, res); 280 281 if (cauchoRes != null) 282 cauchoRes.close(); 283 else { 284 try { 285 OutputStream os = res.getOutputStream(); 286 if (os != null) 287 os.close(); 288 } catch (IllegalStateException e) { 289 } 290 291 try { 292 PrintWriter out = res.getWriter(); 293 if (out != null) 294 out.close(); 295 } catch (IllegalStateException e1) { 296 } 297 298 311 } 312 } finally { 313 subRequest.finish(); 314 315 thread.setContextClassLoader(oldLoader); 316 317 if (response != null) { 318 response.setRequest(oldRequest); 319 response.setResponseStream(oldStream); 320 } 322 323 DispatchRequest.free(subRequest); 324 325 if (reqWrapper != null) 326 reqWrapper.setRequest(parentRequest); 327 328 if (oldUri != null) 330 req.setAttribute(REQUEST_URI, oldUri); 331 332 if (oldContextPath != null) 333 req.setAttribute(CONTEXT_PATH, oldContextPath); 334 335 if (oldServletPath != null) 336 req.setAttribute(SERVLET_PATH, oldServletPath); 337 338 if (oldPathInfo != null) 339 req.setAttribute(PATH_INFO, oldPathInfo); 340 341 if (oldQueryString != null) 342 req.setAttribute(QUERY_STRING, oldQueryString); 343 344 if (oldForward == null) 345 req.removeAttribute("caucho.forward"); 346 } 347 } 348 349 350 public void include(ServletRequest request, ServletResponse response) 351 throws ServletException , IOException 352 { 353 include(request, response, null); 354 } 355 356 359 public void include(ServletRequest request, ServletResponse response, 360 String method) 361 throws ServletException , IOException 362 { 363 HttpServletRequest req = (HttpServletRequest ) request; 364 HttpServletResponse res = (HttpServletResponse ) response; 365 366 IncludeDispatchRequest subRequest; 367 DispatchResponse subResponse; 368 369 Invocation invocation = _includeInvocation; 370 WebApp webApp = invocation.getWebApp(); 371 String queryString = invocation.getQueryString(); 372 373 if (method == null) 374 method = req.getMethod(); 375 376 if (! "POST".equals(method)) 377 method = "GET"; 378 379 HttpServletRequest parentRequest = req; 380 HttpServletRequestWrapper reqWrapper = null; 381 382 HttpServletResponse parentResponse = res; 383 HttpServletResponseWrapper resWrapper = null; 384 385 if (! _webApp.getDispatchWrapsFilters()) { 386 if (req instanceof HttpServletRequestWrapper && 387 ! (req instanceof CauchoRequest)) { 388 reqWrapper = (HttpServletRequestWrapper ) req; 389 parentRequest = (HttpServletRequest ) reqWrapper.getRequest(); 390 } 391 392 if (res instanceof HttpServletResponseWrapper && 393 ! (res instanceof CauchoResponse)) { 394 resWrapper = (HttpServletResponseWrapper ) res; 395 parentResponse = (HttpServletResponse ) resWrapper.getResponse(); 396 } 397 } 398 399 subRequest = IncludeDispatchRequest.createDispatch(); 400 401 WebApp oldWebApp; 402 403 if (req instanceof CauchoRequest) 404 oldWebApp = ((CauchoRequest) req).getWebApp(); 405 else 406 oldWebApp = (WebApp) webApp.getContext(req.getContextPath()); 407 408 subRequest.init(webApp, oldWebApp, 409 parentRequest, parentResponse, 410 method, 411 req.getRequestURI(), req.getServletPath(), 412 req.getPathInfo(), req.getQueryString(), 413 queryString); 414 415 HttpServletRequest topRequest = subRequest; 416 417 if (reqWrapper != null) { 418 reqWrapper.setRequest(subRequest); 419 topRequest = reqWrapper; 420 } 421 422 subResponse = DispatchResponse.createDispatch(); 423 subResponse.setNextResponse(res); 424 425 AbstractResponseStream s = null; 426 boolean oldDisableClose = false; 427 428 subResponse.init(subRequest); 429 subResponse.setNextResponse(parentResponse); 430 subResponse.start(); 431 subResponse.setCharacterEncoding(res.getCharacterEncoding()); 432 433 if (_webApp.getDispatchWrapsFilters()) 434 subResponse.setCauchoResponseStream(true); 435 436 CauchoResponse cauchoRes = null; 437 if (res instanceof CauchoResponse) { 438 cauchoRes = (CauchoResponse) res; 439 } 440 else if (! _webApp.getDispatchWrapsFilters()) { 441 subResponse.killCache(); 442 } 443 444 HttpServletResponse topResponse = subResponse; 445 446 if (resWrapper != null) { 447 resWrapper.setResponse(subResponse); 448 topResponse = res; 449 } 450 451 Object oldUri = null; 452 Object oldContextPath = null; 453 Object oldServletPath = null; 454 Object oldPathInfo = null; 455 Object oldQueryString = null; 456 457 oldUri = req.getAttribute(REQUEST_URI); 458 if (oldUri != null) { 459 oldContextPath = request.getAttribute(CONTEXT_PATH); 460 oldServletPath = req.getAttribute(SERVLET_PATH); 461 oldPathInfo = req.getAttribute(PATH_INFO); 462 oldQueryString = req.getAttribute(QUERY_STRING); 463 } 464 465 subRequest.setPageURI(invocation.getURI()); 466 subRequest.setAttribute(REQUEST_URI, invocation.getURI()); 467 String contextPath; 468 if (webApp != null) 469 contextPath = webApp.getContextPath(); 470 else 471 contextPath = null; 472 473 subRequest.setPageContextPath(contextPath); 474 subRequest.setAttribute(CONTEXT_PATH, contextPath); 475 subRequest.setPageServletPath(invocation.getServletPath()); 476 subRequest.setAttribute(SERVLET_PATH, invocation.getServletPath()); 477 subRequest.setPagePathInfo(invocation.getPathInfo()); 478 subRequest.setAttribute(PATH_INFO, invocation.getPathInfo()); 479 subRequest.setPageQueryString(queryString); 480 subRequest.setAttribute(QUERY_STRING, queryString); 481 482 subRequest.removeAttribute("caucho.jsp.jsp-file"); 483 484 Thread thread = Thread.currentThread(); 485 ClassLoader oldLoader = thread.getContextClassLoader(); 486 boolean isOkay = false; 487 try { 488 invocation.service(topRequest, topResponse); 489 isOkay = true; 490 } finally { 491 thread.setContextClassLoader(oldLoader); 492 494 subRequest.finish(); 495 496 500 if (oldUri != null) 501 req.setAttribute(REQUEST_URI, oldUri); 502 else 503 req.removeAttribute(REQUEST_URI); 504 505 if (oldContextPath != null) 506 req.setAttribute(CONTEXT_PATH, oldContextPath); 507 else 508 req.removeAttribute(CONTEXT_PATH); 509 510 if (oldServletPath != null) 511 req.setAttribute(SERVLET_PATH, oldServletPath); 512 else 513 req.removeAttribute(SERVLET_PATH); 514 515 if (oldPathInfo != null) 516 req.setAttribute(PATH_INFO, oldPathInfo); 517 else 518 req.removeAttribute(PATH_INFO); 519 520 if (oldQueryString != null) 521 req.setAttribute(QUERY_STRING, oldQueryString); 522 else 523 req.removeAttribute(QUERY_STRING); 524 525 if (! isOkay) 526 subResponse.killCache(); 527 528 subResponse.close(); 529 530 536 537 IncludeDispatchRequest.free(subRequest); 538 DispatchResponse.free(subResponse); 539 540 if (reqWrapper != null) 541 reqWrapper.setRequest(parentRequest); 542 543 if (resWrapper != null) 544 resWrapper.setResponse(parentResponse); 545 } 546 } 547 } 548 | Popular Tags |