Downloading Second .ics file From Same Page Opens the Previously Saved One - icalendar

I have a page that among other things has "Add to Calendar" links. These download Icalendar (.ics) events. It's for a travel situation, so there can be two events (outbound and return journeys) and each is offered as a separate download.
If I click one (e.g. outbound) it downloads and offers it to open. I do so and click save to calendar and it adds it to my calendar. So far, so good. Then I click the other one (return) and it downloads but when I open it it opens the already saved event for the outbound instead of a new event for the return. Thus, the wrong data and I have no option to save it (since the event already exists).
This is happening on both iPhone (safari browser) and an Android phone (chrome). No problems on the desktop. Closing the calendar app doesn't help.
It only happens if I add the first event to the calendar - if I just back without saving there there is no problem. It doesn't matter if I try the outbound or return first, the first one added to the calendar takes over! If I delete that from the calendar, I can then add the other one.
Each has a file name which includes the route (so the outbound and return have different file names) given in a Content-Disposition header. I also ensure a new copy is always used. The full headers (before echoing the contents of the ics file and dieing) are:
header( 'Cache-Control: no-cache, must-revalidate', true ); // HTTP/1.1
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT', true ); // Date in the past
header( 'Content-Type: text/calendar; charset=utf-8', true );
header( 'Content-Disposition: attachment; filename="' . $filename . '"', true );
header( 'HTTP/1.0 200 OK', true, 200 );
I'm kind of out of ideas at this point.

OK. Turns out the phones were correct and outlook was wrong. The back-end was re-using the email address as UID, so all the events had the same UID...
I have fixed the back-end code to use a more sensible UID now. And it works

Related

Which http headers to suppress "This document is no longer available." on browser back button?

A perl script creates a download page with this URL
http://server/cgi-bin/oursite/script.pl?action=checkme&username=myname
with headers set by:
my $q = new CGI;
...
print $q->header(-expires => '+0s');
with a bunch of links on it. Here is one:
http://server/cgi-bin/oursite/script.pl?username=myname&action=retrieve&rmime=text__plain&rfile=HM_vmK9Ah.status
(That is the URL in an filename construct.)
If a user clicks on this link the target file is sent to the browser with headers:
print "Content-type: $RMIME\n";
print "Content-Disposition: inline\n\n";
Followed by the text of that file. That displays as it should. Unfortunately, if the user then attempts to use the browser's back arrow it fails. Firefox (for instance), says this:
Document Expired
This document is no longer available.
The requested document is not available in the browser’s cache.
As a security precaution, the browser does not automatically re-request sensitive documents.
Click Try Again to re-request the document from the website.
[Try Again]
Clicking the "reload" button in the browser or "Try Again" in the message and then "resend" returns to the download page.
If the headers for the download page are instead generated by:
print "Expires: +0s\n";
print "Content-type: text/html\n\n";
Then the "back" button works as expected.
I don't understand why the behavior differs in the two cases since other than the failure of the "back" button the pages are displayed the same (as text/html). Can somebody please explain this?
A related question - if the browser is told to "show page source" on the download page created with the first header method that also brings up the "Document expired" message, and "Try again" "resend" shows the URL of the top page provided by the script. However "show page source" on the top page immediately shows it, without the "Document expired" message. If a page was created with the second header method then "show page source" does indeed show the source of the current page. Again, why the difference?
Thank you.
print $q->header(-expires => '+0s');
This gets translated into Expires: .. current date and time .. which means that the response expires immediately. This means the result gets not cached and thus can not be displayed when going back in the browser.
print "Expires: +0s\n";
This gets not translated but send as it is to the browser, i.e: Expires: +0s. Since Expires header expects an actual date and time which is not provided by you, this invalid header simply gets ignored and the default caching policy applies instead. This means that the page gets cached and can be displayed when going back in the browser.

Downloading a PDF from an HTTP POST call

Here is what I'm trying to accomplish (IE 9+, Chrome, FF, Safari) without the use of JQuery:
Make an http POST call to my API endpoint with some data
Server dynamically generates a PDF and returns the PDF as a binary attachment
Browser does default download behavior and downloads the PDF without refreshing the page
Basically I want to get the behavior similar to <a href="test.pdf"> but for a dynamically generated PDF after making a POST call instead of a GET call.
I've tried lots of different things, but they either didn't work cross browser (such as using $window.open() with a blob URL), were blocked by popup blockers (any $window call outside of the click scope), or didn't cause the PDF to be automatically downloaded (any $http POST solution).
I finally found one solution that seems to work which creates a form using javascript and submits it.
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', myurl);
var params = {foo: 'bar'};
for(var key in params) {
if(params.hasOwnProperty(key)) {
var hiddenField = document.createElement('input');
hiddenField.setAttribute('type', 'hidden');
hiddenField.setAttribute('name', key);
hiddenField.setAttribute('value', params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
This successfully accomplishes the 3 steps above, but now I've run into a new problem. There is no way to determine when the PDF file has been successfully downloaded. This is preventing me from removing the form and from displaying a friendly 'Please wait...' message to the user. There is also the additional problem that submitting the form cancels any outstanding ajax requests as well which isn't optimal.
I have full control over both the server and the client, so what's the best way to fix this? I don't want to have to save the PDF on the server so passing back a url and doing a second GET request from the client won't work in this case. Thanks!
You can make an server response behave as a download by applying some HTTP headers:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="SOME_NAME.pdf"
Content-Transfer-Encoding: binary
If you're initiating the download through JS only (instead of having the user click a download link), then check out this question for some caveats.
Update: Syntax for POST
Better Update: Form solution with iframe target
You can detect that your server-side script has finished (and subsequently, that the download is ready to begin) by having the form target an iframe. I believe this should also fix the issue of cancelling outstanding Ajax calls, but I'm not certain. Here is the code to do it (just stick this into your code example after the for loop and before document.body.appendChild(form);):
var frame = document.createElement('iframe');
frame.setAttribute('id', 'pdfFrame');
frame.onload = function(){
document.body.removeChild(form);
document.body.removeChild(frame);
alert('Download ready!');
}
document.body.appendChild(frame);
form.setAttribute('target', 'pdfFrame');
You can replace my alert with your code to remove the 'Please wait...'.

How to create a header for perl?

I am new to perl. I wish to create a perl program which sends request to a website and downloads the data. I read HTTP::Headers and HTTP::Request.
I wish to use HTTP::Request->new( 'POST', $URL, $Header, $PostData ).
My question is how can I determine header values and post data.
Thank you
I was creating a similar script sometime back. I think first you should capture the http request using the browser.
1) Add "HTTPFox" to firefox. It is very helpful.
2) Open HttpFox in a new window. Press start button. This will start capturing packets.
3) Open the website and follow the procedures to download the data.
Please ask if anything is not clear.

iPhone 5 Splash Screen - Can't delete

Making a nice mobile site with jQuery.
The splash screen works great except on an iPhone 5 with iOS6 where it continues to show the old screen from day 1 despite that image not even being on the server and clearing cache endless time, and certainly deleting the app storied on the phone desktop.
... so where is that thing stored on the phone? if not in the cache?
Try this link, it worked for me on my iPhone.
Here are the steps:
Go to Settings
Select 'Safari'
Hit 'Clear Cache'
EDIT: I just saw the comment that you tried to clear the cache. Did you do it this way?
Are you using PHP?
Add the following code to your site, it will send a header which prevents the browser from caching your site.
header("Expires: Mon, 26 Jul 12012 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
Are you using ASP.NET?
Check out this stackoverflow question to learn about preventing the browser to cache your site.

iCal won't accept my ics file

My web app generates ics files. These can be read successfully by Google Calender, but not iCal, which shows the error "iCal can’t read this calendar file. No events have been added to your iCal calendar.".
Why doesn't my ics file load in iCal?
Here is the file contents:
BEGIN:VCALENDAR
VERSION:1.0
PRODID:-//Third Workplace//EN
BEGIN:VEVENT
SUMMARY:Meeting at Third Workplace in Office #4
DTSTART;TZID=UTC;VALUE=DATE-TIME:20120820T160000Z
DTEND;TZID=UTC;VALUE=DATE-TIME:20120820T170000Z
DTSTAMP;VALUE=DATE-TIME:20120820T084134
UID:65---eede0aac722e48979bd2237814da9e3d#thirdworkplace.com
LOCATION:Office #4 at Third Workplace Contra Costa Centre
ORGANIZER:MAILTO:ram#rachum.com
END:VEVENT
END:VCALENDAR
Here is the original, binary version.
Change that version to 2.0, and watch the magic happen :-)
TG
I have had a lot of difficulties with this:
It was frustrating because a downloaded file would open in Google Calendar or iCal, but it would not load as feed in either. I would get these errors in Google Calendar when I did add by URL: "Failed to import calendar from" (sitename) or "Could not fetch the URL."
Here's what I had to do:
Have duration or endtime for events, NOT BOTH.
I also had to remove this from the header:
content-disposition: attachment; filename=Schedule.ics;
Also, to check if it's valid, Google a validator or try http://icalvalid.cloudapp.net/.