where does this URL need urlencoding? - php

I hosted a website i worked on on amazon web services, and for some reason some things dont work compared to when I run it locally on localhost.
of those things are the
if (array_key_exists("error", $json))
function and
the file_get_contents function.
Ive commented out the array key exists part and that solved the issue, at least for that part of logging in, until i get to the view documents page where a slim application error displays
failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
and the issue for that lies in the viewdocspage.php file, particularly this code:
<?php
$raw = file_get_contents("http://cosoft.us-east-1.elasticbeanstalk.com/cosoft/mywiki/api.php?action=query&list=allpages&format=json");
$pages_response = json_decode($raw, true);
$pages_array = $pages_response["query"]["allpages"];
$page_titles = [];
I looked and read up on many threads that the issue lies with the file_get_contents in which the URL contains special characters, such as spaces (which mine doesnt have) and so needs to be encoded, using urlencode (or rawurlencode..?)
now ive tried encoding the whole url like this:
$raw = file_get_contents(urlencode("http://cosoft.us-east-1.elasticbeanstalk.com/cosoft/mywiki/api.php?action=query&list=allpages&format=json"));
but that resulted in this error:
slim error
Message: file_get_contents(http%3A%2F%2Fcosoft.us-east-1.elasticbeanstalk.com%2Fcosoft%2Fmywiki%2Fapi.php%3Faction%3Dquery%26list%3Dallpages%26format%3Djson): failed to open stream: No such file or directory
I figured that this may happen since I read that not all the URL should be wrapped by this encoding, but heres where Im stuck: which part of the url do i use the encoding on? the only special characters i keep coming accross regarding this error is spaces, but i dont have any spaces, so its something else which i dont know what it is...
Help is appreciated, thanks!

You would just need to url_encode the parameters. Say you had a value $value='My name is earl'
If you wanted to pass this value as a parameter in your url
http://somesite.com/?name=$value there would be spaces in the value that is url_encoded. So if you encode it as 'http://somesite.com/?name='.urlencode($value), when this is encoded the value will turn into My+name+is+earl

Reading resources from a URL may be restricted by the server's configuration.
http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
You should use CURL for this.

Related

Using /update-cache requests to update AMP pages

Trying to use /update-cache/ requests to update some AMP pages, but i'm getting 403 errors.
Removed the opening part/protocol from the urls since i don't have the reputation to post this many links, but everything is https.
I have a page at: www.qponverzum.hu/ajanlat/budapest-elozd-meg-a-hajhullast-mikrokameras-hajdiagnosztika-hajhagyma-es-fejborvizsgalattal-tanacsadas-5000-ft-helyett-2500-ft-ert-biohajklinika-szepsegapolas-egeszseg/amp
From the AMP cache: www-qponverzum-hu.cdn.ampproject.org/c/s/www.qponverzum.hu/ajanlat/budapest-elozd-meg-a-hajhullast-mikrokameras-hajdiagnosztika-hajhagyma-es-fejborvizsgalattal-tanacsadas-5000-ft-helyett-2500-ft-ert-biohajklinika-szepsegapolas-egeszseg/amp
I've been following the documentation at developers.google.com/amp/cache/update-ping
If i make an /update-ping request, it seems to work fine, returns a 200 no content response, but due to the high amount of urls/pages we would like to use /update-cache since it allows for a higher request rate.
I've created a private and public RSA key and made the public key acessible at www.qponverzum.hu/.well-known/amphtml/apikey.pub
I've been trying to use the following php code to generate the update-cache url
$ampBaseUrl = "https://www-qponverzum-hu.cdn.ampproject.org";
$signatureUrl = '/update-cache/c/s/www.qponverzum.hu/ajanlat/budapest-elozd-meg-a-hajhullast-mikrokameras-hajdiagnosztika-hajhagyma-es-fejborvizsgalattal-tanacsadas-5000-ft-helyett-2500-ft-ert-biohajklinika-szepsegapolas-egeszseg/amp?amp_action=flush&_ts='.time();
// opening the private key
$pkeyid = openssl_pkey_get_private("file://private-key.pem");
// generating the signature
openssl_sign($signatureUrl, $signature, $pkeyid)
// urlsafe base64 encoding
$signature = urlsafe_b64encode($signature);
// final url for updating
$ampUrl = $ampBaseUrl.$signatureUrl."&amp_url_signature=".$signature;
The urlsafe_b64encode function I'm using:
function urlsafe_b64encode($string) {
return str_replace(array('+','/','='),array('-','_',''), base64_encode($string));
}
$ampUrl ends up looking like this: https://www-qponverzum-hu.cdn.ampproject.org/update-cache/c/s/www.qponverzum.hu/ajanlat/budapest-elozd-meg-a-hajhullast-mikrokameras-hajdiagnosztika-hajhagyma-es-fejborvizsgalattal-tanacsadas-5000-ft-helyett-2500-ft-ert-biohajklinika-szepsegapolas-egeszseg/amp?amp_action=flush&amp_ts=1500362660&amp_url_signature=NjTCnmqUGpMY_CokGxchoczSOxnTLQvcQsX4fv2gIhW3H8hVw24mKCpmNoyV-9LND3OAR9ld80KeMH3lip863p_wBorIy1BAag7bRfvWcxsPrbqbox87VMrUWCEsry5epWxKYl2qNCT1GMv8SYAJ5WR0QZR0Qjvw5MXfZjohmbvrxJ7mWlc7fcvWoIXuO_q_yFkhi7A-fOZWm9sy8UDIlq-zNEPkVUwfqfWc_HbNHgvrk9Z6zZSNzB-dWAOT6QYAc1KeEVOIbvQxKkLkGMArTpydj5iLxz0aERvglKRl215Bqh6_jZu95T5yKv7X4R127ylpWYW2YDlTR9bgRE7Faw
If I make a simple GET request to this url(with a browser or curl) i get a 403 error('Your client does not have permission to get URL').
I've checked the webserver logs, but it doesn't seem like there're any requests made to the public keys url.
I think I'm missing something very obvious, so any feedback would be greatly appreciated.
There's an error in $signatureUrl - it should be amp_ts instead of _ts in the query params and in openssl_sign add the fourth parameter
openssl_sign($signatureUrl, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
The signature needs to be signed with SHA256, if you omit the last parameter it uses SHA1
I've used your script with these 2 changes for my work project and it's working fine.
It should return "OK" in the response body if it's fine.
Check this https://gist.github.com/krzysztofbukowski/739ccf4061d69360b5b2c8306f5878bd
Try to set the response content type to "text/plain" for https://www.qponverzum.hu/.well-known/amphtml/apikey.pub as recommended in here
=========
I use the script for update cache, but I got the 403 forbidden error.
It's hard to debug and find out the root cause.
Did someone succed?
All the other answers have really helped - thanks. I'm adding a little here which may hopefully also help.
As #kul3r4 points out (I missed it first time round) the apikey.pub file needs to be served as plain text. Here is the Nginx config rule for that;
location /.well-known/amphtml/apikey.pub { ## serve amp public key as plain/text
default_type text/plain;
}
If you are echoing out #Krzysztof Bukowski's answer to the screen, the fact that &amp is in the url parameters means my browser was stripping out the amp part of the amp_ts and amp_url_signature so be aware of that.
If you are struggling with the file paths and syntax of this;
$pkeyid = openssl_pkey_get_private("file://amp-private-key.pem");
Then just follow this answer here and put the contents of your private key in a variable -> Openssl and PHP

file_get_contents() "failed to open stream: Network is unreachable" error on valid link

There's an extremely simple example of using Youtube API in php that somehow fails to work in my case, and I couldn't find a definitive solution for.
I desire to use the Youtube API without any wrapper, by myself, to get data of videos. The following search:list query works perfectly when I try accessing it from within by browser (as a link), but in php, I get that error when I try the same.
$apikey_YT = <my API key>;
$ytrequrl = "https://www.googleapis.com/youtube/v3/search?".
"part=snippet".
"&maxResults=50".
"&q=doom".
"&relatedToVideoId=h8j2zj-A5tE".
"&type=video".
"&key=${apikey_YT}";
$result = file_get_contents($ytrequrl);
var_dump($result);
The potential issues were URL encoding, or allowing allow-url-fopen, but neither seemed to help in my case: the former actually gave a new error message: No such file or directory.
What can I do?
Try it like this. Might be your formatting.
This works for me.
$ytrequrl = 'https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=50&q=doom&relatedToVideoId=h8j2zj-A5tE&type=video&key='.$apikey_YT;
$info= file_get_contents($ytrequrl);
$info= json_decode($info, true);
print("<pre>".print_r($info,true)."</pre>");

file_get_contents not working when parameters included in a relative url

I am trying to create a simple web service that will give a result depending on parameters passed.
I would like to use file_get_contents but am having difficulties getting it to work. I have researched many of the other questions relating to the file_get_contents issues but none have been exactly the situation I seem to having.
I have a webpage:
example.com/xdirectory/index.php
I am attempting to get the value of the output of that page using:
file_get_contents(urlencode('https://www.example.com/xdirectory/index.php'));*
That does not work due to some issue with the https. Since the requesting page and the target are both on the same server I try again with a relative path:
file_get_contents(urlencode('../xdirectory/index.php'));
That does work and retrieves the html output of the page as expected.
Now if I try:
file_get_contents(urlencode('../xdirectory/index.php?id=100'));
The html output is (should be): Hello World.
The result retrieved by the command is blank. I check the error log and have an error:
[Fri Dec 04 12:22:54 2015] [error] [client 10.50.0.12] PHP Warning: file_get_contents(../xdirectory/index.php?id=100): failed to open stream: No such file or directory in /var/www/html/inventory/index.php on line 40, referer: https://www.example.com/inventory/index.php
The php.ini has these set:
allow_url_fopen, On local and On master
allow_url_include, On local and On master
Since I can get the content properly using only the url and NOT when using it with parameters I'm guessing that there is an issue with parameters and file_get_contents. I cannot find any notice against using parameters in the documentation so am at a loss and asking for your help.
Additional Notes:
I have tried this using urlencode and not using urlencode. Also, I am not trying to retrieve a file but dynamically created html output depending on parameters passed (just as much of the html output at index.php is dynamically created).
** There are several folks giving me all kind of good suggestions and it has been suggested that I must use the full blown absolute path. I just completed an experiment using file_get_contents to get http://www.duckduckgo.com, that worked, and then with a urlencoded parameter (http://www.duckduckgo.com/?q=php+is+cool)... that worked too.
It was when I tried the secure side of things, https://www.duckduckgo.com that it failed, and, with the same error message in the log as I have been receiving with my other queries.
So, now I have a refined question and I may need to update the question title to reflect it.
Does anyone know how to get a parameterized relative url to work with file_get_contents? (i.e. 'file_get_contents(urlencode('../xdirectory/index.php?id=' . urlencode('100'))); )
Unless you provide a full-blown absolute protocol://host/path-type url to file_get_contents, it WILL assume you're dealing with a local filesystem path.
That means your urlencode() version is wrongly doing
file_get_contents('..%2Fxdirectory%2Findex.php');
and you are HIGHLY unlikely to have a hidden file named ..%2Fetc....
call url with domain, try this
file_get_contents('https://www.example.com/inventory/index.php?id=100');
From reading your comments and additional notes, I think you don't want file_get_contents but you want include.
see How to execute and get content of a .php file in a variable?
Several of these answers give you useful pointers on what it looks like you're trying to achieve.
file_get_contents will return the contents of a file rather than the output of a file, unless it's a URL, but as you seem to have other issues with passing the URI absolutely....
So; you can construct something like:
$_GET['id'] = 100;
//this will pass the variable into the index.php file to use as if it was
// a GET value passed in the URI.
$output = include $_SERVER['DOCUMENT_ROOT']."/file/address/index.php";
unset($_GET['id']);
//$output holds the HTML code as a string,
The above feels hacky trying to incorporate $_GET values into the index.php page, but if you can edit the index.php page you can use plain PHP passed values and also get the output returned with a specific return $output; statement at the end of the included file.
It has been two years since I used PHP so I am just speculating about what I might try in your situation.
Instead of trying fetching the parsed file contents with arguments as a query string, I might try to set the variables directly within the php script and then include it (that is if the framework you use allows this).
To achive this I would use pattern:
ob_start -> set the variable, include the file that uses the variable -> ob_get_contents -> ob_end_clean
It is like opening your terminal and running the php file with arguments.
Anyway, I would not be surprised if there are better ways to achieve the same results. Happy hacking :o)
EDIT:
I like to emphasize that I am just speculating. I don't know if there are any security issues with this approach. You could of course ask and see if anyone knows here on stackoverflow.
EDIT2:
Hmm, scrap what I said last. I would check if you can use argv instead.
'argv' Array of arguments passed to the script. When the script is run on the command line, this gives C-style access to the command line parameters. When called via the GET method, this will contain the query string. http://php.net/manual/en/reserved.variables.server.php
Then you just call your php script locally but without the query mark indicator "?". This way you can use the php interpreter without the server.
This is likely to be the most general solution because you can also use argv for get requests if I am understanding the manual correctly.

file_get_content(converting to htmlspecialchars)

So I have this url http://my-server.com/feeds/feed.pl?op=retrieveIncidents&type=social,government&cbsa=31100 that contains xml data built by another process. Now I was using file_get_contents() with the url hardcoded and it worked perfectly. At this stage of dev I had to start using the config files and the cbsa codes from the current user logged in the application.
Now this /feeds/feed.pl?op=retrieveIncidents&type=social,government&cbsa= comes from the config.
This 31100 comes from the user object.
This http://my-server.com comes from a helper fn().
$server = $this->serverUrl();
$config = new Zend_Config_Ini(APPLICATION_PATH.'/configs/application.ini', APPLICATION_ENV);
$curOperator = Default_Model_Operator::getActiveOperator();
$feedUrl = $server.$config->ims->idfFeed.$curOperator->regions;
If I print/echo $feedUrllooks like http://my-server.com/feeds/feed.pl?op=retrieveIncidents&type=social,government&cbsa=31100
But when I do $feed = file_get_contents($feedUrl) I get
Warning: file_get_contents(http://vdot.orion.meridian-enviro.com/feeds/feed.pl?op=retrieveIncidents&type=social,government&cbsa=31100) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/Agena/lvegerano/svn/webapps/ims/trunk/phpfiles/application/views/scripts/chp/list-for-dashboard.phtml on line 9
Make note of the &. I have tried htmlentities_decode(),urlencode()and other and cant get this to works. What can I do so file_get_contents() translate &to&?
Any help on how to fix this would be greatly appreciated.
I guess I forgot to answer this. The problem was our varnish setup. It is setup to lookup urls and if recognized inserts the host name. Because I had just started working here I was not aware of this feature. Therefore the error I thought it was it wasn't since the varnish was masking the url.

PHP - file get contents not working when passing URL from database otherwise works fine

I am trying to get contents of a web page using file_get_contents
Scenario One:
When I pass a single URL directly from a text field it works perfect.
Scenario Two:
When I take multiple URLs in a text area and then store them in a Mysql database. Then I run a for loop to pass the URL to the same code snippet as in scenario 1 it returns this error
Warning: file_get_contents( URL ) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error in C:\wamp\www\scrape\urltoscrape.php on line 13
I felt that the prob was with the datatype being used. So it was initially varchar I changed it to text.
I also tried strip space. When I echo the URL out it prints it as is with no additional characters or spaces.
Also since it is in a loop I do not think the issue is with multiple URLs being passed at a time. All the URLs individually work fine when tried through scenario 1.
Please help. I am at my wits end.
file_get_contents( URL )
This error tells you, it is trying to open the URL "URL". Make sure you did not forget a $ before the variable name.
file_get_contents() expects a string which it has to follow. Now if you write url as its argument, it will try to fetch the contents of URL
try
file_get_contents($url);

Categories