My question is short (and hopefully simple to solve!): How can I completely disable browser-caching in my webservice realized with vaadin?
I want to completely disable caching since I'm getting problems when I try to do some PDF streaming and displaying them in my browers.
I have read about a solution for my problem for example here:
Using <meta> tags to turn off caching in all browsers?
They talk about adding some headers to the web application that disable browser caching. But how do I add them to my Vaadin application?
A short code snippet would be very welcome (and helpful!)
Thanks once again for every answer and thought you're sharing with me.
It seems to me that you want to disable caching when downloading a PDF file. Assuming you are using a DownloadStream to stream the content, then setting the Content-Disposition and Cache-Control headers as follows should work.
DownloadStream stream = new DownloadStream(getStreamSource().getStream(), contentType, filename);
stream.setParameter("Content-Disposition", "attachment;filename=" + filename);
// This magic incantation should prevent anyone from caching the data
stream.setParameter("Cache-Control", "private,no-cache,no-store");
// In theory <=0 disables caching. In practice Chrome, Safari (and, apparently, IE) all ignore <=0. Set to 1s
stream.setCacheTime(1000);
If you want to disable caching for all Vaadin requests, you'll have to look at the source of AbstractApplicationServlet, and extend methods such as #serveStaticResourcesInVAADIN and others - this is quick tricky, as alot of them are private methods.
A simpler method may be to use an Http Servlet Filter to add the appropriate parameters to the response, without having to modify your app at all. You can write this yourself - should be quick easy - although a quick search finds the Apache2 licensed Cache-Filter : http://code.google.com/p/cache-filter/wiki/NoCacheFilter
I have not used Cache-Filter, but a quick skim suggests it'll work just fine for you.
Related
I am trying to implement this endpoint activities/state/?method=GET in my LRS - but I can not seem to get the resume functionality working. I have all the data, but not sure what does Articulate expect the LRS to return in order to resume where the user left off. I also tried looking at Articulate support page, but nothing useful so far. Any help would be appreciated.
It's looking for the state string to be returned. Which is just a long string that is sent out when the state ( bookmark ) is saved.
I recommend testing with the Golf Prototype at http://tincanapi.com/prototypes/ first so that you know the issue is with the LRS. Try the prototypes in both Internet Explorer and another browser such as Chrome; any difference in behaviour could be a clue.
Please also look at your network tab in Chrome's developer tools and let us know if any requests are failing and what is being stored and retrieved from the State.
Full details of how the State API is supposed to work are found in the spec. Here's the relevant section in version 1.0.2: https://github.com/adlnet/xAPI-Spec/blob/a752217060b83a2e15dfab69f8c257cd86a888e6/xAPI.md#stateapi
It's also worth noting that building an LRS is hard. There are a number of commercial and open source LRS that will likely be cheaper than building one yourself.
I managed to get this working. I was using .NET Web API.
I had to explicitly set the content-type header to octet-stream - It was defaulting to text/html.
The following code did the trick:
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
httpResponseMessage.Content = new StringContent(studentModuleName.SuspendData);
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
I am currently experimenting with IBM JAX-RS capability through WAS 7 and Web 2.0 Feature Pack 1.1.0.0. The problem I am running into is the client Dojo ajax call poses CORS situation and I am basically trying to figure out how I could properly handle the OPTIONS request.
I followed the example in the referenced url (although it's for WAS 8, it should not affect the part I am playing with); however, it is reported that the system cannot find any method that supports OPTIONS.
Any help will be appreciated!
Reference URL: http://www14.software.ibm.com/webapp/wsbroker/redirect?version=matt&product=was-base-iseries&topic=twbs_jaxrs_wadl_serving
Although it's less than a day, since I did not see any response, I want to post out the temp solution I pieced so far.
First of all, check out below link from Mozilla for a better understanding of CORS and OPTIONS request (it did the trick for me).
Link: https://developer.mozilla.org/en-US/docs/HTTP_access_control
Next, one update on the problem of IBM JAX-RS handling OPTIONS. It appears OPTIONS request is handled no different than other GET/POST, it requires an exact match of #Path value. This is not really desired, and in my case, I tried wild card in #Path value, that did not do the trick of triggering the system to handle OPTIONS.
Now, for the solution. With no surprise, I end up using a filter to forward the OPTIONS request to a method inside the resource annotated with #OPTIONS and fixed #Path value, e.g. #Path("options").
In filter, I am handling Allow-Origin and Allow-Header, then I left the resource's #OPTION method to deal with Allow-Methods.
It is very simple and basic solution. Along with proper checking inside filter, the header does not need to be added excessively for every request.
One catch here, it works for Chrome (Version 23.0.1271.95 m) and Mozilla (9.0.1), but not IE. I am still trying to figure out how IE is responding to these CORS. Hope this helps.
I'm trying to load some external content using jQuery load function to div on my page. load method works ok, with local content, but if you want something out of your domain, it won't work.
$("#result").load("http://extrnal.com/page.htm #data);
(it actually works in IE with security warning, but refuses to work in Chrome at all). jQuery documentation says that it is right, because cross-domain content is restricted because of security reasons. Same warning I get if use .getJSON method.
OK, after a googling a bit I found very interesting approach of using YQL for loading content, I've tried some examples, like this:
var request = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2Ffinance.yahoo.com%2Fq%3Fs%3Dyhoo%22&format=json&diagnostics=true&callback=?";
$.getJSON(request, function (json) {
alert(json);
}
);
And it really works!
What I dont understand now is that http://query.yahooapis.com is also cross-domain resouce but browser (both IE and Chrome) works OK with that?
Whats the difference? What am I missing?
Thank you
The results you are getting back from YQL are in JSON format which is permitted for cross site AJAX calls like this. Its the same mechanism that allows you to communicate with web services for external sites via JSON (Ie. the twitter API).
Details here - http://www.wait-till-i.com/2010/01/10/loading-external-content-with-ajax-using-jquery-and-yql/
you can make on external site JSON like this:
callback({key:value,etc:1})
and define
function callback(json) {
..here is processing..
}
Thanks for your answers, but unfortunately both of them do not answer my orginal question..
I've checked out related questions on stackoverflow (i know i need to do that first) and found the reason of such behavior.
First code snipset uses AJAX/JSON to retrive the data and it is permitted because of Same Origin Policy. But request to YQL uses JSONP instead, that is OK.
The JSONP was something that I don't know about, that's why I didn't undrestand the behaviour.
Introduction info on JSONP could be found here:
http://ajaxian.com/archives/jsonp-json-with-padding
I have written a Firefox extension that catches when a particular URL is entered and does some stuff. My main app launches Firefox with this URL. The URL contains sensitive information so I don't want it being stored in the history.
I'm concerned about the case where the extension is not installed. If its not installed and Firefox gets launched with the sensitive URL, it will get stored in history and there's nothing I can do about it. So my idea is to use a bookmarklet.
I will launch Firefox with "javascript:window.location.href='pleaseinstallthisplugin.html'; sensitiveinfo='blahblah'".
If the extension is not installed they will get redirected to a page that tells them to install it and the sensitive info won't get stored in the history. If the extension IS installed it will grab the information in the sensitiveinfo variable and do its thing.
My question is, can the bookmarklet call a method in the extension to pass the sensitive info (and if so, how) or can the extension catch when javascript is being called in the bookmarklet?
How can a bookmarklet and Firefox extension communicate?
p.s. The alternative means of getting around this situation would be for my main app to launch Firefox and communicate with the extension using sockets but I am loath to do that because I've run into too many issues over the years with users with crazy firewalls blocking socket communication. I'd like to do everything without sockets if possible.
As far as I know, bookmarklets can never access chrome files (extensions).
Bookmarklets are executed in the scope of the current document, which is almost always a content document. However, if you are passing it in via the command line, it seems to work:
/Applications/Namoroka.app/Contents/MacOS/firefox-bin javascript:alert\(Components\)
Accessing Components would throw if it was not allowed, but the alert displays the proper object.
You could use unsafeWindow to inject a global. You can add a mere property so that your bookmarklet only needs to detect whether the global is defined or not, but you should know that, as far as I know, there is no way to prohibit sites in a non-bookmarklet context from also sniffing for this same global (since it may be a privacy concern to some that sites can detect whether they are using the extension). I have confirmed in my own add-on which injects a global in a manner similar to that below that it does work in a bookmarklet as well as regular site context.
If you register an nsIObserver, e.g., where content-document-global-created is the topic, and then unwrap the subject, you can inject your global (see this if you need to inject something more sophisticated like an object with methods).
Here is some (untested) code which should do the trick:
var observerService = Cc['#mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
observerService.addObserver({observe: function (subject, topic, data) {
var unsafeWindow = XPCNativeWrapper.unwrap(subject);
unsafeWindow.myGlobal = true;
}}, 'content-document-global-created', false);
See this and this if you want an apparently easier way in an SDK add-on (not sure whether SDK postMessage communication would work as an alternative but with the apparently same concern that this would be exposed to non-bookmarklet contexts (i.e., regular websites) as well).
I'm attempting to port over an Internet Explorer plugin to Firefox, but I'm not sure where to look for what I need.
Basically I need to be able to filter all content that is received by the browser with a certain Content-Type header. I tried implementing a stream converter, and this works, but only for the top-level document in the page, frame, or iframe. I had the same problem with IE, and getting around it was really hacky, and since I would ideally like this to be cross platform I would really like to be able to do this in Firefox without resorting to vtable hacks.
The content is served compressed with a proprietary compression format. So I need to receive the data, decompress it, and change the Content-Type back to what the original uncompressed file should have.
If there is a way to just filter all data received, that would probably be acceptable, I could handle parsing the header myself.
Thanks
I think I may have found what I needed. I came across this link which is used for tracing HTTP calls: http://blues.ath.cx/firekeeper/resources/http_tracer.html
There seems to be some problems with the JavaScript implementation for some reason, and I'm not a JavaScript guru to figure it out, but I've implemented it in C++ and initial results suggest that I should be able to modify it for my needs.
Basically we're replacing the nsIHttpProtocolHandler service with our own implementation, which keeps a reference to the initial implementation. When a call is made to the service, we just proxy it over to the saved original implementation. Then we provide our own implementation of nsIHttpChannel and nsIStreamListener which we use as proxies too.
Again we proxy most of the calls back off to the original handlers. But in OnDataAvailable, instead of passing the data on to the underlying nsIStreamListener, we save it using nsIStorageStream. Then in OnStopRequest, after we've gotten all of the data, we can decompress it and then call OnDataAvailable on the original handler, followed by OnStopRequest.
It has worked on some small simple tests so far, but I'll have to put it through some more rigorous tests... I'll also have to figure out if I can do the same thing with HTTPS.
The biggest problem I see at the moment is that it relies on some unfrozen interfaces such as nsIHttpChannelInternal. Can't be helped though as far as I can tell, and my version compatibility requirements are pretty small, so I can live with it if I have to.
In the meantime, if anybody has any other suggestions, I'm all ears :D