Passing a variable to S3 get_object_url, unexpected character encoding - php

Not an experienced developer and using CodeIgniter for the first time. I'm trying to grab a signed URL for a given MP3 filename stored in S3. This is currently working with the exception of files that contain brackets.
Relevant controller code:
function index ($streamfile) {
// Load S3 client
$this->load->spark('amazon-sdk');
$s3 = $this->awslib->get_s3();
// Define request parameters
$s3bucket = $userdata['s3bucket']; // defined elsewhere
$streamfiletest = ($string)'Crazy_(Remix).mp3';
// Request signed URL
$url = $s3->get_object_url($s3bucket, ***EITHER $streamfiletest or $streamfile***, '5 minutes');
// Fetch status code
$http = new CFRequest($url);
$http->add_header('Content-Type', '');
$http->send_request(true);
$code = $http->get_response_code();
$headers = $http->get_response_header();
// Load the view
$data['filename'] = $url;
$data['debug'] = array(
'file1' => $streamfile,
'file2' => $streamfiletest,
'signed_url' => $url,
'code' => $code,
'headers' => $headers
);
$this->load->view('play', $data);
Relevant view code:
<?php if (isset($debug)) {
echo "DEBUGS:";
echo '<pre>' . print_r($debug, TRUE) . '</pre>';
} ?>
As you can see I either pass $streamfile or $streamfiletest. In the debug I can confirm that both variables are the same string.
When passing $streamfile to the URL request, the URL in the response is incorrect:
DEBUGS:
[file1] => Crazy_(Remix).mp3
[file2] => Crazy_(Remix).mp3
[signed_url] => http://s3-...(removed)/Crazy_%26%2340%3BRemix%26%2341%3B.mp3?AWSAccessKey...
[code] => 404
You can see that the brackets have been strangely encoded %26%2340%3B and therefore I can't find the file in S3.
When passing $streamfiletest however, the response is fine:
DEBUGS:
[file1] => Crazy_(Remix).mp3
[file2] => Crazy_(Remix).mp3
[signed_url] => http://s3-...(removed)/Crazy_%28Remix%29.mp3?AWSAccessKey...
[code] => 200
The brackets are encoded correctly in the signed URL an I get a HTTP 200 from S3.
Any ideas what could be causing this?

In the debug I can confirm that both variables are the same string
Actually, not quite.
If you look closely, it becomes apparent what the url escaped values must mean:
%26%2340%3B %26%2341%3B
& # 40 ; & # 41 ;
Those are numeric html character codes that the browser will display as ( and ) but it does not in fact mean that the two strings have identical content. They only appear to.
The solution, of course, depends on how they are getting transformed that way, and either not doing that, or decoding the numeric character codes.

Try doing the following to decode the url encoded brackets
$data['filename'] = urldecode($url);
This should return the string to its expected format ie with brackets

Related

How can print a json response with php

I'm building a simil web-service in php. This web service can read all record from a table of database and return a list of it in json format.
This is the code of my getArticoli.php file:
<?php
require_once('lib/connection.php');
$query_Articolo = "SELECT CodArticolo,NomeArticolo,Quantita,CodiceBarre, PrezzoAttuale, PrezzoRivenditore,PrezzoIngrosso
FROM VistaArticoli ";
$result_Articoli = $connectiondb->query($query_Articolo);
$answer = array ();
while ($row_Articoli = $result_Articoli->fetch_assoc()) {
$answer[] = ["id" => $row_Articoli['CodArticolo'],
"nome" => '"' . $row_Articoli['NomeArticolo'] . '"',
"quantita" => $row_Articoli['Quantita'],
"codiceBarre" => $row_Articoli['CodiceBarre'],
"codartFornitore" => $row_Articoli['CodiceBarre'],
"PrezzoAttuale" => $row_Articoli['PrezzoAttuale'],
"prezzoRivenditore" => $row_Articoli['prezzoRivenditore'],
"prezzoIngrosso" => $row_Articoli['prezzoIngrosso']];
}
//echo "fine";
echo json_encode($answer);
?>
Now, if I try to open this page, with this url: http://localhost/easyOrdine/getArticoli.php
I don't get the json_response.
In the table of database, there are 1200 records. If I try to insert an echo message in while cycle, I see it.
I have noticed that the problem lays with this field:
"nome"=>'"'.$row_Articoli['NomeArticolo'].'"'
If I remove this field from the response, I can correctly see the json response.
In this field there are any character from a-z/0-9 and special character like "/ * ? - and other".
It is possible that these special character can cause any error of the json answer?
EDIT
I have limit at 5 my query and this is the response:
[{"id":"878","0":"ACCESSORIO PULIZIA PUNTE DISSALDANTE 3 MISURE","quantita":"1","codiceBarre":"DN-705100","codartFornitore":"DN-705100","PrezzoAttuale":"14.39","prezzoRivenditore":null,"prezzoIngrosso":null},
{"id":"318","0":"ACCOPPIANTORE RJ11 TELEFONICO VALUELINE VLTP90920W","quantita":"20","codiceBarre":"5412810196043","codartFornitore":"5412810196043","PrezzoAttuale":"0.68","prezzoRivenditore":null,"prezzoIngrosso":null},
{"id":"320","0":"ACCOPPIATORE AUDIO RCA VALUELINE VLAB24950B","quantita":"5","codiceBarre":"5412810214136","codartFornitore":"5412810214136","PrezzoAttuale":"1.29","prezzoRivenditore":null,"prezzoIngrosso":null},
{"id":"310","0":"ACCOPPIATORE RJ45 VALUELINE VLCP89005W","quantita":"8","codiceBarre":"5412810228843","codartFornitore":"5412810228843","PrezzoAttuale":"0.38","prezzoRivenditore":null,"prezzoIngrosso":null},
{"id":"311","0":"ACCOPPIATORE USB2 VALUELINE VLCP60900B","quantita":"5","codiceBarre":"5412810179596","codartFornitore":"5412810179596","PrezzoAttuale":"1.80","prezzoRivenditore":null,"prezzoIngrosso":null}]
First, remove those extraneous quote characters. You don't need them and they could hurt you down the road:
while ($row_Articoli = $result_Articoli->fetch_assoc()) {
$answer[] = [
"id" => $row_Articoli['CodArticolo'],
"nome" => $row_Articoli['NomeArticolo'],
"quantita" => $row_Articoli['Quantita'],
"codiceBarre" => $row_Articoli['CodiceBarre'],
"codartFornitore" => $row_Articoli['CodiceBarre'],
"PrezzoAttuale" => $row_Articoli['PrezzoAttuale'],
"prezzoRivenditore" => $row_Articoli['prezzoRivenditore'],
"prezzoIngrosso" => $row_Articoli['prezzoIngrosso']
];
}
Then, run your query as is (without the LIMIT), and afterwards run echo json_last_error_msg()';, which could give you a hint to what's going on.
Also, being that your DB is in italian, maybe its encoding is not UTF-8. json_encode requires UTF-8 encoded data. So you may try to utf8_encode your article names before json_encoding the array:
"nome" => utf8_encode($row_Articoli['NomeArticolo']),
And see what you get.
Changing your DB charset to 'utf8mb4' could do the trick as well, and it is usually recommended.

json output for muliple files

I am using this php code which works flawless for one file but when I upload multiple files generated json contains error.
$response = array('file' => ''.$file.'', 'date' => ''.date("d:m:y").'', 'save' => ''.$saving.'%');
echo json_encode($response);
If I am using one file the json output is valid
{"file":"http:\/\/xyy.com\/3\/4\/23968281479202046440249.png","date":"15:11:16","save"
:"<br>Original Size:8.3 Kb, Compressed Size:2.9Kb, Saving:65%"}
but if I am using two or more files json output is invalid and contains error.
{"file":"http:\/\/xxxxxxx.com\/4\/352118314792022053319009.png","date":"15:11:16","save"
:"Saving:68%"}{"file":"http:\/\/way2enjoy.com\/pdf\/1\/2\/3\/4\/270182314792022054204908.png","date":"15:11:16"
,"save":"Saving:65%"}
Any help will be great to make it work for multiple files.
The string with two file objects looks like a couple of JSON objects printed one after another. You should join the arrays before encoding and printing them in order to produce a valid JSON object, e.g.:
$date = date("d:m:y");
$response = [
['file' => $file1, 'date' => $date, 'save' => $saving.'%'],
['file' => $file2, 'date' => $date, 'save' => $saving.'%'],
];
// Also, use the correct MIME type for JSON content
header('Content-Type: application/json');
echo json_encode($response);
Otherwise, make separate HTTP requests for each file.

How can I get base64 to display as a base64 string in PHP?

I have been working with an API that uses tokens for authentication. I am using PHP's SoapClient class to login to said API and retrieve the tokens I need to make additional requests..
The problem is that the API should return base64 string tokens, but in PHP, they are not being dealt with as bas64 strings.. I get a string that looks like this:
ç$P%’™‹2E‡ºË>Šo_ÑÒúé±N5Tá#=œã
Instead of a base64 string that looks like this:
ERy/R5ycTG0sbRyH9KeMGpi9kPr6kROyaarFYgsPEOU=
Note: These 2 strings are not actually related, as I could not get php to display the base64 representation of that 1st string. The base64 string I listed as the 2nd string came from a valid soapUI response.
So I have confirmed with soapUI, that I the tokens do in fact come over as base64 strings, but I cannot get PHP to use them as strings for additional requests. I have tried doing base64_decode and base64_encode on the strings, along with a bunch of other encodings/decodings, but none of them have worked so far.
Any ideas as to what is going on here, and how I might be able to use the data the way I need?
Edit: Here is the code I use to get the token data. It's the DAT api if that helps.
$wsdlDat = "http://someurl.com:8000/wsdl/someWSDL.wsdl";
$soapOptions = array( 'loginId' => $userName, 'password' => $userPassword, 'thirdPartyId' => 'KEFKA_TMS', 'trace' => 1 );
$this->datClient = new SoapClient( $wsdlDat , $soapOptions );
$creds = array( 'loginId' => $userName, 'password' => $userPassword, 'thirdPartyId' => 'KEFKA_TMS' );
$loginOptions['loginOperation'] = $creds;
$this->token = $this->datClient->Login($loginOptions);
$this->token = datObjectToArray($this->token); // TURN STD CLASS OBJ TO ARRAY
$token = $this->token['loginResult']['loginSuccessData']['token']['primary'];
$token2 = $this->token['loginResult']['loginSuccessData']['token']['secondary'];
$exp = $this->token['loginResult']['loginSuccessData']['expiration'];

How to Encode Web Image URL into JSON using PHP code

I am writing an app in which i am allowing user to enter their product details into a framework [i have made on PHP] and then by using that framework i am encoding data into json and that encoded data i am retrieving in my Android App using web services.
But now issue is i am not able to encode web image url therefore i am not getting correct image path in json:-
Like:
I have given this link to encode into JSON:
"imageurl" => "http://www.libpng.org/pub/png/img_png/pnglogo-blk-sml1.png"
but whenever i see encoded web image url in JSON getting something like this:
"imagepath":"http:\/\/www.libpng.org\/pub\/png\/img_png\/pnglogo-blk-sml1.png"
why i am getting wrong image url....
I don't know how can i resolve this issue..please someone help me....
albums.php:
<?php
/*
*Simple JSON generation from static array
*Author: JSR
*/
include_once './data.php';
$albums = array();
// looping through each album
foreach ($album_tracks as $album) {
$tmp = array();
$tmp["id"] = $album["id"];
$tmp["name"] = $album["album"];
$tmp["description"] = $album["detail"];
$tmp["imagepath"] = $album["imageurl"];
$tmp["songs_count"] = count($album["songs"]);
// push album
array_push($albums, $tmp);
}
//printing json
echo json_encode($albums);
?>
data.php:
<?php
/*
*Simple JSON generation from static array
*Author: JSR
*/
$album_tracks = array(
1 => array(
"id" => 1,
"album" => "Appetizers",
"detail" => "All appetizers served with mint and tamarind chutneys.",
"imageurl" => "http://www.libpng.org/pub/png/img_png/pnglogo-blk-sml1.png"
)
));
?>
For me it works
<script>
var str="http:\/\/www.libpng.org\/pub\/png\/img_png\/pnglogo-blk-sml1.png";
document.write("<img src='" + str + "'/>");
</script>
Whenever you send image path or url in json, it escapes all the slashes, quotes, etc. So you can use some regex like s/\////gis to get rid of these escapes characters and get the original url or location.

OpenID check_authentication not working

I'm trying to get a check_authentication response working, but so far, all consumers reject it and say that my server denied check_authentication.
This is the GET and POST data that my server file receives:
$_GET:
Array
(
[mode] => profile
[username] => hachque
[domain] => roket-enterprises.com
)
$_POST:
Array
(
[openid_assoc_handle] => {HMAC-SHA1}{4b00d7b2}{vo1FEQ==}
[openid_identity] => http://www.roket-enterprises.com/openaccount/openid:hachque
[openid_mode] => check_authentication
[openid_response_nonce] => 2009-11-16T04:40:18Zrrz8R4
[openid_return_to] => http://openiddirectory.com:80/openidauth/id/c/finish_auth.php?nonce=adCevd6T
[openid_sig] => SgFE5iT9IGd5EftkrZ72mgCHiLk=
[openid_signed] => assoc_handle,identity,mode,response_nonce,return_to,signed,sreg.email,sreg.fullname,sreg.nickname
[openid_sreg_email] => jrhodes#roket-enterprises.com
[openid_sreg_fullname] => James Rhodes
[openid_sreg_nickname] => jrhodes
)
This is the header reponse that I am outputting (contains POST data as it was explained to me on IRC that sending the key-values as headers shouldn't be done to the consumer server EDIT: Come to think of it, it doesn't make much sense RESPONDING with POST data. Maybe some here can explain the whole process of check_authentication clearly).
Content-Type: text/plain;
Content-Length: 675;
openid.mode=id_res&openid.assoc_handle=%7BHMAC-SHA1%7D%7B4b00d7b2%7D%7Bvo1FEQ%3D%3D%7D&openid.identity=http%3A%2F%2Fwww.roket-enterprises.com%2Fopenaccount%2Fopenid%3Ahachque&openid.response_nonce=2009-11-16T04%3A40%3A18Zrrz8R4&openid.return_to=http%3A%2F%2Fopeniddirectory.com%3A80%2Fopenidauth%2Fid%2Fc%2Ffinish_auth.php%3Fnonce%3DadCevd6T&openid.signed=assoc_handle%2Cidentity%2Cmode%2Cresponse_nonce%2Creturn_to%2Csigned%2Csreg.email%2Csreg.fullname%2Csreg.nickname&openid.sreg_email=jrhodes%40roket-enterprises.com&openid.sreg_fullname=James+Rhodes&openid.sreg_nickname=jrhodes&openid.sig=MGVhMmQ1Mzg4ZWFlMWY1OWVlYjlmZmY0Njc3OTc5YWIzMjM3NGFjMQ%3D%3D&openid.is_valid=true;
This is the PHP code that my file is using to handle check_authentication (remember that PHP turns all . characters into _ for $_GET and $_POST variables since they aren't valid character in PHP array keys):
// Retrieve the OpenID information from the $_REQUEST data
// I'm not sure whether it's possible that this data might
// come in on the $_GET parameter instead of $_POST, so that's
// what it uses $_REQUEST.
$assoc_handle = $_REQUEST['openid_assoc_handle'];
$sig = $_REQUEST['openid_sig'];
$signed = $_REQUEST['openid_signed'];
// The method for returning data is via the headers outputted
// by the webserver. Create an array that stores the headers
// to be returned.
$keys = array(
'openid.mode' => 'id_res',
'openid.assoc_handle' => $_REQUEST['openid_assoc_handle'],
'openid.identity' => $_REQUEST['openid_identity'],
'openid.response_nonce' => $_REQUEST['openid_response_nonce'],
'openid.return_to' => $_REQUEST['openid_return_to'],
'openid.signed' => $_REQUEST['openid_signed'],
'openid.sreg_email' => $_REQUEST['openid_sreg_email'],
'openid.sreg_fullname' => $_REQUEST['openid_sreg_fullname'],
'openid.sreg_nickname' => $_REQUEST['openid_sreg_nickname']
//'openid_mode' => 'id_res'
);
// The server may request that we invalidate the user's session
// via $_REQUEST['openid_invalidate_handle']. In this case we
// will clear the session data (you may need to change this
// depending on how you implement the session). After doing so
// we continue and tell the server we did via a variable
if (strlen($_REQUEST['openid_invalidate_handle']) > 0)
{
// Reset the session
session_unset();
session_name('openid_server');
session_start();
// Set the header we need to return
$keys['openid.invalidate_handle'] = $_REQUEST['openid_invalidate_handle'];
}
// We need to validate the signature now. This constructs a token_contents
// for signing the data. The signing key is returned as openid.sig
// and is generated with base64(HMAC(secret(assoc_handle), token_contents)
$token_contents = '';
foreach (explode(',', $signed) as $param) {
$post = preg_replace('/\./', '_', $param);
$token_contents .= sprintf("%s:%s\n", $param, $_REQUEST['openid_' . $post]);
}
// Generate our openid.sig and add it to the list of keys to
// return.
$keys['openid.sig'] = base64_encode(hash_hmac('sha1',$token_contents,$assoc_handle));
// Add the data that we are sharing (via SReg) to the headers.
// For now this is fixed data (see action_authorization.php).
//$keys["sreg.fullname"] = 'James Rhodes';
//$keys["sreg.nickname"] = 'jrhodes';
//$keys["sreg.email"] = 'jrhodes#roket-enterprises.com';
// Just accept the request for now..
// phpMyID does some kind of secret-shared-key thing
// here to determine whether it is valid. I'm not
// quite sure how that process works yet, so we are just
// going to say go ahead.
$keys["openid.is_valid"] = "true";
// We need to format the $keys array into POST format
$keys_post = "";
$keys_post_first = true;
foreach ($keys as $name => $value)
{
if ($keys_post_first)
$keys_post_first = false;
else
$keys_post .= "&";
$keys_post .= urlencode($name) . "=" . urlencode($value);
}
// Now output the POST data
header('Content-Type: application/x-www-form-urlencoded');
header('Content-Length: ' . strlen($keys_post));
header($keys_post);
Can anyone help me with my problem? I've been trying to get this working for months and I can't get a straight answer on how this stage of OpenID authentication is meant to work.
First of all, although PHP transforms periods to underscores in parameter names, be sure you're sending periods and not underscores.
Secondly, your check_authentication response should only have three parameters, but you have six. Check the spec and fix up your response and see if that helps.
Andrew Arnott,you're wrong!
documentation from openid.net:
11.4.2.1. Request Parameters
openid.mode
Value: "check_authentication"
Exact copies of all fields from the authentication response, except for "openid.mode".
may be more than three fields!
I had a similar issue. In my case, the client (relying party) failed to resolve the name of the OpenId provider to the correct ip. Although this is unlikely to be the case, please check name resolution on your relying server.

Categories