Wasm file served with wrong Content-Type header by Quarkus - mime-types

I need Quarkus to serve my wasm file with Content-Type header application/wasm instead of application/octet-stream. I explicitly use the quarkus-undertow extension.
First I tried to use the undertow-handlers.conf to set the content type like this:
path-suffix('.wasm') -> set("o{Content-Type}", "application/wasm")
For other headers this works without problem, but the Content-Type seems to be overwritten by a following handler.
After this I tried to add a web.xml under src/main/resources/META-INF with a mime mapping for wasm files like this:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<mime-mapping>
<extension>wasm</extension>
<mime-type>application/wasm</mime-type>
</mime-mapping>
</web-app>
This approach doesn't seem to have any effect on the Content-Type.
What is the correct way to overwrite mime type mappings for static files in Quarkus? Why does the web.xml configuration not work?
Update
The web.xml approach from above works since Quarkus 1.1.1.Final.

Did you add the quarkus-undertow extension explicitly? Because by default, it's not present and things are served by Vert.x so you need to add a Vert.x handler instead.

Related

Karaf v4.0.8 : Multiple Blueprints cannot load configuration from same persistent-id

Update: It took a little time to realize for some reason but I see that configuration files are bundle PID specific and by trying to load the same cfg file in blueprint within two different bundles, I was creating a race condition. Make sure you use the cfg files in their target bundles only.
Note: The above applies only to blueprint bundles. If you do not depend on OSGI ConfigAdmin service to keep the bundles dynamically and want to use the cfg files from something like a Camel context, that should be fine.
I have 2 blueprints deployed through karaf 4.0.8 'deploy' folder. Both have the following common section:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint https://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<cm:property-placeholder id="common" persistent-id="common" update-strategy="reload" placeholder-prefix="$(" placeholder-suffix=")"/>
<cm:property-placeholder id="sqlcfg" persistent-id="12345" update-strategy="reload" placeholder-prefix="$[" placeholder-suffix="]">
</cm:property-placeholder>
I would like to load configuration common to both from 'common'. However, when they share the same persistentId and properties file from the 'etc' folder, the blueprint to be deployed second keeps loading and unloading.
If I get them to load from different files - it all works.
Any ideas from the community why I have this behaviour?
Thanks in advance.
In my experience, you either set a different persistent-id or set update-strategy="none". This will stop the second module from going into that loading/unloading loop.
The downside is that you lose the auto refresh of the config file.

Alternate servlet definition to web.xml?

I am using google app engine, and I define all my servlet paths in web.xml. Is there a way to define these in code instead of xml? I ask because the web.xml file is very verbose and I have many servlets. If I could register the servlets in java code somewhere I can probably shorten things.
Thanks
You can define a "main" servlet whose job it is to dispatch to other servlets; in your web.xml, you would write something like:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.mydomain.myapp.Dispatcher</servlet-class>
</servlet>
</web-app>
This would map /* (your entire app) to your dispatcher class. You could then register your various servlets with the dispatcher under different paths (e.g. you could use the Spring DispatcherServlet or your own).

Mapping two servlets in web.xml where one URL pattern is substring of the other

I have a web application where I would like to tie a JSP to address http://host:port/status and a servlet to addresses like http://host:port/status/.... Is this possible? According to this article it should be possible ("container prefers an exact path match over a wildcard path match") at least for some containers and the Java Servlet Specification contains similar examples (albeit without wildcard, on p. 12-123 in April 2013 version), but if I try the following in web.xml it appears as if the JSP is never called and all requests (also to http://host:port/status) are routed to the servlet. My JSP and servlet are hosted on Google App Engine.
<servlet>
<servlet-name>Status</servlet-name>
<jsp-file>/Status.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Status</servlet-name>
<url-pattern>/status</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>StatusUpload</servlet-name>
<servlet-class>com.example.StatusUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StatusUpload</servlet-name>
<url-pattern>/status/*</url-pattern>
</servlet-mapping>
Instead of mapping the same url to two different JSPs/Servlets in web.xml you can use a URL Rewriting filter like Tuckey UrlRewriteFilter which uses a configuration file urlrewrite.xml which would also be placed in WEB-INF. It uses regex in the rules.
These two rules should do what you want:
<rule>
<from>^/status$</from>
<to>/Status.jsp</to>
</rule>
<rule>
<from>^/status/(.*)$</from>
<to>/StatusUpload/?param=$1</to>
</rule>
Then in WEB-INF you would not map the JSP anymore but would map the Servlet to StatusUpload. When the user goes to /status/postfix the URL Rewriting filter will forward to the servlet (with the postfix part passed as a parameter) in the backend without the address the user sees in the address bar changing.

GAE's appspot.com cache-control header - HTTP STATUS 304

I have a lot mouseover images on my GAE development (Java). I hosted it at appspot.com. The current cache-control header I got = no-cache, re-validation. So, when the image hovered and mouse out , it will reload the image and then this is where latency comes...
I am not sure how to deal with this. Any help please (Java solution)?
Edited ==>
appengine.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>s~xxxxxx</application>
<version>1</version>
<static-files>
<include path="/images/**" expiration="1d" />
<include path="/scripts/**" expiration="1d" />
<include path="/stylesheets/**" expiration="1d" />
<include path="/*.p12" expiration="1d" />
<include path="/favicon.ico" expiration="1d" />
</static-files>
<threadsafe>true</threadsafe>
<warmup-requests-enabled>true</warmup-requests-enabled>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<sessions-enabled>true</sessions-enabled>
</appengine-web-app>
When the first load the image (http://xxx.appspot.com/images/myicon.png) after deployment, I will get something like this. There are 2 cache-controls... I guess "no-cache" cache-control replaced the earlier private cache-control.
But then if I refresh that page again, it will go back http 1.1 304 Not Modified.
If you sign in as an administrator, app engine will try to suppress the cache behavior. Can you try it with logging out, or another account?
Here is a relevant issue:
http://code.google.com/p/googleappengine/issues/detail?id=8509
I also had some issues configuring browser caching and defining Expires headers on static files with Google App Engine for Java. The problem was that a filter-mapping in web.xml overruled the configuration of static files. I documented the issue and solution here:
How to set Expires headers on static files with Google App Engine. It might be interesting to check or share your web.xml file.
Does it have to be a Java solution? How about a pure CSS solution that avoids web requests and latency (after the first request)? If you put all of your rollover images together into a single image and put the coordinates of each rollover image (sprite) into CSS, you will see the images as fast as the browser can display them, almost instantly.
Here are some links to information on sprites:
The Mystery Of CSS Sprites: Techniques, Tools And Tutorials
Fast Rollovers Without Preload
CSS Sprites
The last link uses this example CSS:
#logo-link
{
width:191px;
height:151px;
text-decoration:none;
display:block;
background-image:url(dw-logo-sprite.jpg);
background-position:191px 0;
}
#logo-link:hover,#logo-link:active { background-position:0 0; }
Basically, you declare the image's URL once in CSS and include the geometry of the first sprite. On hover, it changes the geometry to use the second sprite (of the same image).
If you want to serve an image from a servlet for some reason, then you can set the cache-control response header like this with Jersey:
#GET
#Path("/{url}/{maxHeight}")
#Produces("image/jpeg")
public Response view(
#Context HttpServletRequest req,
#PathParam("url") String url,
#PathParam("maxHeight") int maxHeight
) throws IOException, URISyntaxException {
... [code to generate imageData]
return Response
.ok(imageData)
.cacheControl(CacheControl.valueOf("max-age=2592000"))
.build();
}
```

My controller/servlet with "/" mapping isn't overriding "Hello App Engine!"

I'm working with Spring MVC on google app engine and even though I've gotten a basic hello world example working, I can't get my servlet to show up when I use the request mapping of "/". Even when I specify "/" as my request mapping in my controller, I keep getting the "Hello App Engine!" page with a link to my project. I've already pulled the welcome-file declaration out of my web xml.
Basically...
package my.package.for.spring.stuff.controllers;
import ....;
// It doesn't seem to make a difference if
// I have this reqeustmapping or not...
#Controller
public class MainController {
// If I change mapping to "/main" and then go to
// localhost:8888/main then everything works as expected
#RequestMapping("/")
public String HelloWorld() {
return "MyView";
}
}
is still going to the "Hello App Engine!" page. Also, here is my web.xml...
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>SpringAppEngine</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringAppEngine</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And then here is my spring xml...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="my.package.for.spring.stuff" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/main/" p:suffix=".jsp" />
</beans>
Why is the app engine generated welcome file still showing up even though I'm declaring the root mapping in my controller? I know my setup should be right because when I change the requestmapping, everything works as expected.
The servlet 3.0 spec says:
A string containing only the ’/’ character indicates the "default"
servlet of the application.
And it also says:
By default all applications will have index.htm(l) and index.jsp in
the list of welcome-file-list. The descriptor may to be used to
override these default settings.
So, I guess that the container considers that the implicit index.html welcome file is an exact match, which takes precedence over the default servlet mapped to /.
The solution is to delete the index.html file or, probably, to define an explicit empty welcome file list in the descriptor.
Apparently pulling the index.html mapping out of the web.xml isn't enough, you actually have to delete the index.html. If someone can post an answer explaining why I'll still upvote and accept.
This post helped me and I think I can expand on why removing the file fixes the problem. According the GAE, any file in the war directory (except JSPs and anything in WEB-INF) gets a mapping to that file name. This implicit mapping appears to supercede any servlet rules in web.xml:
https://developers.google.com/appengine/docs/java/gettingstarted/staticfiles
Once you remove or rename index.html, your servlet rule for "/" is used instead of the implicit mapping for the static file.

Resources