001 /* 002 * Copyright 1999,2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 018 package org.apache.commons.messagelet.impl; 019 020 import java.io.UnsupportedEncodingException; 021 import java.security.Principal; 022 import java.text.ParseException; 023 import java.text.SimpleDateFormat; 024 import java.util.ArrayList; 025 import java.util.Collections; 026 import java.util.Date; 027 import java.util.Enumeration; 028 import java.util.HashMap; 029 import java.util.Locale; 030 import java.util.Map; 031 032 import javax.servlet.ServletContext; 033 import javax.servlet.http.Cookie; 034 import javax.servlet.http.HttpServletRequest; 035 import javax.servlet.http.HttpSession; 036 037 import org.apache.commons.collections.iterators.IteratorEnumeration; 038 039 /** 040 * Based on the HttpRequestBase code from Catalina. 041 * 042 * @author Craig R. McClanahan 043 * @author James Strachan 044 * @version $Revision: 155459 $ $Date: 2005-02-26 13:24:44 +0000 (Sat, 26 Feb 2005) $ 045 */ 046 047 public class HttpServletRequestImpl extends ServletRequestImpl implements HttpServletRequest { 048 049 050 /** 051 * The authentication type used for this request. 052 */ 053 protected String authType = null; 054 055 056 /** 057 * The context path for this request. 058 */ 059 protected String contextPath = ""; 060 061 062 /** 063 * The set of cookies associated with this Request. 064 */ 065 protected ArrayList cookies = new ArrayList(); 066 067 068 /** 069 * The set of SimpleDateFormat formats to use in getDateHeader(). 070 */ 071 protected SimpleDateFormat formats[] = { 072 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), 073 new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), 074 new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) 075 }; 076 077 078 079 /** 080 * The HTTP headers associated with this Request, keyed by name. The 081 * values are ArrayLists of the corresponding header values. 082 */ 083 protected HashMap headers = new HashMap(); 084 085 086 087 /** 088 * The request method associated with this Request. 089 */ 090 protected String method = null; 091 092 093 /** 094 * The path information for this request. 095 */ 096 protected String pathInfo = null; 097 098 099 /** 100 * The query string for this request. 101 */ 102 protected String queryString = null; 103 104 105 /** 106 * Was the requested session ID received in a cookie? 107 */ 108 protected boolean requestedSessionCookie = false; 109 110 111 /** 112 * The requested session ID (if any) for this request. 113 */ 114 protected String requestedSessionId = null; 115 116 117 /** 118 * Was the requested session ID received in a URL? 119 */ 120 protected boolean requestedSessionURL = false; 121 122 123 /** 124 * The request URI associated with this request. 125 */ 126 protected String requestURI = null; 127 128 129 /** 130 * The servlet path for this request. 131 */ 132 protected String servletPath = null; 133 134 135 /** 136 * The currently active session for this request. 137 */ 138 protected HttpSessionImpl session = null; 139 140 141 /** 142 * The Principal who has been authenticated for this Request. 143 */ 144 protected Principal userPrincipal = null; 145 146 147 /** 148 * The parameters 149 */ 150 private Map parameters = null; 151 152 153 // --------------------------------------------------------- Public Methods 154 155 public HttpServletRequestImpl(ServletContext servletContext) { 156 super( servletContext ); 157 } 158 159 160 /** 161 * Add a Cookie to the set of Cookies associated with this Request. 162 * 163 * @param cookie The new cookie 164 */ 165 public void addCookie(Cookie cookie) { 166 167 synchronized (cookies) { 168 cookies.add(cookie); 169 } 170 171 } 172 173 174 /** 175 * Add a Header to the set of Headers associated with this Request. 176 * 177 * @param name The new header name 178 * @param value The new header value 179 */ 180 public void addHeader(String name, String value) { 181 182 name = name.toLowerCase(); 183 synchronized (headers) { 184 ArrayList values = (ArrayList) headers.get(name); 185 if (values == null) { 186 values = new ArrayList(); 187 headers.put(name, values); 188 } 189 values.add(value); 190 } 191 192 } 193 194 195 /** 196 * Clear the collection of Cookies associated with this Request. 197 */ 198 public void clearCookies() { 199 200 synchronized (cookies) { 201 cookies.clear(); 202 } 203 204 } 205 206 207 /** 208 * Clear the collection of Headers associated with this Request. 209 */ 210 public void clearHeaders() { 211 212 headers.clear(); 213 214 } 215 216 217 218 219 /** 220 * Set the authentication type used for this request, if any; otherwise 221 * set the type to <code>null</code>. Typical values are "BASIC", 222 * "DIGEST", or "SSL". 223 * 224 * @param authType The authentication type used 225 */ 226 public void setAuthType(String authType) { 227 228 this.authType = authType; 229 230 } 231 232 233 /** 234 * Set the context path for this Request. This will normally be called 235 * when the associated Context is mapping the Request to a particular 236 * Wrapper. 237 * 238 * @param path The context path 239 */ 240 public void setContextPath(String path) { 241 242 if (path == null) 243 this.contextPath = ""; 244 else 245 this.contextPath = path; 246 247 } 248 249 250 /** 251 * Set the HTTP request method used for this Request. 252 * 253 * @param method The request method 254 */ 255 public void setMethod(String method) { 256 257 this.method = method; 258 259 } 260 261 262 /** 263 * Set the path information for this Request. This will normally be called 264 * when the associated Context is mapping the Request to a particular 265 * Wrapper. 266 * 267 * @param path The path information 268 */ 269 public void setPathInfo(String path) { 270 271 this.pathInfo = path; 272 273 } 274 275 276 /** 277 * Set the query string for this Request. This will normally be called 278 * by the HTTP Connector, when it parses the request headers. 279 * 280 * @param query The query string 281 */ 282 public void setQueryString(String query) { 283 284 this.queryString = query; 285 this.parameters = null; 286 287 } 288 289 290 /** 291 * Set a flag indicating whether or not the requested session ID for this 292 * request came in through a cookie. This is normally called by the 293 * HTTP Connector, when it parses the request headers. 294 * 295 * @param flag The new flag 296 */ 297 public void setRequestedSessionCookie(boolean flag) { 298 299 this.requestedSessionCookie = flag; 300 301 } 302 303 304 /** 305 * Set the requested session ID for this request. This is normally called 306 * by the HTTP Connector, when it parses the request headers. 307 * 308 * @param id The new session id 309 */ 310 public void setRequestedSessionId(String id) { 311 312 this.requestedSessionId = id; 313 314 } 315 316 317 /** 318 * Set a flag indicating whether or not the requested session ID for this 319 * request came in through a URL. This is normally called by the 320 * HTTP Connector, when it parses the request headers. 321 * 322 * @param flag The new flag 323 */ 324 public void setRequestedSessionURL(boolean flag) { 325 326 this.requestedSessionURL = flag; 327 328 } 329 330 331 /** 332 * Set the unparsed request URI for this Request. This will normally 333 * be called by the HTTP Connector, when it parses the request headers. 334 * 335 * @param uri The request URI 336 */ 337 public void setRequestURI(String uri) { 338 339 this.requestURI = uri; 340 341 } 342 343 344 /** 345 * Set the servlet path for this Request. This will normally be called 346 * when the associated Context is mapping the Request to a particular 347 * Wrapper. 348 * 349 * @param path The servlet path 350 */ 351 public void setServletPath(String path) { 352 353 this.servletPath = path; 354 355 } 356 357 358 /** 359 * Set the Principal who has been authenticated for this Request. This 360 * value is also used to calculate the value to be returned by the 361 * <code>getRemoteUser()</code> method. 362 * 363 * @param principal The user Principal 364 */ 365 public void setUserPrincipal(Principal principal) { 366 367 this.userPrincipal = principal; 368 369 } 370 371 372 373 // --------------------------------------------- HttpServletRequest Methods 374 375 376 /** 377 * Return the authentication type used for this Request. 378 */ 379 public String getAuthType() { 380 381 return (authType); 382 383 } 384 385 386 /** 387 * Return the portion of the request URI used to select the Context 388 * of the Request. 389 */ 390 public String getContextPath() { 391 392 return (contextPath); 393 394 } 395 396 397 /** 398 * Return the set of Cookies received with this Request. 399 */ 400 public Cookie[] getCookies() { 401 402 synchronized (cookies) { 403 if (cookies.size() < 1) 404 return (null); 405 Cookie results[] = new Cookie[cookies.size()]; 406 return ((Cookie[]) cookies.toArray(results)); 407 } 408 409 } 410 411 412 /** 413 * Return the value of the specified date header, if any; otherwise 414 * return -1. 415 * 416 * @param name Name of the requested date header 417 * 418 * @exception IllegalArgumentException if the specified header value 419 * cannot be converted to a date 420 */ 421 public long getDateHeader(String name) { 422 423 String value = getHeader(name); 424 if (value == null) 425 return (-1L); 426 427 // Work around a bug in SimpleDateFormat in pre-JDK1.2b4 428 // (Bug Parade bug #4106807) 429 value += " "; 430 431 // Attempt to convert the date header in a variety of formats 432 for (int i = 0; i < formats.length; i++) { 433 try { 434 Date date = formats[i].parse(value); 435 return (date.getTime()); 436 } catch (ParseException e) { 437 ; 438 } 439 } 440 throw new IllegalArgumentException(value); 441 442 } 443 444 445 /** 446 * Return the first value of the specified header, if any; otherwise, 447 * return <code>null</code> 448 * 449 * @param name Name of the requested header 450 */ 451 public String getHeader(String name) { 452 453 name = name.toLowerCase(); 454 synchronized (headers) { 455 ArrayList values = (ArrayList) headers.get(name); 456 if (values != null) 457 return ((String) values.get(0)); 458 else 459 return (null); 460 } 461 462 } 463 464 465 /** 466 * Return all of the values of the specified header, if any; otherwise, 467 * return an empty enumeration. 468 * 469 * @param name Name of the requested header 470 */ 471 public Enumeration getHeaders(String name) { 472 473 name = name.toLowerCase(); 474 synchronized (headers) { 475 ArrayList values = (ArrayList) headers.get(name); 476 if (values != null) 477 return (new IteratorEnumeration( values.iterator() )); 478 else 479 return (new IteratorEnumeration( Collections.EMPTY_LIST.iterator() )); 480 } 481 482 } 483 484 485 /** 486 * Return the names of all headers received with this request. 487 */ 488 public Enumeration getHeaderNames() { 489 490 synchronized (headers) { 491 return (new IteratorEnumeration( headers.keySet().iterator() )); 492 } 493 494 } 495 496 497 /** 498 * Return the value of the specified header as an integer, or -1 if there 499 * is no such header for this request. 500 * 501 * @param name Name of the requested header 502 * 503 * @exception IllegalArgumentException if the specified header value 504 * cannot be converted to an integer 505 */ 506 public int getIntHeader(String name) { 507 508 String value = getHeader(name); 509 if (value == null) 510 return (-1); 511 else 512 return (Integer.parseInt(value)); 513 514 } 515 516 517 /** 518 * Return the HTTP request method used in this Request. 519 */ 520 public String getMethod() { 521 522 return (method); 523 524 } 525 526 527 /** 528 * Returns a <code>Map</code> of the parameters of this request. 529 * Request parameters are extra information sent with the request. 530 * For HTTP servlets, parameters are contained in the query string 531 * or posted form data. 532 * 533 * @return A <code>Map</code> containing parameter names as keys 534 * and parameter values as map values. 535 */ 536 public Map getParameterMap() { 537 if ( parameters == null ) { 538 parameters = new HashMap(); 539 if ( queryString != null ) { 540 try { 541 RequestUtil.parseParameters(parameters, queryString, getCharacterEncoding()); 542 } 543 catch (UnsupportedEncodingException e) { 544 servletContext.log( "Could not parse query string: " + queryString, e); 545 } 546 } 547 } 548 return parameters; 549 } 550 551 /** 552 * Return the path information associated with this Request. 553 */ 554 public String getPathInfo() { 555 556 return (pathInfo); 557 558 } 559 560 561 /** 562 * Return the extra path information for this request, translated 563 * to a real path. 564 */ 565 public String getPathTranslated() { 566 567 if (pathInfo == null) 568 return (null); 569 else 570 return (servletContext.getRealPath(pathInfo)); 571 572 } 573 574 575 /** 576 * Return the query string associated with this request. 577 */ 578 public String getQueryString() { 579 580 return (queryString); 581 582 } 583 584 585 /** 586 * Return the name of the remote user that has been authenticated 587 * for this Request. 588 */ 589 public String getRemoteUser() { 590 591 if (userPrincipal != null) 592 return (userPrincipal.getName()); 593 else 594 return (null); 595 596 } 597 598 599 /** 600 * Return the session identifier included in this request, if any. 601 */ 602 public String getRequestedSessionId() { 603 604 return (requestedSessionId); 605 606 } 607 608 609 /** 610 * Return the request URI for this request. 611 */ 612 public String getRequestURI() { 613 614 return (requestURI); 615 616 } 617 618 619 /** 620 * Reconstructs the URL the client used to make the request. 621 * The returned URL contains a protocol, server name, port 622 * number, and server path, but it does not include query 623 * string parameters. 624 * <p> 625 * Because this method returns a <code>StringBuffer</code>, 626 * not a <code>String</code>, you can modify the URL easily, 627 * for example, to append query parameters. 628 * <p> 629 * This method is useful for creating redirect messages and 630 * for reporting errors. 631 * 632 * @return A <code>StringBuffer</code> object containing the 633 * reconstructed URL 634 */ 635 public StringBuffer getRequestURL() { 636 637 StringBuffer url = new StringBuffer(); 638 String scheme = getScheme(); 639 int port = getServerPort(); 640 if (port < 0) 641 port = 80; // Work around java.net.URL bug 642 643 url.append(scheme); 644 url.append("://"); 645 url.append(getServerName()); 646 if ((scheme.equals("http") && (port != 80)) 647 || (scheme.equals("https") && (port != 443))) { 648 url.append(':'); 649 url.append(port); 650 } 651 url.append(getRequestURI()); 652 653 return (url); 654 655 } 656 657 658 /** 659 * Return the portion of the request URI used to select the servlet 660 * that will process this request. 661 */ 662 public String getServletPath() { 663 664 return (servletPath); 665 666 } 667 668 669 /** 670 * Return the session associated with this Request, creating one 671 * if necessary. 672 */ 673 public HttpSession getSession() { 674 675 return (getSession(true)); 676 677 } 678 679 680 /** 681 * Return the session associated with this Request, creating one 682 * if necessary and requested. 683 * 684 * @param create Create a new session if one does not exist 685 */ 686 public HttpSession getSession(boolean create) { 687 // Return the current session if it exists and is valid 688 if ((session != null) && !session.isValid()) 689 session = null; 690 691 if ( create && session == null) { 692 session = new HttpSessionImpl( servletContext ); 693 } 694 return session; 695 } 696 697 698 /** 699 * Return <code>true</code> if the session identifier included in this 700 * request came from a cookie. 701 */ 702 public boolean isRequestedSessionIdFromCookie() { 703 704 if (requestedSessionId != null) 705 return (requestedSessionCookie); 706 else 707 return (false); 708 709 } 710 711 712 /** 713 * Return <code>true</code> if the session identifier included in this 714 * request came from the request URI. 715 */ 716 public boolean isRequestedSessionIdFromURL() { 717 718 if (requestedSessionId != null) 719 return (requestedSessionURL); 720 else 721 return (false); 722 723 } 724 725 726 /** 727 * Return <code>true</code> if the session identifier included in this 728 * request came from the request URI. 729 * 730 * @deprecated As of Version 2.1 of the Java Servlet API, use 731 * <code>isRequestedSessionIdFromURL()</code> instead. 732 */ 733 public boolean isRequestedSessionIdFromUrl() { 734 735 return (isRequestedSessionIdFromURL()); 736 737 } 738 739 740 /** 741 * Return <code>true</code> if the session identifier included in this 742 * request identifies a valid session. 743 */ 744 public boolean isRequestedSessionIdValid() { 745 return false; 746 747 } 748 749 750 /** 751 * Return <code>true</code> if the authenticated user principal 752 * possesses the specified role name. 753 * 754 * @param role Role name to be validated 755 */ 756 public boolean isUserInRole(String role) { 757 return false; 758 } 759 760 761 /** 762 * Return the principal that has been authenticated for this Request. 763 */ 764 public Principal getUserPrincipal() { 765 766 return (userPrincipal); 767 768 } 769 }