httplite: re-update code after project re-org
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1214819 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/Activator.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/Activator.java
index a5f0cb6..8974c24 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/Activator.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/Activator.java
@@ -148,6 +148,8 @@
*/
public void stop(final BundleContext context) throws Exception
{
+ m_server.setStopping();
+
if (m_httpServiceReg != null)
{
m_httpServiceReg.unregister();
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/HttpServiceImpl.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/HttpServiceImpl.java
index c5ef61d..b85dded 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/HttpServiceImpl.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/osgi/HttpServiceImpl.java
@@ -91,6 +91,8 @@
public void registerResources(final String alias, final String name,
final HttpContext context) throws NamespaceException
{
+ validateAlias(alias);
+
synchronized (m_servletMap)
{
if (m_servletMap.containsKey(alias))
@@ -160,6 +162,8 @@
final Dictionary initparams, final HttpContext context) throws ServletException,
NamespaceException
{
+ validateAlias(alias);
+
if (m_servletMap.containsKey(alias))
{
throw new NamespaceException("Alias " + alias
@@ -286,7 +290,7 @@
}
else
{
- return new ResourceHandler(request, response, element);
+ return new ResourceHandler(request, response, element, m_logger);
}
}
@@ -316,4 +320,27 @@
return new HttpServletResponseImpl(output);
}
+ /**
+ * Validate that a given alias is legal.
+ *
+ * @param alias input alias
+ * @throws NamespaceException is thrown if alias is illegal
+ */
+ private void validateAlias( String alias ) throws NamespaceException
+ {
+ if (alias == null)
+ {
+ throw new NamespaceException( "Alias is null." );
+ }
+
+ if (alias.trim().length() == 0)
+ {
+ throw new NamespaceException( "Alias is an empty string." );
+ }
+
+ if (!alias.startsWith( "/" ))
+ {
+ throw new NamespaceException( "Alias must begin with '/'." );
+ }
+ }
}
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Connection.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Connection.java
index d5ffcb5..4b1d95d 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Connection.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Connection.java
@@ -181,8 +181,8 @@
boolean error = false;
m_logger.log(Logger.LOG_DEBUG,
- "Processing request (" + (m_requestLimit - m_requestCount)
- + " remaining) : " + request.getRequestURI());
+ "Processing " + request.getRequestURI() + " (" + (m_requestLimit - m_requestCount)
+ + " remaining)");
// If client is HTTP/1.1, then send continue message.
if (request.getProtocol().equals(HttpConstants.HTTP11_VERSION))
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/ResourceHandler.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/ResourceHandler.java
index 323cafe..ae0be7c 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/ResourceHandler.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/ResourceHandler.java
@@ -22,6 +22,9 @@
import java.io.InputStream;
import java.net.URL;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.httplite.osgi.Logger;
import org.apache.felix.httplite.osgi.ServiceRegistration;
import org.apache.felix.httplite.osgi.ServiceRegistrationHandler;
import org.apache.felix.httplite.servlet.HttpConstants;
@@ -38,19 +41,22 @@
public class ResourceHandler implements ServiceRegistrationHandler
{
- private final HttpServletRequestImpl m_request;
+ private static final String INDEX_HTML = "index.html";
+ private final HttpServletRequestImpl m_request;
private final HttpServletResponseImpl m_response;
private final HttpContext m_httpContext;
private final String m_name;
private final String m_alias;
+ private final Logger m_logger;
/**
* @param req HttpRequest
* @param res HttpResponse
* @param resource ServiceRegistration
+ * @param logger Log reference
*/
- public ResourceHandler(final HttpServletRequestImpl req, final HttpServletResponseImpl res, final ServiceRegistration resource)
+ public ResourceHandler(final HttpServletRequestImpl req, final HttpServletResponseImpl res, final ServiceRegistration resource, final Logger logger)
{
if (resource.isServlet())
{
@@ -62,7 +68,8 @@
this.m_response = res;
this.m_httpContext = resource.getContext();
this.m_name = resource.getName();
- this.m_alias = resource.getAlias();
+ this.m_alias = resource.getAlias();
+ this.m_logger = logger;
}
/* (non-Javadoc)
@@ -75,18 +82,31 @@
{
//POST, PUT, DELETE operations not valid on resources.
+ m_logger.log(Logger.LOG_WARNING, "Ignored client " + m_request.getMethod() + " on static resource.");
return;
}
if (m_httpContext.handleSecurity(m_request, m_response))
{
String resourceName = getResourceName(m_request.getRequestURI());
-
- URL resource = m_httpContext.getResource(resourceName);
-
+
+ URL resource = null;
+
+ if (resourceName.endsWith("/"))
+ {
+ m_logger.log(Logger.LOG_DEBUG, "Appending " + INDEX_HTML + " to request " + resourceName);
+ resource = m_httpContext.getResource(resourceName + INDEX_HTML);
+ }
+ else
+ {
+ resource = m_httpContext.getResource(resourceName);
+ }
+
if (resource == null)
{
- throw new IOException("Unable to find resource: " + resourceName);
+ m_logger.log(Logger.LOG_INFO, "Returning HTTP 404 for request for " + resourceName);
+ m_response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
}
InputStream inputStream = resource.openStream();
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Server.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Server.java
index b0b2048..926419d 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Server.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/server/Server.java
@@ -106,6 +106,11 @@
private final int m_connectionRequestLimit;
private ServiceRegistrationResolver m_resolver;
private final Logger m_logger;
+
+ /**
+ * Set to true when bundle is in a stopping state. Socket errors will be ignored.
+ */
+ private boolean m_stopping = false;
/**
* Construct a web server with the specified configuration. The configuration
@@ -344,8 +349,11 @@
}
catch (IOException ex)
{
- m_logger.log(Logger.LOG_ERROR,
- "The call to accept() terminated with an exception.", ex);
+ if (!m_stopping)
+ {
+ m_logger.log(Logger.LOG_ERROR,
+ "The call to accept() terminated with an exception.", ex);
+ }
}
}
@@ -387,4 +395,16 @@
}
m_logger.log(Logger.LOG_DEBUG, "Shutdown complete.");
}
+
+ /**
+ * Sets the stopping flag to true. Socket exceptions will not be logged. Method can only be called once.
+ */
+ public void setStopping() {
+ if (m_stopping)
+ {
+ throw new IllegalStateException("setStopping() called multiple times.");
+ }
+
+ m_stopping = true;
+ }
}
\ No newline at end of file
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletRequestImpl.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletRequestImpl.java
index bff22e7..e4ca6e2 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletRequestImpl.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletRequestImpl.java
@@ -197,16 +197,6 @@
m_uri = st.nextToken();
m_version = st.nextToken();
- // If the URI is absolute, break into host and path.
- m_uriHost = "";
- int hostIdx = m_uri.indexOf("//");
- if (hostIdx > 0)
- {
- int pathIdx = m_uri.indexOf("/", hostIdx + 2);
- m_uriHost = m_uri.substring(hostIdx + 2, pathIdx);
- m_uri = m_uri.substring(pathIdx);
- }
-
// If the URI has query string, parse it.
int qsIdx = m_uri.indexOf("?");
if (qsIdx > 0)
@@ -214,6 +204,47 @@
m_queryString = m_uri.substring(qsIdx + 1);
m_uri = m_uri.substring(0, qsIdx);
}
+
+ // If path contains multiple successive path separators (a//b/c a/b////c, etc.), strip them.
+ if (m_uri.indexOf( "//" ) > -1)
+ {
+ // separator
+
+ m_uri = stripRedundantSeparators(m_uri);
+ }
+ }
+
+ /**
+ * Remove successive '/' characters.
+ *
+ * @param in input string
+ * @return stripped string
+ */
+ private String stripRedundantSeparators( String in )
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean lastIsSeparator = false;
+
+ for (int i = 0; i < in.length(); ++i)
+ {
+ char c = in.charAt( i );
+
+ if (lastIsSeparator && c == '/')
+ {
+ continue;
+ }
+
+ sb.append( c );
+
+ if (c == '/')
+ {
+ lastIsSeparator = true;
+ } else {
+ lastIsSeparator = false;
+ }
+ }
+
+ return sb.toString();
}
/**
@@ -230,7 +261,7 @@
* If any I/O error occurs.
**/
public void parseHeader(final ConcreteServletInputStream is) throws IOException
- {
+ {
for (String s = is.readLine(); (s != null) && (s.length() != 0); s = is.readLine())
{
int idx = s.indexOf(":");
@@ -268,6 +299,11 @@
}
}
}
+
+ if (m_headers.containsKey( "Host" ))
+ {
+ m_uriHost = m_headers.get( "Host" ).toString();
+ }
}
/**
@@ -502,6 +538,19 @@
*/
public Map getParameterMap()
{
+ if (m_parameters == null)
+ {
+ try
+ {
+ m_parameters = parseParameters();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ m_logger.log(Logger.LOG_ERROR, "Failed to parse request parameters.", e);
+ return null;
+ }
+ }
+
return m_parameters;
}
@@ -512,6 +561,19 @@
*/
public Enumeration getParameterNames()
{
+ if (m_parameters == null)
+ {
+ try
+ {
+ m_parameters = parseParameters();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ m_logger.log(Logger.LOG_ERROR, "Failed to parse request parameters.", e);
+ return null;
+ }
+ }
+
return Collections.enumeration(m_parameters.keySet());
}
@@ -522,6 +584,19 @@
*/
public String[] getParameterValues(String arg0)
{
+ if (m_parameters == null)
+ {
+ try
+ {
+ m_parameters = parseParameters();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ m_logger.log(Logger.LOG_ERROR, "Failed to parse request parameters.", e);
+ return null;
+ }
+ }
+
return (String[]) m_parameters.values().toArray(new String[m_parameters.size()]);
}
@@ -810,7 +885,10 @@
public StringBuffer getRequestURL()
{
StringBuffer sb = new StringBuffer();
- sb.append(m_uriHost);
+ if (m_uriHost != null)
+ {
+ sb.append(m_uriHost);
+ }
sb.append(m_uri);
return sb;
@@ -903,12 +981,12 @@
parseParameterString(queryString, params);
}
- if (m_requestBody != null)
+ if (m_requestBody != null && m_requestBody.length > 0)
{
parseParameterString(new String(m_requestBody), params);
}
- return params;
+ return Collections.unmodifiableMap( params );
}
/**
@@ -957,7 +1035,7 @@
{
if (m_method != null && m_uri != null)
{
- return m_method + m_uri;
+ return m_method + " " + m_uri;
}
return super.toString();
diff --git a/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletResponseImpl.java b/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletResponseImpl.java
index 5c7025b..45dd509 100644
--- a/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletResponseImpl.java
+++ b/httplite/minimum/src/main/java/org/apache/felix/httplite/servlet/HttpServletResponseImpl.java
@@ -60,7 +60,7 @@
private boolean m_getOutputStreamCalled = false;
private boolean m_getWriterCalled = false;
private ServletOutputStreamImpl m_servletOutputStream;
- private ServletPrintWriter m_servletPrintWriter;
+ private PrintWriter m_servletPrintWriter;
private int m_statusCode = HttpURLConnection.HTTP_OK;
private String m_customStatusMessage = null;
@@ -341,8 +341,7 @@
if (m_servletPrintWriter == null)
{
m_buffer = new ByteArrayOutputStream(m_bufferSize);
- m_servletPrintWriter = new ServletPrintWriter(m_buffer,
- getCharacterEncoding());
+ m_servletPrintWriter = new PrintWriter(m_buffer);
}
return m_servletPrintWriter;
@@ -665,8 +664,12 @@
buffer.append(' ');
buffer.append(code);
buffer.append(' ');
- buffer.append("HTTP Error ");
- buffer.append(code);
+
+ if (code > 399)
+ {
+ buffer.append("HTTP Error ");
+ buffer.append(code);
+ }
buffer.append(HttpConstants.HEADER_DELEMITER);
if (code == 100)
{
@@ -698,6 +701,7 @@
//Only append error HTML messages if the return code is in the error range.
if (code > 399)
{
+ //TODO: Consider disabling the HTML generation, optionally, so clients have full control of the response content.
if (htmlStartTag == null)
{
htmlStartTag = HttpConstants.DEFAULT_HTML_HEADER;