How to overcome browser's "Save" feature after SESSION expires? - php

PDF Generation Dependent on $_POST
I generate a PDF in my browser, using a PHP script, where the PDF-generating script depends on variables sent to it through POST. When POST is empty, PDF cannot be generated and it issues a warning saying "PDF Must be Regenerated".
Certain situations triggered POST array being empty, namely, if I hit browser's Refresh button while being on the page with PDF, for whatever reason, POST data does not get resent and there is no prompt asking me to resend it, it just becomes empty and the script detects it and the warning is issued. The warning is PDF Must be Regenerated, which is what I put in when POST array is empty in my code.
PDF Generation Workaround Dependent on $_SESSION
So a work-around I did is to save POST data to SESSION and then use SESSION when POST is empty. Like below:
if (empty($_POST))
{
// try restore from session first
$_POST['product_count'] = $_SESSION['product_count'];
if (empty($_POST['product_count'])) // if we failed.. session is empty
{
print 'PDF Must be Regenerated';
exit();
}
}
else
{
//save POST into SESSION
$_SESSION['product_count'] = $_POST['product_count'];
}
Browser's Save feature tries to generate PDF after SESSION expires
And all was well and fine until users started noticing a certain behavior:
They generate PDF using script
Leave the browser idle for a while doing other business, until SESSION expires behind the scenes
Then they use browser's Save-As feature to save the PDF.
The browser, instead of saving PDF from memory (PDF is still visible inside the browser), browser our company uses (Mozilla), makes a request to the server, asking for a fresh new copy of the PDF. But ... while doing so, POST is empty because POST is not being resent, and SESSION is empty because SESSION has expired during the idling stage.
This results in a corrupted PDF, where PDF is actually an ASCII text file containing words PDF Must be Regenerated. Users don't notice it until it is too late.
But, Mozilla apparently makes a call to the server, PHP scripts pass the user login credentials test, but all the while having empty POST and SESSION, resulting in corrupt PDF.
Login credentials check does not depend on SESSION and to be honest I can't yet tell what it depends on because I can't easily reproduce the issue so I can't readily test.
The work-around is obviously to save PDF soon after it has been generated, before SESSION expires, but user is "always right" and I want to let the user to be able to save the PDF even when SESSION expired. My question is "how".
How? What can I do?

The pdf thing seems surely a bug on the browser. but regardless, you want to use GET.
post is to execute an action and the browser correctly do not re-issue that request. From your description it does not seem viewing the pdf is executing an action.
if you use GET, it means get me this data with those parameters. and the browser will handle it accordingly.
if it is the result of an action, then break the action and the report into two requests. for example, make viewing the resulting PDF report a link in the response for the action. you can see this pattern when you buy someone online for example. the payment POST request gives you a link via GET to the invoice.

Related

PHP handle download request when session is expired

I'm looking for some help in how best to handle page navigation/redirection from a PHP application. We don't offer many downloads so this has only just now come up as an issue. The gist is that a user loads a webpage to view some data and this page offers a hyperlink to download the data into a spreadsheet (dynamically built). The issue that I'm struggling to come up with a slick solution to is if the user sits on the webpage for long enough to where their session expires in PHP. Suppose in that case the user comes back to the page and clicks the download link.
There are two scenarios I need to handle. The first is with old browsers like IE (have to support it for the time being). IE doesn't support the download attribute for ANCHOR elements. Therefore, when the link is clicked and the session is invalid, the user is presented with a login form but the browser URL now reflects the endpoint of the download. Upon logging in, the download functions correctly but the user is left at the login form because the presence of the Content-Type: attachment makes the browser not navigate. I am looking for how to best get the user back to what is essentially the initial HTTP_REFERER when the download was requested. The only idea I can come up with is either a standard endpoint or query string parameter to use so that my login form handling code can properly redirect after successful login for a download request.
The other scenario is for modern browsers that support the download attribute. My code does set the HTTP response code to 401 when it determines the login form needs to be rendered (maybe that's not correct though). I do not see anything within $_SERVER that alludes to that fact though which suggests, again, a standard endpoint or query string parameter to use for identification. Modern browsers handle this case well by simply denying the download and actually displays that the request needs authorization. So, this works well as long as setting the status to 401 on all login form renders is correct otherwise, I'd again need some way to know that the requested endpoint is a download.
I'd like to avoid any kind of JavaScript solution if possible.

How to prevent viewing two pages in same time

I've media website once member is logged successfully it creates session
$_SESSION['login_id'] = $username;
I wonder how to prevent members to watch two channels in same time.
I mean for example if member is viewing page video.php?id=4 and open in new tab page video.php?id=5 it shows him error have to close the page of video.php?id=4 before viewing the new page.
1st thing came into my mind is random token key that cleared on page exit but i don't know if it good idea or not, does anyone known how to do it or have better idea ! ~ thanks
At first thought
You could use requests to a php script that tells you if the user is still opening a web page.
For that you can use a loop of timed out ajax requests ( using jQuery for example)
Hint:
Instead of making Requests you can try and load tiny images ( 1px h/w ) and of course load this image using a php script (you can trick the url using htaccess),
So when the image is requested, your php script will do the trick (setting the currently watched video) then serve the image (don't forget to set the proper content-type )
and keep loading the image at certain interval (you will need to generate url token to avoid caching ;) )
A second solution could be
Serving your videos using php script as proxy, like that you can know when a video has been streamed completely, then if a user request a second video, knowing his is still streaming a previous one, you deny his request, show him an appropriate message or do as you like :)
I guess, using the 2nd solution would be better for you and the visitor, since he would be able to start caching a 2nd video once the 1st one has been cached completely
1st solution will use many request which can overwhelm the network or both the client side and server side
Both Solutions would not track a user that is using more than one browser, which means he would have more than one session, unless the user is registered and logged in
if ($_SESSION['login_id'] = $username && COUNT($_GET['id'])>1 )
Now after you check this condition I don't know what you could do to prevent the user from opening 2 tabs..
Just my thoughts
Since the video has to stream, it pings the server . The session can have assigned to it, the last video clicked. then once a new video is clicked, the session on the server will use the new video id and once the first video pings the server and find out the session is pointed at a different page, then the video can return an error message
Alternatively, You could assign an ID to each instance of form OR a hidden field with an ID, then use AJAX to ping the server with that ID. If the user tries to request the same form when there's an active ID, it should display an error message.

Getting contents of referring page with php

I'm trying to enable screenshots of the page a logged in user is currently on. I've placed a button that needs to:
read in the content of the referring page
save it to a file
render that file as a PDF
redirect back to the referring page
The problem I've run into is that users are logged in and on pages that are very specific to them. I can't grab the page via CURL with generic credentials because the screenshot won't be applicable, and I don't have the user's credentials.
How can I read in the contents of the current/referrering page with PHP without access to the users credentials? I've tried file_get_contents which was not working either.
It sounds like your mechanism is going to be faulty anyway: you're not saving the page as it looks to them, but rather saving the page as it looks to CURL at some point in the future.
If you want an accurate solution, then you need to save a copy of the rendered HTML somewhere server-side as you send it out (you can use PHP's output buffering to capture it) and mark the file you save with some sort of key that goes to the user. If the user clicks the button, it sends that key to the server which you use to look up the saved HTML file, and process it as desired.
Significantly less efficient, of course, but there you go. Alternately, you can save just the parameters processed in the page such that you can re-render it with PHP if required. Still no curl involved, but less saving going on. Obviously you don't need to keep this cache information long; just a few minutes, so storing it in ram (e.g. memcache) would be sufficient.
I don't believe this can be accomplished ethically without obtaining the user's credentials.

Why would some POST data go missing when using Uploadify?

I have been using Uploadify in my PHP application for the last couple months, and I've been trying to track down an elusive bug. I receive emails when fatal errors occur, and they provide me a good amount of details. I've received dozens of them. I have not, however, been able to reproduce the problem myself. Some users (like myself) experience no problem, while others do.
Before I give details of the problem, here is the flow.
User visits edit screen for a page in the CMS I am using.
Record id for the page is put into a form as a hidden value.
User clicks the Uploadify browse button and selects a file (only single file selection is allowed).
User clicks Submit button for my form.
jQuery intercepts the form submit action, triggers Uploadify to start uploading, and returns false for the submit action (manually cancelling the form submit event so that Uploadify can take over).
Uploadify uploads to a custom process script.
Uploadify finishes uploading and triggers the Javascript completion callback.
The Javascript callback calls $('#myForm').submit() to submit the form.
Now that's what SHOULD happen. I've received reports of the upload freezing at 100% and also others where "I/O Error" is displayed.
What's happening is, the form is submitting with the completion callback, but some post parameters present in the form are simply not in the post data. The id for the page, which earlier I said is added to the form as a hidden field, is simply not there in the post data ($_POST)--there is no item for 'id' in the $_POST array. The strange thing is, the post data DOES contain values for some fields. For instance, I have an input of type text called "name" which is for the record name, and it does show up in the post data.
Here is what I've gathered:
This has been happening on Mac OSX 10.5 and 10.6, Windows XP, and Windows 7. I can post exact user agent strings if that helps.
Users must use Flash 10.0.12 or later. We've made it so the form reverts to using a normal "file" field if they have < 10.0.12.
Does anyone have ANY ideas at all what the cause of this could be?
IOError: Client read error (Timeout?)
I got the same error a lot although my server side is python/django. I assumed it was the client timing out, but looking back though the logs for you now there seems to be a coincidence of this ceasing when I changed something in the authentication routines. Is it possible that the server is receiving the file but then refusing to write it to storage?
Also, you aware that several flash clients do not send cookies? You have to work around it by injecting the session keys into uploadify's 'scriptData' variable.
x--------------------------------
Edit. This python/django code starts off the routine to which uploadify submits itself:
# Adobe Flash doesn't always send the cookies, esp. from Apple Mac's.
# So we've told flash to send the session keys via POST. So recreate the
# session now. Also facilitates testing via curl.
cookie_name = settings.SESSION_COOKIE_NAME
if request.member.is_anonymous() and request.POST.has_key(cookie_name):
# Convert posted session keys into a session and fetch session
request.COOKIES[cookie_name] = request.POST[cookie_name]
SessionMiddleware().process_request(request)
# boot anyone who is still anonymous
if request.member.is_anonymous():
response['message'] = "Your session is invalid. Please login."
return HttpResponse(simplejson.dumps(response), mimetype='application/json')
Uploadify might alter the form. Take a look at the html/DOM tree of the form at the time when uploadify has finished and is calling your callback.
Have you tried using Live HTTP Headers in Firefox to see if there is some kind of rewrite happening that is causing the post data to be lost?

Read header files and do something before full photo upload happens

I am passing a GUID as a header and a photo as a body to a php file. The GUID is used to authenticate. If it's not valid, I want to end the call and I do this using
die("GUID was expired");
This works fine, but my issue is that the whole photo is uploading before that gets called. This is bad for the user. I want to read the header and have the upload wait until I do the validity check. Is this possible in php? So rather than uploading the photo, then getting a failed response, just upload the headers from objective c, if the Guid is valid, then upload the photo.
Thanks!
I don't believe that's possible in PHP; the browser will POST the image content body before PHP ever gets a say in the matter.
One (slightly complicated) solution to this problem would be to do a HEAD request with an XMLHttpRequest just before the form is submitted using JavaScript. If the request failed, you could display an error message to the user or redirect to a login page. Otherwise, let the form submit as usual. Of course, the GUID could expire between the HEAD request and the subsequent POST, so it's not completely fool-proof.

Categories