[TIP/TRICK] Get Facebook and others to load a shared url.

Started by nend, November 28, 2011, 07:43:29 PM

Previous topic - Next topic

nend

Well this is a tip or should I say a hack that allows Facebook and some others to load information from pages that have been shared on a SMF Forum. It also makes the link load from the social site, lol.

The main reason Facebook and SMF collide is because SMF uses ";" to separate items in the query string and well Facebook does not support semicolons in urls, sorry to say. Any url with a semicolon separator will get everything after that semicolon put in the first variable in the query string. Plus everything after that like ; and = will get converted.

The trick here is to convert them back before SMF loads. Before anyone says anything, yeah I know I could of did a http redirect but Facebook will not follow it anyways, so no use there. :(

Will here it is, put this in the beginning of your index.php

if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}

SA™

http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

nend

That is what it is for, ;)

When the user clicks on the link in FB or G+ they get a link like the one you have above, but that doesn't work in SMF so it has to be converted and all the post information pulled from it, however SMF does not convert a url that has been encoded this way. Maybe it shoud, maybe not, however we can make it do it.

Say I have a gallery item
http://site.com/index.php?action=media%3Bsa%3Ditem%3Bin%3D120

All the script sees is this below, so it can't find anything of meaning in that mess so we end up on the board index.

var                   value
actionmedia%3Bsa%3Ditem%3Bin%3D120

With this hack it converts the values so we can actually go to the page we are meant to go to.

var                   value
actionmedia
saitem
in120

SA™

thats what i fault but it doesnt seem to work

with the code added it goes to the action fine [without it goes to the boardindex]

after conversion the url still looks like this

http://www.sa-smf.com/community/index.php?action=kb%3Barea%3Darticle%3Bcont%3D41

try the url above and your see what i mean
http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

nend

I just checked my sources, I changed the script a little, not much though. I remember having the same problem you where.
// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}

SA™

http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

nend

Ahh, I see the problem, I only exploded the uri string once. I need to explode each instance, So that script can only do up to two values. Try this, I will update the script to count instances at the top, this one only does 10 instances. It should do the trick to test though.

// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, 10);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}

SA™

http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

nend

I can't produce the same results, every url works.

http://wrestletopia.2-si.net/n/index.php?action=media%3Bsa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/index.php?action%3Dmedia%3Bsa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/media/?sa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/media/?sa=item%3Bin%3D120

Can you get the output of $_SERVER["REQUEST_URI"] at the end of the script, I doubt this would be different though.
Maybe the variable type isn't set as a integer, if you consider it in the beginning it is a string, maybe it stays as a string and then later on there is a check to see if the value is a integer for security reasons and then the script is haulted on a error.

Try
// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = is_numeric($key[1]) ? (int)$key[1] : $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] =  is_numeric($key[1]) ? (int)$key[1] : $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}


I haven't tested this, it looks typo free though, lol.

Oldiesmann

Wouldn't it just be simpler to pass the URL through PHP's urldecode() function?
Michael Eshom
Christian Metal Fans

nend

Quote from: Oldiesmann on January 10, 2012, 08:50:49 AM
Wouldn't it just be simpler to pass the URL through PHP's urldecode() function?
It will decode the url ok, but we still need the values from it. Since these sites encode the url the values are not passed. I actually did it the way you suggested at first and did a redirect and FB did not follow. As easy as I thought it was at the beginning in the end it was no easy fix, lol. ;)

SA™

tryed the new code it still didnt work correct nend :/
http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

nend

Well I am stumped about your site, I tried the simple way like suggested used urldecode and then tried a redirect then I seen the problem.

When you have a url like this urldecode doesn't work because it consider it as a value of action and it is right. But this is one of the common malformed urls that FB and G+ spits out.
site.com/index.php?action=media%3Bsa%3Ditem%3Bin%3D120

So try this we are redirecting on this one, but not using urldecode. Shouldn't be too much of a problem unless a mod submits data in the url with the "=" sign then it would be a problem. We have to disable for this or something, haven't ran into compatibility issues yet though.

if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: ".$_SERVER["REQUEST_URI"]);
}

SA™

http://samods.github.io/SAChatBar/

Xbox Live: smokerthecheese 360 or xbone
My Work
Piano Movers / Delivery service
QuoteMy allies are dead.
I'm 'bout to be too.
Zombies are chasing me.
F*** it, I'm screwed -___-

spcx

Hey nend, used your trick to solve my linking prob on FB. But a quick question, how can I make my link on FB:

becomes
http://triggerinc.net/index.php?action=classifieds&sa=view&id=32

instead of ;

Reason why is that you can try both & and ; on the same URL, but it brings different results on FB. If I use & it displays the link with the pic and body copy of the link which is what I want!

Is there a way to work around this?

petb

There where much more Users with this Problem,..
http://www.simplemachines.org/community/index.php?topic=474432.msg3316966#msg3316966
http://www.simplemachines.org/community/index.php?topic=471506.msg3295593#msg3295593

My Question was:
Why did smf changed this ?
Because older Versions havent any Problem with the %3B and %3D in the Query String.

nend

Quote from: spcx on April 25, 2012, 02:52:59 PM
Hey nend, used your trick to solve my linking prob on FB. But a quick question, how can I make my link on FB:

becomes
http://triggerinc.net/index.php?action=classifieds&sa=view&id=32

instead of ;

Reason why is that you can try both & and ; on the same URL, but it brings different results on FB. If I use & it displays the link with the pic and body copy of the link which is what I want!

Is there a way to work around this?

Maybe with quite a bit of work, what you have is a disagreement here. SMF prefers ; in urls and Facebook hates them and prefers & to separate the arguments. So if you want SMF to support & instead of ; you might want to search the entire code base or edit the output buffer. If your going to miss with the buffer though you might as well just install one of these SEO url mods like PrettyURLs or SimpleSEF.

Quote from: petb on May 19, 2012, 10:32:41 AM
There where much more Users with this Problem,..
http://www.simplemachines.org/community/index.php?topic=474432.msg3316966#msg3316966
http://www.simplemachines.org/community/index.php?topic=471506.msg3295593#msg3295593

My Question was:
Why did smf changed this ?
Because older Versions havent any Problem with the %3B and %3D in the Query String.

I think the changes in SMF was due to a anticipated HTML standard that still isn't accepted, I however doubt it will ever be accepted. This standard will say you have to use ; instead of &.

demlak

Quote from: nend on November 28, 2011, 07:43:29 PM
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}

i would like to make a mod of this code..
(just change the %3D in first line to %3B)

since im not using FB and also my board is not working for non-logged-in users..  this FB thing is not relevant for us.. but it is relevant for activation links on webmailers like gmx, gmail, web.de, and so on.. webmailers got many problems on those links in activation mails.. but some interpret "=" correct.. but it seems no webmailer interprets the semicolon correct.

if it´s ok for you.. i will submit this as a mod to SMF... since i don´t want to steal code.. i need your permission =) and you will be named in there...

nend


rodelio.lagahit

and this mod killed my forum :(
any idea how to remove this for my site to be accessible again?

Advertisement: