/*
* E-XML Library: For XML, XML-RPC, HTTP, and related.
* Copyright (C) 2002-2008 Elias Ross
*
* genman@noderunner.net
* http://noderunner.net/~genman
*
* 1025 NE 73RD ST
* SEATTLE WA 98115
* USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* $Id$
*/
package net.noderunner.http.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.Principal;
import java.text.ParseException;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import net.noderunner.http.ContentType;
import net.noderunner.http.HttpUtil;
import net.noderunner.http.MessageHeader;
import net.noderunner.http.MessageHeaders;
import net.noderunner.http.ServerRequest;
/**
* Simple HTTP servlet request.
* @author Elias Ross
*/
public class HttpServletRequestImpl implements HttpServletRequest {
private final ServerRequest request;
private final InputStream inputStream;
private final Map<String, String[]> parameters = new HashMap<String, String[]>();
private final Map<String, Object> attributes = new HashMap<String, Object>();
private BasicHttpSession session;
private String serverName;
private int serverPort;
private String remoteHost;
private int remotePort;
private String remoteAddr;
private String localAddr;
private String localName;
private int localPort;
private String encoding;
private boolean initParams = false;
/**
* Constructs a new HttpServletRequestImpl based on a server request.
*/
public HttpServletRequestImpl(ServerRequest request) throws IOException {
this.request = request;
this.encoding = getCharacterEncoding0();
try {
URI uri = new URI(request.getRequestLine().getRequestURI());
String rq = uri.getRawQuery();
if (rq != null) {
parameters.putAll(HttpUtil.urlDecode(uri.getRawQuery()));
}
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
inputStream =
HttpUtil.uncloseableInputStream(
HttpUtil.wrapInputStream(request.getInputStream(), request.getHeaders()));
}
void serverSocket(ServerSocket ss) {
serverName = ss.getLocalSocketAddress().toString();
localName = ss.getLocalSocketAddress().toString();
localAddr = ss.getLocalSocketAddress().toString();
serverPort = ss.getLocalPort();
localPort = ss.getLocalPort();
}
void remoteAddress(InetSocketAddress address) {
remoteHost = address.getHostName();
remoteAddr = address.getAddress().getHostAddress();
remotePort = address.getPort();
}
public String getAuthType() {
return null;
}
private String getURI() {
String uri = request.getRequestLine().getRequestURI();
return uri;
}
public String getContextPath() {
return getURI();
}
public Cookie[] getCookies() {
return new Cookie[0];
}
public long getDateHeader(String fieldName) {
try {
Date date = new HttpDateFormat().parse(getHeader(fieldName));
return date.getTime();
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public String getHeader(String fieldName) {
return request.getHeaders().getFieldContent(fieldName);
}
public Enumeration<String> getHeaderNames() {
return Collections.enumeration(request.getHeaders().getNames());
}
public Enumeration<Object> getHeaders(String arg0) {
throw new UnsupportedOperationException();
}
public int getIntHeader(String fieldName) {
return Integer.parseInt(getHeader(fieldName));
}
public String getMethod() {
return request.getRequestLine().getMethod().name();
}
public String getPathInfo() {
return getURI();
}
public String getPathTranslated() {
return getURI();
}
public String getQueryString() {
return getURI();
}
public String getRemoteUser() {
return null;
}
public String getRequestURI() {
return getURI();
}
public StringBuffer getRequestURL() {
return new StringBuffer(getURI());
}
public String getRequestedSessionId() {
return null;
}
public String getServletPath() {
return getURI();
}
public HttpSession getSession() {
if (session == null)
this.session = new BasicHttpSession();
return session;
}
public HttpSession getSession(boolean create) {
if (!create)
return session;
return getSession();
}
public Principal getUserPrincipal() {
return null;
}
public boolean isRequestedSessionIdFromCookie() {
return false;
}
public boolean isRequestedSessionIdFromURL() {
return false;
}
public boolean isRequestedSessionIdFromUrl() {
return false;
}
public boolean isRequestedSessionIdValid() {
return false;
}
public boolean isUserInRole(String arg0) {
return false;
}
public Object getAttribute(String key) {
return attributes.get(key);
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(attributes.keySet());
}
private String getCharacterEncoding0() {
String ct = getHeader(MessageHeader.FN_CONTENT_TYPE);
if (ct == null)
return null;
String enc = ContentType.parse(ct).getParameterValue("encoding");
return enc;
}
public String getCharacterEncoding() {
return encoding;
}
public int getContentLength() {
String cl = getHeader("content-length");
if (cl == null)
return -1;
return Integer.parseInt(cl);
}
public String getContentType() {
return getHeader("content-type");
}
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStream() {
@Override
public int read(byte[] b, int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
@Override
public int read() throws IOException {
return inputStream.read();
}
};
}
public String getLocalAddr() {
return localAddr;
}
public String getLocalName() {
return localName;
}
public int getLocalPort() {
return localPort;
}
public Locale getLocale() {
return Locale.getDefault();
}
public Enumeration<Locale> getLocales() {
return Collections.enumeration(Collections.singleton(getLocale()));
}
public String getParameter(String key) {
initParams();
String[] sa = parameters.get(key);
if (sa == null)
return null;
return sa[0];
}
public Map<String, String[]> getParameterMap() {
initParams();
return parameters;
}
public Enumeration<String> getParameterNames() {
initParams();
return Collections.enumeration(parameters.keySet());
}
private void initParams() {
if (initParams)
return;
MessageHeaders headers = request.getHeaders();
// TODO decide of headers should be read or not
if (headers.contains(MessageHeader.MH_URL_ENCODED)) {
try {
parameters.putAll(HttpUtil.urlDecode(inputStream));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
initParams = true;
}
public String[] getParameterValues(String key) {
return parameters.get(key);
}
public String getProtocol() {
return "http";
}
public BufferedReader getReader() throws IOException {
InputStreamReader isr;
if (encoding == null)
isr = new InputStreamReader(inputStream);
else
isr = new InputStreamReader(inputStream, encoding);
return new BufferedReader(isr);
}
public String getRealPath(String arg0) {
return getURI();
}
public String getRemoteAddr() {
return remoteAddr;
}
public String getRemoteHost() {
return remoteHost;
}
public int getRemotePort() {
return remotePort;
}
public RequestDispatcher getRequestDispatcher(String arg0) {
throw new UnsupportedOperationException();
}
public String getScheme() {
return "http";
}
public String getServerName() {
return serverName;
}
public int getServerPort() {
return serverPort;
}
public boolean isSecure() {
return false;
}
public void removeAttribute(String key) {
attributes.remove(key);
}
public void setAttribute(String key, Object value) {
attributes.put(key, value);
}
public void setCharacterEncoding(String encoding)
throws UnsupportedEncodingException {
Charset.forName(encoding);
this.encoding = encoding;
}
public String toString() {
return super.toString() + " p=" + parameters;
}
}