Package org.knopflerfish.bundle.http

Source Code of org.knopflerfish.bundle.http.RequestImpl

/*
* Copyright (c) 2003-2010, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.knopflerfish.bundle.http;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.osgi.service.http.HttpContext;

public class RequestImpl implements Request, PoolableObject {

  // private fields

  private final RequestBase base;

  private HttpConfigWrapper httpConfig;

  private final Registrations registrations;

  private final HttpSessionManager sessionManager;

  private InetAddress localAddress  = null;
  private InetAddress remoteAddress = null;

  private int localPort  = 0;
  private int remotePort = 0;

  private final Attributes attributes = new Attributes();

  private boolean keepAlive = false;

  private HttpSession session = null;

  private String requestedSessionId = null;

  private boolean requestedSessionIdFromURL = false;

  private boolean requestedSessionIdFromCookie = false;

  private String servletPath = null;

  private Cookie[] cookies = null;

  // constructors

  public RequestImpl(final Registrations registrations,
                     final HttpSessionManager sessionManager) {

    base = new RequestBase();

    this.registrations = registrations;
    this.sessionManager = sessionManager;
  }

  // public methods

  public StringBuffer getRequestURL() {
    StringBuffer sb = new StringBuffer((httpConfig.isSecure() ? "https" : "http") +
                                       "://" +getLocalName() +
                                       ":" + getLocalPort() +
                                       base.getURI());
    return sb;
  }

  public java.util.Map getParameterMap() {
    return base.getParameters();
  }

  public String getLocalAddr() {
    return localAddress.getHostAddress();
  }

  public String getLocalName() {
    if (httpConfig.getDNSLookup()) {
      return localAddress.getHostName();
    }
    String hostAddress = localAddress.getHostAddress();
    if (-1<hostAddress.indexOf(":")) {
      int pPos = hostAddress.indexOf("%");
      if (-1<pPos) {
        hostAddress = hostAddress.substring(0,pPos);
      }
      return "[" +hostAddress +"]";
    }
    return hostAddress;
  }


  public int getLocalPort() {
    return localPort;
  }

  public void init(InputStream is,
                   InetAddress localAddress,
                   int localPort,
                   InetAddress remoteAddress,
                   int remotePort,
                   HttpConfigWrapper httpConfig)
      throws HttpException, IOException
  {
    base.init(is, httpConfig);

    this.httpConfig    = httpConfig;
    this.localAddress  = localAddress;
    this.localPort     = localPort;
    this.remoteAddress = remoteAddress;
    this.remotePort    = remotePort;

    boolean http_1_1 = base.getProtocol().equals(
                                                 RequestBase.HTTP_1_1_PROTOCOL);

    if (http_1_1
        && !base.getHeaders(HeaderBase.HOST_HEADER_KEY)
        .hasMoreElements())
      throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);

    int available = getContentLength();
    String connection = getHeader(HeaderBase.CONNECTION_HEADER_KEY);
    // For details on the Proxy-Connection header please read:
    // http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/web-proxy-connection-header.html
    if (null==connection || 0==connection.length()) {
      // We handle Proxy-Connection in the same way as Connection
      connection = getHeader("Proxy-Connection");
    }

    String method = base.getMethod();
    //TODO: OPTIONS and DELETE -> lengthKnown
    boolean lengthKnown = method.equals(RequestBase.GET_METHOD)
      || method.equals(RequestBase.HEAD_METHOD)
      || available != -1;
    if (lengthKnown) {
      if (http_1_1) {
        if (!"Close".equals(connection)) {
          keepAlive = true;
        }
      } else if ("Keep-Alive".equals(connection)) {
          keepAlive = true;
      }
    }
   
    if (available != -1) {
      if (keepAlive) {
        base.getBody().setLimit(available);       
      } else if (!http_1_1) {
        // perhaps not according to spec, but works better :)
        base.getBody().setLimit(available);               
      }
    } else {
      if (method.equals(RequestBase.POST_METHOD)) {
        String transfer_encoding = getHeader(HeaderBase.TRANSFER_ENCODING_KEY);
        if(HeaderBase.TRANSFER_ENCODING_VALUE_CHUNKED.equals(transfer_encoding)) {
          // Handle chunked body the by reading every chunk and creating
          // a new servletinputstream for the decoded body
          // The only client (so far) that seems to be doing this is the
          // Axis2 library
          base.setBody(readChunkedBody(base.getBody()));
        } else {
          throw new HttpException(HttpServletResponse.SC_LENGTH_REQUIRED);
        }
      }
    }

    handleSession();
  }

  ServletInputStreamImpl readChunkedBody(ServletInputStreamImpl is)
    throws IOException, HttpException {
    int          chunkSize = 0;
    String       line;
    StringBuffer sb = new StringBuffer();

    // Build stringbuffer containing all chunk contents, then
    // make a byte array using request encoding.
    // Yes, one could likely be more memory effective
    do {
      line = is.readLine().trim();
      int ix = line.indexOf(";");
      if(ix != -1) {
        line = line.substring(0, ix);
      }
      chunkSize = Integer.parseInt(line, 16);
      int n = 0;
      while(n < chunkSize) {
        line = is.readLine();
        n += line.length();
        sb.append(line);
        sb.append("\r\n");
      }
    } while(chunkSize > 0);

    // remaining stuff should be parsed as headers
    base.parseHeaders(is);

    String enc = getCharacterEncoding();
    if(enc == null || enc.length() == 0) {
      enc = "UTF-8";
    }
    byte[] bytes = sb.toString().getBytes(enc);
    ByteArrayInputStream bin = new ByteArrayInputStream(bytes);

    return new ServletInputStreamImpl(bin, bytes.length);
  }

  public boolean getKeepAlive() {
    return keepAlive;
  }

  // package methods

  public void setServletPath(String servletPath) {
    this.servletPath = servletPath;
  }

  // private methods

  private void handleSession() {

    Cookie sessionCookie =
      (Cookie) base.getCookies().get(HttpUtil.SESSION_COOKIE_KEY);
    if (sessionCookie != null) {
      requestedSessionIdFromCookie = true;
      requestedSessionId = sessionCookie.getValue();
    } else {
      requestedSessionId = base.getSessionIdParameter();
      if (null!=requestedSessionId) {
        requestedSessionIdFromURL = true;
      }
    }
  }

  // implements PoolableObject

  public void init() {
  }

  public void destroy() {

    base.destroy();

    localAddress  = null;
    remoteAddress = null;

    localPort  = 0;
    remotePort = 0;

    attributes.removeAll();

    keepAlive = false;

    session = null;
    requestedSessionId = null;
    requestedSessionIdFromURL = false;
    requestedSessionIdFromCookie = false;

    servletPath = null;

    cookies = null;
  }

  // implements Request

  public InputStream getRawInputStream() {
    return base.getBody();
  }

  // implements HttpServletRequest

  public String getAuthType() {

    Object o = getAttribute(HttpContext.AUTHENTICATION_TYPE);
    if (o instanceof String) {
      return (String) o;
    }
    return null;
  }

  public String getRemoteUser() {

    Object o = getAttribute(HttpContext.REMOTE_USER);
    if (o instanceof String) {
      return (String) o;
    }
    return null;
  }

  public String getContextPath() {
    return "";
  }

  public Cookie[] getCookies() {

    Dictionary d;
    if (cookies == null && !(d = base.getCookies()).isEmpty()) {
      cookies = new Cookie[d.size()];
      Enumeration e = d.elements();
      for (int i = 0; i < cookies.length; i++)
        cookies[i] = (Cookie) e.nextElement();
    }

    return cookies;
  }

  public long getDateHeader(String name) {

    String value = base.getHeader(name);
    if (value == null)
      return -1; // NYI: throw new IllegalArgumentException()???

    for (int i = 0; i < HttpUtil.DATE_FORMATS.length; i++) {
      try {
        return HttpUtil.DATE_FORMATS[i].parse(value).getTime();
      } catch (Exception ignore) {
      }
    }

    throw new IllegalArgumentException("Invalid date value: "+value);
  }

  public String getHeader(String name) {
    return base.getHeader(name);
  }

  public Enumeration getHeaderNames() {
    return base.getHeaders().keys();
  }

  public Enumeration getHeaders(String name) {
    return base.getHeaders(name);
  }

  public int getIntHeader(String name) {

    String value = base.getHeader(name);
    if (value == null)
      return -1; // NYI: throw new NumberFormatException()???

    return Integer.parseInt(value);
  }

  public String getMethod() {
    return base.getMethod();
  }

  public String getPathInfo() {

    String decodedURI = HttpUtil.decodeURLEncoding(base.getURI());
    if (decodedURI != null && decodedURI.length() > servletPath.length()
        && decodedURI.startsWith(servletPath)) {
      return HttpUtil.makeTarget(decodedURI, servletPath);
    }
    return null;
  }

  public String getPathTranslated() {
    return getPathInfo();
  }

  public String getQueryString() {
    return base.getQueryString();
  }

  public String getRequestURI() {
    return base.getURI();
  }

  public String getRequestedSessionId() {
    return requestedSessionId;
  }

  public String getServletPath() {
    return servletPath;
  }

  public HttpSession getSession() {
    return getSession(true);
  }

  public HttpSession getSession(boolean create) {

    if (session == null) {
      session = sessionManager.getHttpSession(requestedSessionId);
      if (create && session == null)
        session = sessionManager.createHttpSession();
    }

    return session;
  }

  public Principal getUserPrincipal() {
    return null;
  }

  public boolean isRequestedSessionIdFromCookie() {
    return requestedSessionIdFromCookie;
  }

  public boolean isRequestedSessionIdFromURL() {
    return requestedSessionIdFromURL;
  }

  public boolean isRequestedSessionIdFromUrl() {
    return isRequestedSessionIdFromURL(); // deprecated
  }

  public boolean isRequestedSessionIdValid() {

    if (requestedSessionId == null)
      return false;

    HttpSession session = getSession(false);
    if (session == null) {
      return false;
    }
    return requestedSessionId.equals(session.getId());
  }

  public boolean isUserInRole(String role) {
    return false;
  }

  // implements ServletRequest

  public Object getAttribute(String name) {
    return attributes.getAttribute(name);
  }

  public Enumeration getAttributeNames() {
    return attributes.getAttributeNames();
  }

  public void setAttribute(String name, Object value) {
    attributes.setAttribute(name, value);
  }

  public void removeAttribute(String name) {
    attributes.removeAttribute(name);
  }

  public void setCharacterEncoding(String enc)
    throws UnsupportedEncodingException
  {
    base.setCharacterEncoding(enc);
  }

  public String getCharacterEncoding() {
    return base.getCharacterEncoding();
  }

  public int getContentLength() {
    return base.getContentLength();
  }

  public String getContentType() {
    return base.getContentType();
  }

  public ServletInputStream getInputStream() {
    return base.getBody(); // NYI: should be wrapped
  }

  public Locale getLocale() {
    return (Locale) base.getLocales().nextElement();
  }

  public Enumeration getLocales() {
    return base.getLocales();
  }

  public String getParameter(String name) {

    String[] values = getParameterValues(name);
    if (values == null || values.length == 0) {
      return null;
    }
    return values[0];
  }

  public Enumeration getParameterNames() {
    return base.getParameters().keys();
  }

  public String[] getParameterValues(String name) {
    return (String[]) base.getParameters().get(name);
  }

  public String getProtocol() {
    return base.getProtocol();
  }

  public BufferedReader getReader() {
    InputStreamReader isr = null;
    try {
      String enc = getCharacterEncoding();
      isr = null==enc
        ? new InputStreamReader(base.getBody())
        : new InputStreamReader(base.getBody(), enc);
    } catch (UnsupportedEncodingException use) {
      // Fallback to use the local default encoding...
      isr = new InputStreamReader(base.getBody());
    }
    return new BufferedReader(isr); // NYI:
    // should
    // be
    // wrapped
  }

  public String getRealPath(String path) {
    return null; // deprecated
  }

  public String getRemoteAddr() {
    return remoteAddress.getHostAddress();
  }

  public String getRemoteHost() {

    if (httpConfig.getDNSLookup()) {
      return remoteAddress.getHostName();
    }
    return remoteAddress.getHostAddress();
  }

  public int getRemotePort() {
    return remotePort;
  }

  public RequestDispatcher getRequestDispatcher(String uri) {
    RequestDispatcher rd = registrations.getRequestDispatcher(uri);
    return rd;
  }

  public String getServerName() {

    String host = base.getHeader(HeaderBase.HOST_HEADER_KEY);
    if (host == null || host.length() == 0)
      host = httpConfig.getHost();
    else {
      int index = host.indexOf(':');
      if (index != -1)
        host = host.substring(0, index);
    }
    if (host == null || host.length() == 0) {
      try {
        host = InetAddress.getLocalHost().getHostName();
      } catch (UnknownHostException uhe) {
        host = null;
      }
    }

    return host;
  }

  public int getServerPort() {

    String host = base.getHeader(HeaderBase.HOST_HEADER_KEY);
    if (host == null || host.length() == 0) {
      return httpConfig.getPort();
    }
    int index = host.indexOf(':');
    if (index != -1) {
      try {
        return Integer.parseInt(host.substring(index + 1));
      } catch (Exception ignore) {
      }
    }
    return isSecure() ? 443 : 80;
  }

  public boolean isSecure() {
    return httpConfig.isSecure();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.servlet.ServletRequest#getScheme()
   */
  public String getScheme() {
    return httpConfig.getScheme();
  }

} // RequestImpl
TOP

Related Classes of org.knopflerfish.bundle.http.RequestImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.