Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-server/src/main/java/org/eclipse/jetty/server/Request.java')
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Request.java203
1 files changed, 195 insertions, 8 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index 021e60e77c..b873977d95 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -19,6 +19,8 @@
package org.eclipse.jetty.server;
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -37,16 +39,26 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.DispatcherType;
+import javax.servlet.MultipartConfigElement;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
@@ -61,6 +73,7 @@ import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
@@ -69,8 +82,11 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.MultiPartInputStream;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.UrlEncoded;
@@ -111,12 +127,51 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class Request implements HttpServletRequest
{
+ public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig";
+ public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream";
+ public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext";
private static final Logger LOG = Log.getLogger(Request.class);
private static final String __ASYNC_FWD = "org.eclipse.asyncfwd";
private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
private static final int __NONE = 0, _STREAM = 1, __READER = 2;
+ public static class MultiPartCleanerListener implements ServletRequestListener
+ {
+
+ @Override
+ public void requestDestroyed(ServletRequestEvent sre)
+ {
+ //Clean up any tmp files created by MultiPartInputStream
+ MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM);
+ if (mpis != null)
+ {
+ ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT);
+
+ //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files
+ if (context == sre.getServletContext())
+ {
+ try
+ {
+ mpis.deleteParts();
+ }
+ catch (MultiException e)
+ {
+ sre.getServletContext().log("Errors deleting multipart tmp files", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void requestInitialized(ServletRequestEvent sre)
+ {
+ //nothing to do, multipart config set up by ServletHolder.handle()
+ }
+
+ }
+
+
/* ------------------------------------------------------------ */
public static Request getRequest(HttpServletRequest request)
{
@@ -170,7 +225,9 @@ public class Request implements HttpServletRequest
private Buffer _timeStampBuffer;
private HttpURI _uri;
-
+
+ private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime
+
/* ------------------------------------------------------------ */
public Request()
{
@@ -188,7 +245,9 @@ public class Request implements HttpServletRequest
if (listener instanceof ServletRequestAttributeListener)
_requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener);
if (listener instanceof ContinuationListener)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException(listener.getClass().toString());
+ if (listener instanceof AsyncListener)
+ throw new IllegalArgumentException(listener.getClass().toString());
}
/* ------------------------------------------------------------ */
@@ -306,6 +365,7 @@ public class Request implements HttpServletRequest
}
}
}
+
}
if (_parameters == null)
@@ -323,6 +383,28 @@ public class Request implements HttpServletRequest
_parameters.add(name,LazyList.get(values,i));
}
}
+
+ if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null)
+ {
+ try
+ {
+ getParts();
+ }
+ catch (IOException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.warn(e);
+ else
+ LOG.warn(e.toString());
+ }
+ catch (ServletException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.warn(e);
+ else
+ LOG.warn(e.toString());
+ }
+ }
}
finally
{
@@ -345,7 +427,7 @@ public class Request implements HttpServletRequest
{
return _async;
}
-
+
/* ------------------------------------------------------------ */
/*
* @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
@@ -401,8 +483,8 @@ public class Request implements HttpServletRequest
public String getAuthType()
{
if (_authentication instanceof Authentication.Deferred)
- _authentication = ((Authentication.Deferred)_authentication).authenticate(this);
-
+ setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
+
if (_authentication instanceof Authentication.User)
return ((Authentication.User)_authentication).getAuthMethod();
return null;
@@ -1279,6 +1361,7 @@ public class Request implements HttpServletRequest
UserIdentity user = ((Authentication.User)_authentication).getUserIdentity();
return user.getUserPrincipal();
}
+
return null;
}
@@ -1299,6 +1382,12 @@ public class Request implements HttpServletRequest
return _handled;
}
+ public boolean isAsyncStarted()
+ {
+ return _async.isAsyncStarted();
+ }
+
+
/* ------------------------------------------------------------ */
public boolean isAsyncSupported()
{
@@ -1434,7 +1523,8 @@ public class Request implements HttpServletRequest
if (_savedNewSessions != null)
_savedNewSessions.clear();
- _savedNewSessions = null;
+ _savedNewSessions=null;
+ _multiPartInputStream = null;
}
/* ------------------------------------------------------------ */
@@ -1915,7 +2005,7 @@ public class Request implements HttpServletRequest
{
if (!_asyncSupported)
throw new IllegalStateException("!asyncSupported");
- _async.suspend();
+ _async.startAsync();
return _async;
}
@@ -1924,7 +2014,7 @@ public class Request implements HttpServletRequest
{
if (!_asyncSupported)
throw new IllegalStateException("!asyncSupported");
- _async.suspend(_context,servletRequest,servletResponse);
+ _async.startAsync(_context,servletRequest,servletResponse);
return _async;
}
@@ -1936,6 +2026,103 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
+ public boolean authenticate(HttpServletResponse response) throws IOException, ServletException
+ {
+ if (_authentication instanceof Authentication.Deferred)
+ {
+ setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response));
+ return !(_authentication instanceof Authentication.ResponseSent);
+ }
+ response.sendError(HttpStatus.UNAUTHORIZED_401);
+ return false;
+ }
+
+ /* ------------------------------------------------------------ */
+ public Part getPart(String name) throws IOException, ServletException
+ {
+ getParts();
+ return _multiPartInputStream.getPart(name);
+ }
+
+ /* ------------------------------------------------------------ */
+ public Collection<Part> getParts() throws IOException, ServletException
+ {
+ if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
+ throw new ServletException("Content-Type != multipart/form-data");
+
+ if (_multiPartInputStream == null)
+ _multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM);
+
+ if (_multiPartInputStream == null)
+ {
+ MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
+
+ if (config == null)
+ throw new IllegalStateException("No multipart config for servlet");
+
+ _multiPartInputStream = new MultiPartInputStream(getInputStream(),
+ getContentType(), config,
+ (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
+
+ setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
+ setAttribute(__MULTIPART_CONTEXT, _context);
+ Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing
+ for (Part p:parts)
+ {
+ MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p;
+ if (mp.getContentDispositionFilename() == null)
+ {
+ //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
+ String charset = null;
+ if (mp.getContentType() != null)
+ charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType()));
+
+ ByteArrayOutputStream os = null;
+ InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file
+ try
+ {
+ os = new ByteArrayOutputStream();
+ IO.copy(is, os);
+ String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset);
+ getParameter(""); //cause params to be evaluated
+ getParameters().add(mp.getName(), content);
+ }
+ finally
+ {
+ IO.close(os);
+ IO.close(is);
+ }
+ }
+ }
+ }
+
+ return _multiPartInputStream.getParts();
+ }
+
+ /* ------------------------------------------------------------ */
+ public void login(String username, String password) throws ServletException
+ {
+ if (_authentication instanceof Authentication.Deferred)
+ {
+ _authentication=((Authentication.Deferred)_authentication).login(username,password,this);
+ if (_authentication == null)
+ throw new ServletException();
+ }
+ else
+ {
+ throw new ServletException("Authenticated as "+_authentication);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public void logout() throws ServletException
+ {
+ if (_authentication instanceof Authentication.User)
+ ((Authentication.User)_authentication).logout();
+ _authentication=Authentication.UNAUTHENTICATED;
+ }
+
+ /* ------------------------------------------------------------ */
/**
* Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and
* {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method.

Back to the top