I try to implement a custom PushStrategy, which is an API related to server push support of SPDY protocol inside Jetty.
I implement the following method:
public Set<String> apply(Stream stream, Fields requestHeaders, Fields responseHeaders);
However I need to access the ServletContext inside the method call but I don't know how I can access it.
I'm investigating a way to inject the WebAppContext in jetty.xml:
<New id="pushStrategy" class="spdy.MyPushStrategy">
<Set name="webAppContext">
<Ref id="..." />
</Set>
</New>
The problem is that this configuration step is in the Server block declared in jetty.xml:
<Configure id="Server" class="org.eclipse.jetty.server.Server">....</Configure>
while WebAppContext is configured in jetty-web.xml
<Configure id="WebAppContext" class="org.eclipse.jetty.webapp.WebAppContext">
I don't know how to refer any existing WebAppContext ID in this file.
Here is my maven plugin config:
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<stopPort>8888</stopPort>
<stopKey>quit</stopKey>
<jvmArgs>
-Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn-version}/npn-boot-${npn-version}.jar
</jvmArgs>
<webAppConfig>
<jettyEnvXml>${basedir}/src/main/config/jetty-web.xml</jettyEnvXml>
</webAppConfig>
<jettyXml>${basedir}/src/main/config/jetty.xml</jettyXml>
<contextPath>/</contextPath>
</configuration>
When you create a WebAppContext via an XML file, such as what is described in the Configuring a Specific WebApp Deployment.
You can configure an id attribute for that particular webapp's <Configure> element.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="myapp1" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
<Set name="war">/opt/myapp/myapp.war</Set>
</Configure>
Then you can use the Jetty XML notation you described to reference that particular webapp.
<New id="pushStrategy" class="spdy.MyPushStrategy">
<Set name="webAppContext">
<Ref id="myapp1" />
</Set>
</New>
Now, back to your more specific concern, access to the ServletContext from the PushStrategy implementation.
That cannot be done from a PushStrategy implementation, as it is too high-level in the layering of the TLS -> SPDY (with PushStrategy) -> Connector -> Connection -> HTTP -> Request -> Handlers -> WebAppContext -> ServletContext -> Servlet.
You might be able to split up the behavior though.
Create a CustomPushFilter that your Servlet context has, it has the logic on what you want to associate for the push, done via a custom response header. Then your CustomPushStrategy could look for those response headers to know how to associate those extra resources. Bonus with this approach is that your Servlets could even automatically add resources for push based on servlet specific knowledge.
Related
I have a simple xml context to display static files. The server loads fine and the page to show files loads as expected. The issue is that file with permission 000 are still showing in the list. If I click on one of the files I get a java stack trace error saying that jetty does not have permission to read the file (because it doesnt).
Does anyone know how to get these files with no read permission to not show up?
I am using jetty distribution version 9.4.34.v20201102. I run jetty as a service and have JETTY_USER set in /etc/default/jetty.
Here is my simple context in JETTY_BASE/webapps/static.xml
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/</Set>
<Set name="handler">
<New class="org.eclipse.jetty.server.handler.ResourceHandler">
<Set name="resourceBase">/mshr/test/</Set>
<Set name="directoriesListed">true</Set>
</New>
</Set>
</Configure>
This is not supported by the Jetty ResourceHandler, the ResourceService, or the DefaultServlet.
Asking about file permissions during file listing is actually quite an expensive thing to do (depending on the file system).
That's why Jetty doesn't do that.
If you feel otherwise, file a request at https://github.com/eclipse/jetty.project/issues
Migrating from Jetty 6 to 9 has been much harder than what I originally thought but I have got a lot of it done thanks to the resources you all have online
I question that I have not found xml examples online regarding Embedded Servlets in Jetty 9 other than the link below
http://jetty.4.x6.nabble.com/Jetty-9-Context-Deployer-td4960157.html
First off, it seems that you all have migrated from ContextDeployer to WebAppProvider is this a correct statement?
I ask this because in Jetty6, I was able to use a context deployer to search a directory to configure servlets as context objects. Since ContextDeployers seem to be gone, the closest usage in Jetty I see is the WebAppProvider which opens webpages from a war file. This isn't what my company wants to do and we would like to be able to use contexts in the same way we have done in the past
Now I have seen the ServletContextHandler which seems simple enough to configure and would act as the context object. However, my current web app provider configuration will not open my servlet web pages
Here is an excerpt of how I use the DeployManager in xml
<Call name="addBean">
<Arg>
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
<Set name="contexts">
<Ref refid="Contexts" />
</Set>
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="config/jetty/context/"/></Set>
<Set name="scanInterval">5</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
An example Servlet configuration xml
<Configure id="contexts" class="org.eclipse.jetty.servlet.ServletContextHandler">
<Set name="contextPath">/</Set>
<Call name="addServlet">
<Arg>class.name.here</Arg>
<Arg>/*</Arg>
</Call>
</Configure>
You can use the WebAppProvider in exactly the same way that ContextDeployer was previously used. Specifically if you put a context.xml file into the webapp directory, it will be hot deployed exactly as it was with the ContextDeployer.
As for the type of the Context you wish to deploy, it an be just a ContextHandler, a ServletContextHandler, a WebAppContext or anything else that extends ContextHandler
Look in the demo-base/webapps directory for some examples.
In your example, I'm guessing that the id="contexts" might be the problem. Try removing it as you don't need an id there. Other than that, it looks like it should work, so you are on the right path.
How do i configure Railo on Jelastic (PAAS) to work with multiple domains using Jetty?
I found the configuration for Railo using Tomcat, but I would like to use Jetty because of the memory requirements
Thanks
In Jelastic there are at least 2 possible ways of binding your domain name.
Actually you can bind your domain by deploying your application to a specified context ROOT via Jelastic dashboard. Here is an article which explains how to manage it: http://jelastic.com/docs/custom-domains
The second way is to set DNS A Record. The given article explicitly shows how to do it: http://jelastic.com/docs/A-Records-domain-names
I am not sure on the Jelastic specific side, but with Jetty you can create an XML file in the contexts folder, and it should look something like this:
contexts/Localhost.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/webapps/railo/</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<!-- virtual hosts -->
<Set name="virtualHosts">
<Array type="String">
<Item>localhost</Item>
<Item>127.0.0.1</Item>
</Array>
</Set>
</Configure>
You can then create more files in there for each domain, making sure you add/edit the entries for the resourceBase (your file webroot) and in the Item for the virtual host.
I am not sure how Jelastic handles this stuff with Jetty specifically, but if you can edit the files you should be cool.
I trying to create custom configuration for jetty when using sbt-web-plugin (for running with container:start). There are two container settings allowing to specify custom jetty xml configuration: configurationFiles and configurationXml (when customConfiguration is true).
However, this overrides internal configuration of jetty done by sbt-web-plugin completely so custom config should configure jetty fully. And it will not work without specifying classpath to .class files compiled from project and to dependencies.
I trying to do something like that:
configurationXml in container.Configuration <<= fullClasspath (
<Configure id="Server" class="org.eclipse.jetty.server.Server">
...
<Set name="handler">
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/src/main/webapp</Set>
<Set name="descriptor"><SystemProperty name="jetty.home" default="."/>/src/main/webapp/WEB-INF/web.xml</Set>
<Set name="contextPath">/</Set>
<Set name="extraClasspath">{/* classpath should be here */}</Set>
</New>
</Set>
...
</Configure>
)
Seems that direct dependency of configurationXml on fullClasspath is not possible, because configurationXml is SettingKey and fullClasspath is TaskKey:
Tasks with dependencies
The practical importance of this is that you can't have tasks as dependencies for a non-task setting.
Is it possible to include fullClasspath setting in configurationXml parameter?
If not, is it still possible to add custom configuration settings to jetty development server invoked on container:start?
You can customize just the WebAppContext using the env setting:
env in Compile := Some(file(".") / "jetty-env.xml" asFile)
For example, consider the following in myproject/jetty-env.xml:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/custom</Set>
</Configure>
This will deploy your webapp under the context path /custom, but won't change any configuration of the underlying Server.
Jetty allows headers to be set using the jetty-rewrite functionality, but it doesn't appear to be very smart, and only accepts a fixed string.
How do I tell Jetty to send an "expires in 8 hours" header?
With Apache .htaccess and mod_expires you can do "access plus 8 hours" but of course Jetty doesn't understand .htaccess files, nor can I find any info on a similar construct in jetty-rewrite.xml
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">*.png</Set>
<Set name="name">Expires</Set>
<Set name="value">access plus 8 hours</Set>
</New>
</Arg>
</Call>
That just sends the literal text "access plus 1 day" back, which is of course ignored by the client.
Could/should this be done with a servlet filter? Jetty has a Gzip filter but doesn't appear to offer something similar for dynamically setting headers.
That could be a nice feature..
Open an enhancement for it at bugs.eclipse.org under RT/Jetty. Patches are welcome, either attached to the bug or pushed into our gerrit instance.
That being said...the jetty xml is really an xml layer over java so I suspect you could actually so this in java if you can find the APi for it. I think there is a joda time library that has a method where you could wire up something that would call new DateTime().plusHours(8) to populate that value.
Probably better to add it as a feature though.