FELIX-55 Upgrade to Jetty 6.1.7 and export Servlet API 2.5 from within the bundle
FELIX-434 Support remote user and authentication type API when using handleSecurity()
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@641218 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http.jetty/pom.xml b/http.jetty/pom.xml
index 259cdb0..ad5e7f4 100644
--- a/http.jetty/pom.xml
+++ b/http.jetty/pom.xml
@@ -1,81 +1,110 @@
<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.apache.felix</groupId>
- <artifactId>felix</artifactId>
- <version>1.0.2</version>
- <relativePath>../pom/pom.xml</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <name>Apache Felix HTTP Service</name>
- <version>0.9.0-SNAPSHOT</version>
- <artifactId>org.apache.felix.http.jetty</artifactId>
- <dependencies>
- <dependency>
- <groupId>${pom.groupId}</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>${pom.groupId}</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>1.0.0</version>
- </dependency>
- <dependency>
- <groupId>${pom.groupId}</groupId>
- <artifactId>javax.servlet</artifactId>
- <version>1.0.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>jetty</groupId>
- <artifactId>org.mortbay.jetty-jdk1.2</artifactId>
- <version>4.2.25</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
+ <parent>
<groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>1.4.0</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>HTTP Service</Bundle-Name>
- <Bundle-Description>An implementation of the OSGi HTTP Service using Jetty.</Bundle-Description>
- <Bundle-Activator>${pom.artifactId}.Activator</Bundle-Activator>
- <Bundle-DocURL>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</Bundle-DocURL>
- <Bundle-URL>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</Bundle-URL>
- <Bundle-Source>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</Bundle-Source>
- <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
- <DynamicImport-Package>javax.net.ssl</DynamicImport-Package>
- <Export-Package>org.osgi.service.http; version=1.1</Export-Package>
- <Import-Package>!com.sun.net.ssl.internal.ssl,!com.sun.net.ssl,!org.xml.sax,!org.xml.sax.helpers,!javax.xml.parsers,!javax.security.cert,javax.servlet;version=1.1, javax.servlet.http;version=1.1,*</Import-Package>
- <Private-Package>org.apache.felix.http.jetty, org.mortbay.*;-split-package:=merge-first</Private-Package>
- <Export-Service>org.osgi.service.http.HttpService</Export-Service>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <artifactId>felix</artifactId>
+ <version>1.0.2</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>bundle</packaging>
+ <name>Apache Felix HTTP Service</name>
+ <version>0.9.0-SNAPSHOT</version>
+ <artifactId>org.apache.felix.http.jetty</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>1.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>1.0.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>javax.servlet</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api-2.5</artifactId>
+ <version>6.1.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ <version>6.1.7</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>HTTP Service</Bundle-Name>
+ <Bundle-Description>
+ An implementation of the OSGi HTTP Service
+ using Jetty.
+ </Bundle-Description>
+ <Bundle-Activator>
+ ${pom.artifactId}.Activator
+ </Bundle-Activator>
+ <Bundle-DocURL>
+ http://oscar-osgi.sf.net/obr2/${pom.artifactId}/
+ </Bundle-DocURL>
+ <Bundle-URL>
+ http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar
+ </Bundle-URL>
+ <Bundle-Source>
+ http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar
+ </Bundle-Source>
+ <Bundle-SymbolicName>
+ ${pom.artifactId}
+ </Bundle-SymbolicName>
+ <Export-Package>
+ org.osgi.service.http; version=1.1,
+ javax.servlet;javax.servlet.http;version=2.5
+ </Export-Package>
+ <Private-Package>
+ org.apache.felix.http.jetty,
+ org.mortbay.*;-split-package:=merge-first
+ </Private-Package>
+ <Import-Package>
+ javax.net.ssl; javax.security.cert;
+ javax.xml.parsers; org.xml.sax;
+ org.xml.sax.helpers;
+ org.slf4j;resolution:=optional, *
+ </Import-Package>
+ <Export-Service>
+ org.osgi.service.http.HttpService
+ </Export-Service>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/http.jetty/src/main/java/org/apache/felix/http/jetty/Activator.java b/http.jetty/src/main/java/org/apache/felix/http/jetty/Activator.java
index 20bd058..c1a91f6 100644
--- a/http.jetty/src/main/java/org/apache/felix/http/jetty/Activator.java
+++ b/http.jetty/src/main/java/org/apache/felix/http/jetty/Activator.java
@@ -19,16 +19,18 @@
package org.apache.felix.http.jetty;
-import java.lang.reflect.Constructor;
-
-import org.mortbay.http.HashUserRealm;
-import org.mortbay.http.HttpServer;
-import org.mortbay.http.JsseListener;
-import org.mortbay.http.SocketListener;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.HandlerCollection;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.HashUserRealm;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.OsgiServletHandler;
-import org.mortbay.jetty.servlet.ServletHttpContext;
-import org.mortbay.util.Code;
-import org.mortbay.util.InetAddrPort;
+import org.mortbay.jetty.servlet.SessionHandler;
+import org.mortbay.log.Log;
+import org.mortbay.log.Logger;
+import org.mortbay.log.StdErrLog;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -36,6 +38,8 @@
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.HttpService;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
/**
@@ -63,11 +67,12 @@
public class Activator implements BundleActivator
{
protected static boolean debug = false;
+ private static ServiceTracker m_logTracker = null;
private BundleContext m_bundleContext = null;
private ServiceRegistration m_svcReg = null;
private HttpServiceFactory m_httpServ = null;
- private HttpServer m_server = null;
+ private Server m_server = null;
private OsgiServletHandler m_hdlr = null;
private int m_httpPort;
@@ -84,10 +89,9 @@
String optDebug = m_bundleContext.getProperty( "org.apache.felix.http.jetty.debug" );
if ( optDebug != null && optDebug.toLowerCase().equals( "true" ) )
{
- Code.setDebug( true );
debug = true;
}
-
+
// get default HTTP and HTTPS ports as per the OSGi spec
try
{
@@ -110,6 +114,12 @@
m_httpsPort = 443;
}
+ m_logTracker = new ServiceTracker( bundleContext, LogService.class.getName(), null );
+ m_logTracker.open();
+
+ // set the Jetty logger to be LogService based
+ initializeJettyLogger();
+
try
{
initializeJetty();
@@ -118,7 +128,7 @@
catch ( Exception ex )
{
//TODO: maybe throw a bundle exception in here?
- System.out.println( "Http2: " + ex );
+ log( LogService.LOG_INFO, "Http2", ex );
return;
}
@@ -144,9 +154,29 @@
{
//TODO: log some form of error
}
+
+ // replace non-LogService logger for jetty
+ Log.setLog( new StdErrLog() );
+
+ m_logTracker.close();
}
+ protected void initializeJettyLogger() {
+ String oldProperty = System.getProperty( "org.mortbay.log.class" );
+ System.setProperty( "org.mortbay.log.class", LogServiceLog.class.getName() );
+
+ if (!(Log.getLog() instanceof LogServiceLog)) {
+ Log.setLog( new LogServiceLog() );
+ }
+
+ Log.getLog().setDebugEnabled( debug );
+
+ if (oldProperty != null) {
+ System.setProperty( "org.mortbay.log.class", oldProperty );
+ }
+ }
+
protected void initializeJetty() throws Exception
{
//TODO: Maybe create a separate "JettyServer" object here?
@@ -154,13 +184,14 @@
HashUserRealm realm = new HashUserRealm( "OSGi HTTP Service Realm" );
// Create server
- m_server = new HttpServer();
- m_server.addRealm( realm );
+ m_server = new Server();
+ m_server.addUserRealm( realm );
// Add a regular HTTP listener
- SocketListener listener = null;
- listener = ( SocketListener ) m_server.addListener( new InetAddrPort( m_httpPort ) );
- listener.setMaxIdleTimeMs( 60000 );
+ Connector connector = new SelectChannelConnector();
+ connector.setPort( m_httpPort );
+ connector.setMaxIdleTime( 60000 );
+ m_server.addConnector( connector );
// See if we need to add an HTTPS listener
String enableHTTPS = m_bundleContext.getProperty( "org.ungoverned.osgi.bundle.https.enable" );
@@ -169,20 +200,13 @@
initializeHTTPS();
}
- m_server.start();
-
// setup the Jetty web application context shared by all Http services
- ServletHttpContext hdlrContext = new ServletHttpContext();
- hdlrContext.setContextPath( "/" );
- //TODO: was in original code, but seems we shouldn't serve
- // resources in servlet context
- //hdlrContext.setServingResources(true);
- hdlrContext.setClassLoader( getClass().getClassLoader() );
- debug( " adding handler context : " + hdlrContext );
- m_server.addContext( hdlrContext );
-
m_hdlr = new OsgiServletHandler();
- hdlrContext.addHandler( m_hdlr );
+
+ Context hdlrContext = new Context( m_server, new SessionHandler(), null, m_hdlr, null );
+ hdlrContext.setClassLoader( getClass().getClassLoader() );
+ hdlrContext.setContextPath( "/" );
+ debug( " adding handler context : " + hdlrContext );
try
{
@@ -191,9 +215,10 @@
catch ( Exception e )
{
// make sure we unwind the adding process
- System.err.println( "Exception Starting Jetty Handler Context: " + e );
- e.printStackTrace( System.err );
+ log( LogService.LOG_ERROR, "Exception Starting Jetty Handler Context", e );
}
+
+ m_server.start();
}
@@ -208,45 +233,60 @@
sslProvider = "org.mortbay.http.SunJsseListener";
}
+
+ SslSocketConnector s_listener = new SslSocketConnector();
+ s_listener.setPort( m_httpsPort );
+ s_listener.setMaxIdleTime( 60000 );
+
// Set default jetty properties for supplied values. For any not set,
// Jetty will fallback to checking system properties.
String keystore = m_bundleContext.getProperty( "org.ungoverned.osgi.bundle.https.keystore" );
if ( keystore != null )
{
- System.setProperty( JsseListener.KEYSTORE_PROPERTY, keystore );
+ s_listener.setKeystore( keystore );
}
String passwd = m_bundleContext.getProperty( "org.ungoverned.osgi.bundle.https.password" );
if ( passwd != null )
{
- System.setProperty( JsseListener.PASSWORD_PROPERTY, passwd );
+ System.setProperty( SslSocketConnector.PASSWORD_PROPERTY, passwd );
+ s_listener.setPassword( passwd );
}
String keyPasswd = m_bundleContext.getProperty( "org.ungoverned.osgi.bundle.https.key.password" );
if ( keyPasswd != null )
{
- System.setProperty( JsseListener.KEYPASSWORD_PROPERTY, keyPasswd );
+ System.setProperty( SslSocketConnector.KEYPASSWORD_PROPERTY, keyPasswd );
+ s_listener.setKeyPassword( keyPasswd );
}
- //SunJsseListener s_listener = new SunJsseListener(new InetAddrPort(m_httpsPort));
- Object args[] =
- { new InetAddrPort( m_httpsPort ) };
- Class argTypes[] =
- { args[0].getClass() };
- Class clazz = Class.forName( sslProvider );
- Constructor cstruct = clazz.getDeclaredConstructor( argTypes );
- JsseListener s_listener = ( JsseListener ) cstruct.newInstance( args );
-
- m_server.addListener( s_listener );
- s_listener.setMaxIdleTimeMs( 60000 );
+ m_server.addConnector( s_listener );
}
- protected static void debug( String txt )
+ public static void debug( String txt )
{
if ( debug )
{
- System.err.println( ">>Oscar HTTP: " + txt );
+ log( LogService.LOG_DEBUG, ">>Felix HTTP: " + txt, null );
+ }
+ }
+
+
+ public static void log( int level, String message, Throwable throwable )
+ {
+ LogService log = ( LogService ) m_logTracker.getService();
+ if ( log != null )
+ {
+ log.log( level, message, throwable );
+ }
+ else
+ {
+ System.out.println( message );
+ if ( throwable != null )
+ {
+ throwable.printStackTrace( System.out );
+ }
}
}
diff --git a/http.jetty/src/main/java/org/apache/felix/http/jetty/HttpServiceImpl.java b/http.jetty/src/main/java/org/apache/felix/http/jetty/HttpServiceImpl.java
index 29dfa6f..02995a7 100644
--- a/http.jetty/src/main/java/org/apache/felix/http/jetty/HttpServiceImpl.java
+++ b/http.jetty/src/main/java/org/apache/felix/http/jetty/HttpServiceImpl.java
@@ -30,12 +30,16 @@
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import org.mortbay.http.HttpServer;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.OsgiResourceHolder;
import org.mortbay.jetty.servlet.OsgiServletHandler;
+import org.mortbay.jetty.servlet.SessionHandler;
import org.osgi.framework.Bundle;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
+import org.osgi.service.log.LogService;
public class HttpServiceImpl implements HttpService
@@ -48,11 +52,11 @@
/** Bundle which "got" this service instance from the service factory */
private Bundle m_bundle = null;
- private HttpServer m_server = null;
+ private Server m_server = null;
private OsgiServletHandler m_serverServletHandler = null;
- public HttpServiceImpl( Bundle bundle, HttpServer server, OsgiServletHandler serverServletHandler )
+ public HttpServiceImpl( Bundle bundle, Server server, OsgiServletHandler serverServletHandler )
{
m_bundle = bundle;
m_server = server;
@@ -139,38 +143,25 @@
addAlias( alias, null );
//make sure alias is unique, and create
- org.mortbay.http.HttpContext hdlrContext = null;
+ Context hdlrContext = null;
if ( osgiHttpContext == null )
{
osgiHttpContext = createDefaultHttpContext();
}
- hdlrContext = m_server.addContext( alias );
+ // servlets using same context must get same handler to ensure
+ // they share a common ServletContext
+ Activator.debug( "looking for context: " + osgiHttpContext );
+ ServletContextGroup grp = ServletContextGroup.getServletContextGroup( m_serverServletHandler, osgiHttpContext );
- // update alias namespace with reference to context object for later
+ grp.addResource( alias, name );
+
+ // update alias namespace with reference to group object for later
// unregistering
- updateAlias( alias, hdlrContext );
+ updateAlias( alias, grp );
- // create resource handler, observing any access controls
- AccessControlContext acc = null;
- if ( System.getSecurityManager() != null )
- {
- acc = AccessController.getContext();
- }
- OsgiResourceHandler hdlr = new OsgiResourceHandler( osgiHttpContext, name, acc );
-
- hdlrContext.addHandler( hdlr );
- try
- {
- hdlrContext.start();
- }
- catch ( Exception e )
- {
- System.err.println( "Oscar exception adding resource: " + e );
- e.printStackTrace( System.err );
- // maybe we should remove alias here?
- }
+ // maybe should remove alias/servlet entries if exceptions?
}
@@ -196,34 +187,11 @@
protected void doUnregister( String alias, boolean forced )
{
- Object obj = removeAlias( alias );
-
- if ( obj instanceof org.mortbay.http.HttpContext )
+ Activator.debug( "** http unregister servlet :" + m_bundle + ", alias: " + alias + ",forced:" + forced );
+ ServletContextGroup grp = removeAlias( alias );
+ if ( grp != null )
{
- Activator.debug( "** http unregister resource :" + m_bundle + ", alias: " + alias );
-
- org.mortbay.http.HttpContext ctxt = ( org.mortbay.http.HttpContext ) obj;
- try
- {
- ctxt.stop();
- m_server.removeContext( ctxt );
- }
- catch ( Exception e )
- {
- System.err.println( "Oscar exception removing resource: " + e );
- e.printStackTrace();
- }
- }
- else if ( obj instanceof ServletContextGroup )
- {
- Activator.debug( "** http unregister servlet :" + m_bundle + ", alias: " + alias + ",forced:" + forced );
-
- ServletContextGroup grp = ( ServletContextGroup ) obj;
- grp.removeServlet( alias, forced );
- }
- else
- {
- // oops - this shouldn't happen !
+ grp.remove( alias, forced );
}
}
@@ -243,14 +211,14 @@
}
- protected Object removeAlias( String alias )
+ protected ServletContextGroup removeAlias( String alias )
{
synchronized ( m_aliasNamespace )
{
// remove alias, don't worry if doesn't exist
Object obj = m_aliasNamespace.remove( alias );
m_localAliasSet.remove( alias );
- return obj;
+ return ( ServletContextGroup ) obj;
}
}
diff --git a/http.jetty/src/main/java/org/apache/felix/http/jetty/LogServiceLog.java b/http.jetty/src/main/java/org/apache/felix/http/jetty/LogServiceLog.java
new file mode 100644
index 0000000..f439a30
--- /dev/null
+++ b/http.jetty/src/main/java/org/apache/felix/http/jetty/LogServiceLog.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.jetty;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mortbay.log.Logger;
+import org.osgi.service.log.LogService;
+
+
+public class LogServiceLog implements Logger
+{
+ private static Map loggers = new HashMap();
+
+ private final String m_name;
+
+ private boolean m_debugEnabled;
+
+
+ public LogServiceLog()
+ {
+ this( "org.mortbay.log" );
+ }
+
+
+ public LogServiceLog( String name )
+ {
+ this.m_name = name;
+ }
+
+
+ public Logger getLogger( String name )
+ {
+ Logger logger = ( Logger ) loggers.get( name );
+ if ( logger == null )
+ {
+ logger = new LogServiceLog( name );
+ logger.setDebugEnabled( isDebugEnabled() );
+ loggers.put( name, logger );
+ }
+ return logger;
+ }
+
+
+ public boolean isDebugEnabled()
+ {
+ return m_debugEnabled;
+ }
+
+
+ public void setDebugEnabled( boolean enabled )
+ {
+ this.m_debugEnabled = enabled;
+ }
+
+
+ public void debug( String msg, Throwable throwable )
+ {
+ log( LogService.LOG_DEBUG, msg, throwable );
+ }
+
+
+ public void debug( String msg, Object arg0, Object arg1 )
+ {
+ log( LogService.LOG_DEBUG, format( msg, arg0, arg1 ), null );
+ }
+
+
+ public void info( String msg, Object arg0, Object arg1 )
+ {
+ log( LogService.LOG_INFO, format( msg, arg0, arg1 ), null );
+ }
+
+
+ public void warn( String msg, Throwable throwable )
+ {
+ log( LogService.LOG_WARNING, msg, throwable );
+ }
+
+
+ public void warn( String msg, Object arg0, Object arg1 )
+ {
+ log( LogService.LOG_WARNING, format( msg, arg0, arg1 ), null );
+ }
+
+
+ public String toString()
+ {
+ return m_name;
+ }
+
+
+ private String format( String msg, Object arg0, Object arg1 )
+ {
+ int i0 = msg.indexOf( "{}" );
+ int i1 = i0 < 0 ? -1 : msg.indexOf( "{}", i0 + 2 );
+
+ if ( arg1 != null && i1 >= 0 )
+ msg = msg.substring( 0, i1 ) + arg1 + msg.substring( i1 + 2 );
+ if ( arg0 != null && i0 >= 0 )
+ msg = msg.substring( 0, i0 ) + arg0 + msg.substring( i0 + 2 );
+ return msg;
+ }
+
+
+ private void log( int level, String message, Throwable throwable )
+ {
+ Activator.log( level, m_name + ":" + message, throwable );
+ }
+}
diff --git a/http.jetty/src/main/java/org/apache/felix/http/jetty/OsgiResourceHandler.java b/http.jetty/src/main/java/org/apache/felix/http/jetty/OsgiResourceHandler.java
deleted file mode 100644
index f6c81b3..0000000
--- a/http.jetty/src/main/java/org/apache/felix/http/jetty/OsgiResourceHandler.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.http.jetty;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import org.mortbay.http.HttpException;
-import org.mortbay.http.HttpRequest;
-import org.mortbay.http.HttpResponse;
-import org.mortbay.http.handler.AbstractHttpHandler;
-import org.mortbay.jetty.servlet.DummyServletHttpRequest;
-import org.mortbay.jetty.servlet.DummyServletHttpResponse;
-import org.mortbay.jetty.servlet.OsgiServletHandler;
-import org.mortbay.jetty.servlet.ServletHttpRequest;
-import org.mortbay.jetty.servlet.ServletHttpResponse;
-import org.osgi.service.http.HttpContext;
-
-
-public class OsgiResourceHandler extends AbstractHttpHandler
-{
- protected HttpContext m_osgiHttpContext;
- protected String m_name;
- protected OsgiServletHandler m_dummyHandler;
- protected AccessControlContext m_acc;
-
-
- public OsgiResourceHandler( HttpContext osgiHttpContext, String name, AccessControlContext acc )
- {
- m_osgiHttpContext = osgiHttpContext;
- m_name = name;
- // needed for OSGi security handling
- m_dummyHandler = new OsgiServletHandler();
- m_acc = acc;
- }
-
-
- public void initialize( org.mortbay.http.HttpContext context )
- {
- super.initialize( context );
- m_dummyHandler.initialize( context );
- }
-
-
- public void handle( String pathInContext, String pathParams, HttpRequest request, HttpResponse response )
- throws HttpException, IOException
- {
- Activator.debug( "handle for name:" + m_name + "(path=" + pathInContext + ")" );
-
- ServletHttpRequest servletRequest = new DummyServletHttpRequest( m_dummyHandler, pathInContext, request );
- ServletHttpResponse servletResponse = new DummyServletHttpResponse( servletRequest, response );
-
- if ( !m_osgiHttpContext.handleSecurity( servletRequest, servletResponse ) )
- {
- // spec doesn't state specific processing here apart from
- // "send the response back to the client". We take this to mean
- // any response generated in the context, and so all we do here
- // is set handled to "true" to ensure any output is sent back
- request.setHandled( true );
- return;
- }
-
- // Create resource based name and see if we can resolve it
- String resName = m_name + pathInContext;
- Activator.debug( "** looking for: " + resName );
- URL url = m_osgiHttpContext.getResource( resName );
-
- if ( url == null )
- {
- return;
- }
-
- Activator.debug( "serving up:" + resName );
-
- // It doesn't state so in the OSGi spec, but can't see how anything
- // other than GET and variants would be supported
- String method = request.getMethod();
- if ( method.equals( HttpRequest.__GET ) || method.equals( HttpRequest.__POST )
- || method.equals( HttpRequest.__HEAD ) )
- {
- handleGet( request, response, url, resName );
- }
- else
- {
- try
- {
- response.sendError( HttpResponse.__501_Not_Implemented );
- }
- catch ( Exception e )
- {/*TODO: include error logging*/
- }
- }
- }
-
-
- public void handleGet( HttpRequest request, final HttpResponse response, final URL url, String resName )
- throws IOException
- {
- String encoding = m_osgiHttpContext.getMimeType( resName );
-
- if ( encoding == null )
- {
- encoding = getHttpContext().getMimeByExtension( resName );
- }
-
- if ( encoding == null )
- {
- encoding = getHttpContext().getMimeByExtension( ".default" );
- }
-
- //TODO: not sure why this is needed, but sometimes get "IllegalState"
- // errors if not included
- response.setAcceptTrailer( true );
- response.setContentType( encoding );
-
- //TODO: check other http fields e.g. ranges, timestamps etc.
-
- // make sure we access the resource inside the bundle's access control
- // context if supplied
- if ( System.getSecurityManager() != null )
- {
- try
- {
- AccessController.doPrivileged( new PrivilegedExceptionAction()
- {
- public Object run() throws Exception
- {
- copyResourceBytes( url, response );
- return null;
- }
- }, m_acc );
- }
- catch ( PrivilegedActionException ex )
- {
- IOException ioe = ( IOException ) ex.getException();
- throw ioe;
- }
- }
- else
- {
- copyResourceBytes( url, response );
- }
-
- request.setHandled( true );
- //TODO: set other http fields e.g. __LastModified, __ContentLength
- }
-
-
- private void copyResourceBytes( URL url, HttpResponse response ) throws IOException
- {
- OutputStream os = null;
- InputStream is = null;
-
- try
- {
- os = response.getOutputStream();
- is = url.openStream();
-
- int len = 0;
- byte[] buf = new byte[1024];
- int n = 0;
-
- while ( ( n = is.read( buf, 0, buf.length ) ) >= 0 )
- {
- os.write( buf, 0, n );
- len += n;
- }
-
- try
- {
- response.setContentLength( len );
- }
- catch ( IllegalStateException ex )
- {
- System.err.println( "OsgiResourceHandler: " + ex );
- }
- }
- finally
- {
- if ( is != null )
- {
- is.close();
- }
- if ( os != null )
- {
- os.close();
- }
- }
- }
-}
diff --git a/http.jetty/src/main/java/org/apache/felix/http/jetty/ServletContextGroup.java b/http.jetty/src/main/java/org/apache/felix/http/jetty/ServletContextGroup.java
index 069de1f..3872123 100644
--- a/http.jetty/src/main/java/org/apache/felix/http/jetty/ServletContextGroup.java
+++ b/http.jetty/src/main/java/org/apache/felix/http/jetty/ServletContextGroup.java
@@ -18,6 +18,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
@@ -31,6 +32,8 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import org.mortbay.jetty.servlet.Holder;
+import org.mortbay.jetty.servlet.OsgiResourceHolder;
import org.mortbay.jetty.servlet.OsgiServletHandler;
import org.mortbay.jetty.servlet.OsgiServletHolder;
import org.mortbay.jetty.servlet.ServletHolder;
@@ -116,22 +119,45 @@
}
- void removeServlet( String alias, boolean destroy )
+ void addResource( String alias, String path )
{
String wAlias = aliasWildcard( alias );
- OsgiServletHolder holder = m_hdlr.removeOsgiServletHolder( wAlias );
- Servlet servlet = holder.getOsgiServlet();
- Activator.debug( " removing servlet instance: " + servlet );
- m_servletSet.remove( servlet );
+ ServletHolder holder = new OsgiResourceHolder( m_hdlr, path, this );
+ m_hdlr.addOsgiServletHolder( wAlias, holder );
+ Activator.debug( " adding resources for " + wAlias + " at: " + path );
+ }
- if ( destroy )
- {
- servlet.destroy();
- }
- if ( m_servletSet.isEmpty() )
+ void remove( String alias, boolean destroy )
+ {
+ String wAlias = aliasWildcard( alias );
+ ServletHolder holder = m_hdlr.removeOsgiServletHolder( wAlias );
+
+ if ( holder != null )
{
- destroy();
+ try
+ {
+ Servlet servlet = holder.getServlet();
+ if ( servlet != null )
+ {
+ Activator.debug( " removing servlet instance: " + servlet );
+ m_servletSet.remove( servlet );
+
+ if ( destroy )
+ {
+ servlet.destroy();
+ }
+
+ if ( m_servletSet.isEmpty() )
+ {
+ destroy();
+ }
+ }
+ }
+ catch ( ServletException se )
+ {
+ // may only be thrown if servlet in holder is null
+ }
}
}
@@ -164,6 +190,12 @@
}
+ public String getContextPath()
+ {
+ return m_hdlr.getServletContext().getContextPath();
+ }
+
+
public String getMimeType( String file )
{
String type = m_osgiHttpContext.getMimeType( file );
@@ -209,18 +241,47 @@
}
+ public Set getResourcePaths( String path )
+ {
+ // This is not implemented yet, might want to access the bundle entries
+ return null;
+ }
+
+
public RequestDispatcher getRequestDispatcher( String uri )
{
return m_hdlr.getServletContext().getRequestDispatcher( uri );
}
+ public RequestDispatcher getNamedDispatcher( String name )
+ {
+ if ( getMinorVersion() >= 2 )
+ {
+ return m_hdlr.getServletContext().getNamedDispatcher( name );
+ }
+
+ return null;
+ }
+
+
public String getServerInfo()
{
return m_hdlr.getServletContext().getServerInfo();
}
+ public String getServletContextName()
+ {
+ if ( getMinorVersion() >= 3 )
+ {
+ return m_hdlr.getServletContext().getServletContextName();
+ }
+
+ return null;
+ }
+
+
public Servlet getServlet( String servletName ) throws ServletException
{
return m_hdlr.getServletContext().getServlet( servletName );
@@ -233,6 +294,28 @@
}
+ public String getInitParameter( String name )
+ {
+ if ( getMinorVersion() >= 2 )
+ {
+ return m_hdlr.getServletContext().getInitParameter( name );
+ }
+
+ return null;
+ }
+
+
+ public Enumeration getInitParameterNames()
+ {
+ if ( getMinorVersion() >= 2 )
+ {
+ return m_hdlr.getServletContext().getInitParameterNames();
+ }
+
+ return Collections.enumeration( Collections.EMPTY_LIST );
+ }
+
+
/* (non-Javadoc)
* @see javax.servlet.ServletContext#getServlets()
*/
diff --git a/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpRequest.java b/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpRequest.java
deleted file mode 100644
index b01c415..0000000
--- a/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpRequest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.mortbay.jetty.servlet;
-
-
-import org.mortbay.http.HttpRequest;
-
-
-public class DummyServletHttpRequest extends ServletHttpRequest
-{
- public DummyServletHttpRequest( ServletHandler servletHandler, String pathInContext, HttpRequest request )
- {
- super( servletHandler, pathInContext, request );
- }
-
-}
\ No newline at end of file
diff --git a/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpResponse.java b/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpResponse.java
deleted file mode 100644
index 7f0d368..0000000
--- a/http.jetty/src/main/java/org/mortbay/jetty/servlet/DummyServletHttpResponse.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.mortbay.jetty.servlet;
-
-
-import org.mortbay.http.HttpResponse;
-
-
-public class DummyServletHttpResponse extends ServletHttpResponse
-{
- public DummyServletHttpResponse( ServletHttpRequest request, HttpResponse response )
- {
- super( request, response );
- }
-
-}
diff --git a/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiResourceHolder.java b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiResourceHolder.java
new file mode 100644
index 0000000..241acb1
--- /dev/null
+++ b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiResourceHolder.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.mortbay.jetty.servlet;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.http.jetty.Activator;
+import org.apache.felix.http.jetty.ServletContextGroup;
+import org.mortbay.jetty.HttpConnection;
+import org.mortbay.jetty.HttpMethods;
+import org.mortbay.jetty.Request;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.log.LogService;
+
+
+public class OsgiResourceHolder extends ServletHolder
+{
+ private ServletContextGroup m_servletContextGroup;
+ private HttpContext m_osgiHttpContext;
+ private AccessControlContext m_acc;
+
+
+ public OsgiResourceHolder( ServletHandler handler, String name, ServletContextGroup servletContextGroup )
+ {
+ super();
+
+ setServletHandler( handler );
+ setName( name );
+
+ m_servletContextGroup = servletContextGroup;
+ m_osgiHttpContext = servletContextGroup.getOsgiHttpContext();
+
+ if ( System.getSecurityManager() != null )
+ {
+ m_acc = AccessController.getContext();
+ }
+ }
+
+
+ public synchronized Servlet getServlet()
+ {
+ return null;
+ }
+
+
+ // override "Holder" method to prevent instantiation
+ public synchronized Object newInstance()
+ {
+ return null;
+ }
+
+
+ public void handle( ServletRequest sRequest, ServletResponse sResponse ) throws ServletException, IOException
+ {
+ HttpServletRequest request = ( HttpServletRequest ) sRequest;
+ HttpServletResponse response = ( HttpServletResponse ) sResponse;
+ String target = request.getPathInfo();
+
+ Activator.debug( "handle for name:" + getName() + "(path=" + target + ")" );
+
+ if ( !m_osgiHttpContext.handleSecurity( request, response ) )
+ {
+ return;
+ }
+
+ // Create resource based name and see if we can resolve it
+ String resName = getName() + target;
+ Activator.debug( "** looking for: " + resName );
+ URL url = m_osgiHttpContext.getResource( resName );
+
+ if ( url == null )
+ {
+ Request base_request = sRequest instanceof Request ? ( Request ) sRequest : HttpConnection
+ .getCurrentConnection().getRequest();
+ base_request.setHandled( false );
+ return;
+ }
+
+ Activator.debug( "serving up:" + resName );
+
+ String method = request.getMethod();
+ if ( method.equals( HttpMethods.GET ) || method.equals( HttpMethods.POST ) || method.equals( HttpMethods.HEAD ) )
+ {
+ handleGet( request, response, url, resName );
+ }
+ else
+ {
+ try
+ {
+ response.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED );
+ }
+ catch ( Exception e )
+ {/*TODO: include error logging*/
+ }
+ }
+ }
+
+
+ public void handleGet( HttpServletRequest request, final HttpServletResponse response, final URL url, String resName )
+ throws IOException
+ {
+ String encoding = m_osgiHttpContext.getMimeType( resName );
+
+ if ( encoding == null )
+ {
+ encoding = m_servletContextGroup.getMimeType( resName );
+ }
+
+ if ( encoding == null )
+ {
+ encoding = m_servletContextGroup.getMimeType( ".default" );
+ }
+
+ //TODO: not sure why this is needed, but sometimes get "IllegalState"
+ // errors if not included
+ response.setContentType( encoding );
+
+ //TODO: check other http fields e.g. ranges, timestamps etc.
+
+ // make sure we access the resource inside the bundle's access control
+ // context if supplied
+ if ( m_acc != null )
+ {
+ try
+ {
+ AccessController.doPrivileged( new PrivilegedExceptionAction()
+ {
+ public Object run() throws Exception
+ {
+ copyResourceBytes( url, response );
+ return null;
+ }
+ }, m_acc );
+ }
+ catch ( PrivilegedActionException ex )
+ {
+ IOException ioe = ( IOException ) ex.getException();
+ throw ioe;
+ }
+ }
+ else
+ {
+ copyResourceBytes( url, response );
+ }
+
+ //TODO: set other http fields e.g. __LastModified, __ContentLength
+ }
+
+
+ private void copyResourceBytes( URL url, HttpServletResponse response ) throws IOException
+ {
+ OutputStream os = null;
+ InputStream is = null;
+
+ try
+ {
+ os = response.getOutputStream();
+ is = url.openStream();
+
+ int len = 0;
+ byte[] buf = new byte[1024];
+ int n = 0;
+
+ while ( ( n = is.read( buf, 0, buf.length ) ) >= 0 )
+ {
+ os.write( buf, 0, n );
+ len += n;
+ }
+
+ try
+ {
+ response.setContentLength( len );
+ }
+ catch ( IllegalStateException ex )
+ {
+ Activator.log( LogService.LOG_ERROR, "OsgiResourceHandler", ex );
+ }
+ }
+ finally
+ {
+ if ( is != null )
+ {
+ is.close();
+ }
+ if ( os != null )
+ {
+ os.close();
+ }
+ }
+ }
+
+
+ // override "Holder" method to prevent attempt to load
+ // the servlet class.
+ public void doStart() throws Exception
+ {
+ }
+
+
+ // override "Holder" method to prevent destroy, which is only called
+ // when a bundle manually unregisters
+ public void doStop()
+ {
+ }
+
+}
diff --git a/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHandler.java b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHandler.java
index 49da73d..beaae87 100644
--- a/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHandler.java
+++ b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHandler.java
@@ -21,13 +21,14 @@
import java.io.IOException;
import java.net.URL;
+
import javax.servlet.ServletException;
-import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.mortbay.http.PathMap;
-import org.mortbay.util.Code;
+import org.apache.felix.http.jetty.Activator;
+import org.mortbay.util.LazyList;
+import org.osgi.service.log.LogService;
public class OsgiServletHandler extends ServletHandler
@@ -35,20 +36,68 @@
// allow external adding of osgi servlet holder
public void addOsgiServletHolder( String pathSpec, ServletHolder holder )
{
- super.addServletHolder( pathSpec, holder );
+ super.addServletWithMapping( holder, pathSpec );
}
- public OsgiServletHolder removeOsgiServletHolder( String pathSpec )
+ public ServletHolder removeOsgiServletHolder( String pathSpec )
{
- OsgiServletHolder holder = ( OsgiServletHolder ) super.getServletHolder( pathSpec );
- PathMap map = super.getServletMap();
- map.remove( pathSpec );
+ ServletMapping oldMapping = null;
+ ServletMapping[] mappings = getServletMappings();
+ for ( int i = 0; i < mappings.length && oldMapping == null; i++ )
+ {
+ String[] pathSpecs = mappings[i].getPathSpecs();
+ for ( int j = 0; j < pathSpecs.length && oldMapping == null; j++ )
+ {
+ if ( pathSpec.equals( pathSpecs[j] ) )
+ {
+ oldMapping = mappings[i];
+ }
+ }
+ }
- // Remove holder from handler name map to allow re-registration.
- super._nameMap.remove( holder.getName() );
+ if ( oldMapping == null )
+ {
+ return null;
+ }
- return holder;
+ ServletHolder[] holders = getServlets();
+ if ( holders != null )
+ {
+ holders = ( ServletHolder[] ) holders.clone();
+ }
+
+ ServletHolder oldHolder = null;
+ for ( int i = 0; i < holders.length; i++ )
+ {
+ if ( oldMapping.getServletName().equals( holders[i].getName() ) )
+ {
+ oldHolder = holders[i];
+ }
+ }
+ if ( oldHolder == null )
+ {
+ return null;
+ }
+
+ try
+ {
+ setServlets( ( ServletHolder[] ) LazyList.removeFromArray( holders, oldHolder ) );
+ setServletMappings( ( ServletMapping[] ) LazyList.removeFromArray( mappings, oldMapping ) );
+
+ if (oldHolder.isStarted() && isStopped()) {
+ oldHolder.stop();
+ }
+
+ return ( ServletHolder ) oldHolder;
+ }
+ catch ( Exception e )
+ {
+ setServlets( holders );
+ if ( e instanceof RuntimeException )
+ throw ( RuntimeException ) e;
+ throw new RuntimeException( e );
+ }
}
@@ -56,16 +105,16 @@
// HttpContext
public URL getResource( String uriInContext )
{
- Code.debug( "OSGI ServletHandler getResource:" + uriInContext );
+ Activator.debug( "OSGI ServletHandler getResource:" + uriInContext );
return null;
}
- // override standard behaviour to check context first
- protected void dispatch( String pathInContext, HttpServletRequest request, HttpServletResponse response,
- ServletHolder servletHolder ) throws ServletException, UnavailableException, IOException
+ public void handle( String target, HttpServletRequest request, HttpServletResponse response, int type )
+ throws IOException, ServletException
{
- Code.debug( "dispatch path = " + pathInContext );
- super.dispatch( pathInContext, request, response, servletHolder );
+ Activator.debug( "dispatch path = " + target );
+ super.handle( target, request, response, type );
}
+
}
diff --git a/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHolder.java b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHolder.java
index 8b384e5..07b5aa1 100644
--- a/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHolder.java
+++ b/http.jetty/src/main/java/org/mortbay/jetty/servlet/OsgiServletHolder.java
@@ -31,9 +31,11 @@
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.http.jetty.ServletContextGroup;
+import org.osgi.service.http.HttpContext;
public class OsgiServletHolder extends ServletHolder
@@ -46,7 +48,10 @@
public OsgiServletHolder( ServletHandler handler, Servlet servlet, String name,
ServletContextGroup servletContextGroup, Dictionary params )
{
- super( handler, name, servlet.getClass().getName() );
+ super(servlet);
+ setServletHandler( handler );
+ setName( name );
+
m_servlet = servlet;
m_servletContextGroup = servletContextGroup;
@@ -58,7 +63,7 @@
while ( e.hasMoreElements() )
{
Object key = e.nextElement();
- super.put( key, params.get( key ) );
+ setInitParameter( String.valueOf( key ), String.valueOf( params.get( key ) ) );
}
}
}
@@ -89,6 +94,9 @@
if ( m_servletContextGroup.getOsgiHttpContext().handleSecurity( ( HttpServletRequest ) request,
( HttpServletResponse ) response ) )
{
+ // wrap request to get auth type and remote user
+ request = new HttpServiceHttpServletRequest( ( HttpServletRequest ) request );
+
// service request
super.handle( request, response );
}
@@ -112,7 +120,7 @@
// override "Holder" method to prevent attempt to load
// the servlet class.
- public void start() throws Exception
+ public void doStart() throws Exception
{
_class = m_servlet.getClass();
@@ -130,7 +138,41 @@
// override "Holder" method to prevent destroy, which is only called
// when a bundle manually unregisters
- public void stop()
+ public void doStop()
{
}
+
+ // Simple wrapper class returning the authentication type and remote user
+ // from the respective request attribute as specificed by the HttpService
+ // spec (step 4 in Section 102.7, Authentication)
+ private static class HttpServiceHttpServletRequest extends HttpServletRequestWrapper {
+
+ HttpServiceHttpServletRequest(HttpServletRequest request) {
+ super(request);
+ }
+
+ public String getAuthType()
+ {
+ // use the auth type attribute; should not be null, but
+ // better check and use wrapped result if missing
+ Object name = getAttribute( HttpContext.AUTHENTICATION_TYPE );
+ if (name != null) {
+ return name.toString();
+ }
+
+ return super.getAuthType();
+ }
+
+ public String getRemoteUser()
+ {
+ // use the remote user attribute; should not be null, but
+ // better check and use wrapped result if missing
+ Object name = getAttribute( HttpContext.REMOTE_USER );
+ if (name != null) {
+ return name.toString();
+ }
+
+ return super.getRemoteUser();
+ }
+ }
}