htaccess internal and external request distinction - ajax

I have a problem with an .htaccess file. I've tried googling but could not find anything helpful.
I have an AJAX request loading pages into the index.php. The link triggering it is getting prepended by "#" via jquery. So if you click on the link domain.com/foo/bar (a wordpress permalink) you get domain.com/#/foo/bar in the browser and the content will get loaded via AJAX.
My problem is: Since these are blog posts, external links grab the real link (domain.com/foo/bar), so I want them to get redirected to domain.com/#/foo/bar (cause then ajax checks the hash and does its magic).
Example here.
The jquery code for the prepend is:
$allLinks.each(function() {
$(this).attr('href', '#' + this.pathname);
...
and then the script checks
if (hash) { //we know what we want, the url is not the home page!
hash = hash.substring(1);
URL = 'http://' + top.location.host + hash;
var $link = $('a[href="' + URL + '"]'), // find the link of the url
...
Now I am trying to get the redirect to work with htaccess. I need to check if the request is external or internal
RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1 #???
and if the uri starts with "/#/" which is a problem since it's a comment then, \%23 does not really work somehow.
RewriteCond %{REQUEST_URI} !^/\%23/(.*)$ #???
How do I get this to work to simply redirect an external request from domain.com/foo/bar to domain.com/#/foo/bar without affecting the internal AJAX stuff?

I suppose your $allinks variable is assigned in a fashion similar to this:
$allinks = $('a');
Do this instead:
$allinks = $('a[href^="' + document.location.protocol + '//' + document.location.hostname + '"]');
This will transform internal links to your hash-y style only.

Ok i've done it with PHP here is the code
$path = $_SERVER["REQUEST_URI"];
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
echo "It's ajax";
} else {
if(strpos($path, '/#/') === false) {
header("Location: http://schnellebuntebilder.de/#".$path); //ONLY WORKS IF THERE IS NO BODY TAG
}
}
There sure is a better solution, but this does the trick for now and since the page /foo/bar does, in my case, not include the header.php there is no >body<-tag and the php "header()" function works . If anyone knows the htaccess script for this I am keen to know and learn.

Related

How to download file directly from blob URL?

I am looking to download a PDF directly from a blob URL using Ruby code. The URL appears like this:
blob:https://dev.myapp.com/ba853441-d1f7-4595-9227-1b0e445b188b
I am able to visit the link in a web browser and have the PDF appear in a new tab. On inspection, other than the GET request there are some request headers related to browser/user agent.
I've attempted to use OpenURI but it detects the url as not an HTTP URI. Open URI works just fine with files from URLs that look like https://.../invoice.pdf
I've also tried to go the JS route with this snippet but this is returning 0 for me, as others have also reported.
Any automated solutions that require a download onClick and then navigating the local disk is not sufficient for my project. I am looking to retrieve files directly from the URL in the same fashion that OpenURI works for a file on a server. Thanks in advance.
I was able to get the Javascript snippet to work. The piece that I was missing was that the blob URL needed to be opened/visited in the browser first (in this case, Chrome). Here's a code snippet that might work for others.
def get_file_content_in_base64(uri)
result = page.evaluate_async_script("
var uri = arguments[0];
var callback = arguments[1];
var toBase64 = function(buffer){for(var r,n=new Uint8Array(buffer),t=n.length,a=new Uint8Array(4*Math.ceil(t/3)),i=new Uint8Array(64),o=0,c=0;64>c;++c)i[c]='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charCodeAt(c);for(c=0;t-t%3>c;c+=3,o+=4)r=n[c]<<16|n[c+1]<<8|n[c+2],a[o]=i[r>>18],a[o+1]=i[r>>12&63],a[o+2]=i[r>>6&63],a[o+3]=i[63&r];return t%3===1?(r=n[t-1],a[o]=i[r>>2],a[o+1]=i[r<<4&63],a[o+2]=61,a[o+3]=61):t%3===2&&(r=(n[t-2]<<8)+n[t-1],a[o]=i[r>>10],a[o+1]=i[r>>4&63],a[o+2]=i[r<<2&63],a[o+3]=61),new TextDecoder('ascii').decode(a)};
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function(){ callback(toBase64(xhr.response)) };
xhr.onerror = function(){ callback(xhr.status) };
xhr.open('GET', uri);
xhr.send();
", uri)
if result.is_a? Integer
fail 'Request failed with status %s' % result
end
return result
end
def get_pdf_from_blob
yield # Yield to whatever Click actions that trigger the file download
sleep 3 # Wait for direct download to complete
visit 'chrome://downloads'
sleep 3
file_name = page.text.split("\n")[3]
blob_url = page.text.split("\n")[4]
visit blob_url
sleep 3 # Wait for PDF to load
base64_str = get_file_content_in_base64(blob_url)
decoded_content = Base64.decode64(base64_str)
file_path = "./tmp/#{file_name}"
File.open(file_path, "wb") do |f|
f.write(decoded_content)
end
return file_path
end
From here you can send file_path to S3, send to PDF Reader, etc.

Why is my AJAX request failing?

I'm trying to learn to use AJAX with Rails.
Here is my client side coffeescript code:
$(document).ready ->
$("#url").blur ->
$.get("/test_url?url=" + $(this).val(), (data) ->
alert("Response code: " + data)
).fail( () ->
alert("Why am I failing?")
)
Here is my server-side Ruby code:
def url_response
url = URI.parse(params[:url])
Net::HTTP.get_response(url).code unless url.port.nil?
end
The Ruby code is being called and correctly returns the HTTP response code, but I can't do anything with the data because the client-side script says the call has failed. As far as I can see, it is not failing. url_response is being called and it is returning a value, so what exactly is failing here?
The problem was I removed the line that rendered the response. I previously had in, but thanks to Frederick Cheung's hint to check if the URL works directly in the browser, I realised that it no longer worked in the browser as it did previously, which is why I didn't think to check again!
The code below got everything working again.
def url_response
url = URI.parse(params[:url])
render :text => Net::HTTP.get_response(url).code unless url.port.nil?
end

State object once and retrieve multiple attributes

Here is a snippet from a Sinatra app where users will be submitting urls. I must ensure that http:// is prepended to the url in order to route outside my application. How can I state site once and access it's attributes? (Line 3)
p.params= "www.ruby-lang.org/en/"
site = URI(p.params[:url])
site = "http://" + site.host + site.path + site.query
If you need to ensure the url begins with http://, why not use a regex?
p.params = "www.ruby-lang.org/en/"
site = p.params.gsub(/^(­?!http:\/\­/)/, "http­://")
# site = http://www.ruby-lang.org/en/
^(­?!http:\/\­/) matches only when the beginning of the string is not followed by http://

Making a URL in a string usable by Ruby's Net::HTTP

Ruby's Net:HTTP needs to be given a full URL in order for it to connect to the server and get the file properly. By "full URL" I mean a URL including the http:// part and the trailing slash if it needs it. For instance, Net:HTTP won't connect to a URL looking like this: example.com, but will connect just fine to http://example.com/. Is there any way to make sure a URL is a full URL, and add the required parts if it isn't?
EDIT: Here is the code I am using:
parsed_url = URI.parse(url)
req = Net::HTTP::Get.new(parsed_url.path)
res = Net::HTTP.start(parsed_url.host, parsed_url.port) {|http|
http.request(req)
}
If this is only doing what the sample code shows, Open-URI would be an easier approach.
require 'open-uri'
res = open(url).read
This would do a simple check for http/https:
if !(url =~ /^https?:/i)
url = "http://" + url
end
This could be a more general one to handle multiple protocols (ftp, etc.)
if !(url =~ /^\w:/i)
url = "http://" + url
end
In order to make sure parsed_url.path gives you a proper value (it should be / when no specific path was provided), you could do something like this:
req = Net::HTTP::Get.new(parsed_url.path.empty? ? '/' : parsed_url.path)

PHP4 including file during session

I am trying to put second language on my webpage. I decided to use different files for different languages told apart by path - language/pl/projects.ln contains Polish text, language/en/projects.ln - English. Those extensions are just to tell language files from other, the content is simple php:
$lang["desc"]["fabrics"]["title"] = "MATERIAŁY";
$lang["desc"]["fabrics"]["short_text"] = "Jakiś tam tekst na temat materiałów";
$lang["desc"]["services"]["title"] = "USŁUGI";
$lang["desc"]["services"]["short_text"] = "Jakiś tam tekst na temat usłóg";
And then on the index page I use it like so:
session_start();
if (isset($_SESSION["lang"])) {
$language = $_SESSION["lang"];
} else {
$language = "pl";
}
include_once("language/$language/projects.ln");
print $lang["desc"]["fabrics"]["title"];
The problem is that if the session variable is not set everything works fine and array item content is displayed but once I change and set $_SESSION["lang"] nothing is displayed. I tested if the include itself works as it should by putting print "sth"; at the beginning of projects.ln file and that works all right both with $_SESSION["lang"] set and unset.
Please help.
Can you test the return value of session_start() - if it's false, it failed to start the session.
Is it being called before you output anything to the browser? If headers were already sent and your error_reporting level is too low, you won't even see the error message.
Stupid, but - do you set value of $_SESSION['lang'] to valid value like "en"? Does the English translation load correctly when you use it as default value in else block instead of "pl"?
"Jakiś tam tekst na temat usłóg" -> "usług" :)
Can you tell us what does this one output:
if(session_start()) {
echo SID, '<br/>';
if(isset($_SESSION['lang'])) {
echo 'lang = "',$_SESSION['lang'], '"';
}
}
Session starts fine and accidentally I managed to fix it.
I renamed $_SESSION['lang'] to $_SESSION['curr_lang'] and it now works allright. It seams like it didn't like the array and session variable having the same name (?).

Resources