I have a button on a page with an onClick I dynamically set via Jquery.
That button starts the download of a file.
I’m using mod_rewrite to turn http://somesite.com/blah1/blah2/blah3/blah4 into index.php&q=$1
Then I access q, split on / and I get any user requested path as an array.
Works great except I can’t send an encoded path as one of my variables:
<?php
$html = '<button onClick="window.location = \'' . SITE_URL . 'downloadLog/' . urlencode($some_path) . ">Click me</button>';
Looked into AllowEncodedSlashes On for Apache.
Tried it.. Always end up with either %2Fvar%2Fadm%2Fmessages even after urldecode() or rawurldecode(), or apache attempting to go somewhere that doesn’t exist even with my mod_rewrite on / converting these to q=.
So.. the new idea is I’ll just create a form onClick and submit that. POST will have no problem with my urlencoded path as a parameter.
Since this is destined to go in an onClick, and my onClick= uses double quotes (this is part of another huge piece of code I can’t easily change right now) I’m having trouble getting the escaping correct I think. Broke down and didn’t use quotes around my id/name as a last resort, still no dice.
So here is what I came up with. This does not error in firebug, but I don’t see a POST happening either.
function get_inline_post($a) {
$output .= 'this_form = $(\'<form submit=' . SITE_URL . $a['submit'] . ' ></form>\').html(\'\')';
unset($a['submit']);
foreach ( $a as $key => $value ) {
$output .= '.append(\'<input id=' . $key . ' name=' . $key . ' type=hidden>\')';
}
$output .= ';';
foreach ($a as $key => $value ) {
$output .= '$(\'#' . $key . '\').val(\'' . rawurlencode($value) . '\');';
}
$output .= 'this_form.submit();';
return $output;
}
Which given the right variables ends up building this to go in my onClick:
<button class="ui-corner-all"
onClick="
this_form = $('<form submit=/downloadHostLog/messages></form>').html('').append('<input id=link_hcmdb_id name=link_hcmdb_id type=hidden >').append('<input id=added_path name=added_path type=hidden >');
$('#link_hcmdb_id').val('046345D4771C4D3FBD2EF33CBE038028');$('#added_path').val('var%2Fadm');this_form.submit();
"
title="Kill me now" type="button">
<span class="ui-icon ui-icon-copy"></span>
</button>
Remember,I’m trying to initiate a download here so answers with .post() are useless. Thank you.
Edit:
I’m open to using the original idea of just urlencoding it in the window.location script, but I’ve wasted all day on it already. Actually made a table and tried every variation of:
single urlencoding, double urlencoding encoding,Different levels of encoding going in versus coming out.
rawurlencode vs urlencode,
AllowEncodedSlashes On/Off
At this point I’m guessing that my combination of using mod_rewrite, splitting on / to generate the original query path as an array, and AllowEncodedSlashes just may not work together.
I’m also eliminating the fact that the buttons are sent to the user via ajax, and this button actually ends up in a jqgrid.
This is part of the reason I want to simply inline the onClick on generation instead of doing
$().click(function(){blah});
for every single result row as every row has 5 different parameters other than what I show here that are unique to every row for security purposes… so I end up calling the bind 50-500 times anyway which was painfully slow.
What I was doing previously was just generating a uid for each row, storing that in a session variable, and dereferencing it back when the user visited /downloadLog/UID. That worked as well, but I like to keep my session information under 4k for performance reasons and doing this took it to 16k easily.
Simply replacing / with | before encoding and changing it back after worked but I refused to resort to building in a bug like that.
EDIT: @dqhendricks My current mod_rewrite statement:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)? index.php?q=$1 [L,QSA]
The corresponding php that processes that:
foreach ( preg_split('/\//',$_GET['q']) as $key => $value)
{
$g[$key] = urldecode($value);
}
Given the above I tried AllowEncodedSlashes On and Off. Neither one allowed /blah/blah/%2F%var%2Fadmin/blah to be even directed into index.php. Got 404.
Don’t quote me on this, but I believe frameworks like Zend just redirect everything to index.php (no GET request variables), then gets the request data from something like $_SERVER[‘ORIG_PATH_INFO’]*. This gives you the request data prior to decoding the url. You can then split the request string, and decode each variable yourself.
*Unsure exactly, but something like this. Would have to look into Zend Framework’s routing class to be sure.
EDIT
Dug up the code that gets the request uri from zend framework. Part of the Zend_Controller_Request_Http class, but you get the idea.