Community
Participate
Working Groups
I tried to enable tabbed browsing for my two RAP-applications. I followed the guide in the faq: http://wiki.eclipse.org/RAP/FAQ#Tomcat For one application everything worked fine out of the box. The other application has FORM-authentication enabled for the servlet url. The login over a simple jsp-page works fine. But after that the rap-application won't load. I traced the problem with firebug. The request url for the JSLibraryServiceHandler does not contain the jsessionid. Therefore the server returns the login page, because the request is not authenticated. I changed JSLibraryServiceHandler.java to use RWT.getResponse().encodeURL for the request url. After that the application was loaded without a problem.
Created attachment 187714 [details] Patch for encodeURL in JSLibraryServiceHandler
I agree that with the current code, each request to the JSLibraryServiceHandler happens in a new/different session than the if cookis are disabled. Which is bad already and causes the issue at hand. Further, the patch looks good and solves the issue. I only fear that the Javascript response cannot be cached anymore as the URL changes each time.
If we registered the concatenated JavaScript as a resource, we couldn't gzip it anymore. But IIRC we already agreed that it's much better to let the servlet container do the compression. For development, I guess gzipping (and unzipping) is just a waste of cycles, as network traffic is super fast anyway. What else keeps up from registering the compressed script as a resource?
(In reply to comment #3) > [ ... ] > What else keeps up from registering the compressed script as a resource? The JSLibraryServiceHandler sets and Expire date far in the future which keeps the resource in the clients cache. The "hash=" in the request URL takes care that changes lead to a different URL adn thus prevents delivering outdated Javascript. As startup performance is crucial for RWT, this custom mechanism was instruced. When using the resource manager we would give up control over the caching to either the servlet container (RWT standalone) or the HttpService (OSGi). Both would handle resources in a less optimal way as they aren't aware that resources never expire in RWT. A rewrite of the resource manager that delivers resouces by itself could of course also deliver the Javascript client file...
(In reply to comment #4) > > What else keeps up from registering the compressed script as a resource? > The JSLibraryServiceHandler sets and Expire date far in the future which keeps > the resource in the clients cache. It's true, the servlet container could only send ETag and LastModified headers, as it does for images, not a future Expire header. But the difference is just that the browser needs to send an additional request to find out whether the resource has changed. At the startup of RAP we have tons of these "If-Modified-Since" / "If-None-Match" requests (one for each image) with empty 304 Not Modified responses, so one more would not make a difference in startup time. I don't know if there are still browsers that do not cache resources based on these headers, we'd have to ensure that all supported clients do. > The "hash=" in the request URL takes care > that changes lead to a different URL adn thus prevents delivering outdated > Javascript. If we'd create a resource, we could also suffix the resource name with a hash of the content, couldn't we? > When using the resource manager we would give up control over the caching to > either the servlet container (RWT standalone) or the HttpService (OSGi). Both > would handle resources in a less optimal way as they aren't aware that > resources never expire in RWT. Granted, in theory there might be servlet containers that do not send ETag/LastModified headers, but since this is now state of the art, I doubt that there are in reality. At least Jetty and Tomcat send these headers out of the box. > A rewrite of the resource manager that delivers resouces by itself could of > course also deliver the Javascript client file... +1 for rewriting the resource manager! ;-)
(In reply to comment #5) > [ ... ] > If we'd create a resource, we could also suffix the resource name with a hash of > the content, couldn't we? There is no need to as this would be done by the resource manager anyway. > [ ... ] > Granted, in theory there might be servlet containers that do not send > ETag/LastModified headers, but since this is now state of the art, I doubt that > there are in reality. At least Jetty and Tomcat send these headers out of the > box. I agree with you that it is unlikely that there are servlet engines which do not implement ETag/LastModified and if so we shouldn't bother. What I forgot in my previous comment is that the resource manager always reads the resource to deliver from disk, whereas the JSLibraryHandler buffers the resource in memory.
(In reply to comment #6) > What I forgot in my previous comment is that the resource manager always reads > the resource to deliver from disk, whereas the JSLibraryHandler buffers the > resource in memory. I've copied the concatenated JavaScript into the context folder and compared response times between requesting the static resource and the service handler using ApacheBench. There's only a small difference, but the static resource is slightly faster than the service handler: ab -n 500 -c 20 "http://localhost:9091/rwt-resources/js" [...] Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.4 0 3 Processing: 1 8 4.1 6 23 Waiting: 1 7 4.1 6 23 Total: 4 8 4.2 6 23 ab -n 500 -c 20 "http://localhost:9091/rap?custom_service_handler=org.eclipse.rwt.internal.service.JSLibraryServiceHandler&hash=H-746931086" [...] Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.4 0 3 Processing: 0 10 4.9 9 35 Waiting: 0 10 4.9 8 35 Total: 1 10 4.8 9 35 I tested locally with an SSD, so I'm not quite sure whether this result holds true on a server. However, I believe that the operating system does some caching as well. I will repeat this experiment on a different hardware. Since it turned out that Safari cannot handle Exprires headers (bug 338412), I'm even more tempted to make this change.
Fixed by removing the JSLibraryServiceHandler in bug 345120.