CURL POST: Ignore the response-body like it happens with FOLLOWLOCATION - php

How can I not download request's body?
Using CURLOPT_NOBODY it performs HEAD request not sending POST data.
Uing FOLLOWLOCATION=0 I make request+body+request+body.
Using FOLLOWLOCATION=1 it makes request+request+body if it redirects to url I need.
If it redirects to the page I don't need I make request+request+body+request+body
I need: Request ignoring body + request with body.
Something like 3rd option but with redirect to url I really need (that obviously I can't control).

Related

Slim3 redirect GET request as POST request

Just started learning Slim3. Have been spending some time figuring out how to perform redirects with overriding original request type with no success.
I want the /origin route to perform the redirect to /dest route.
/origin route receives GET request performs validation and after success redirects with POST request to /dest uri route. Here is the screenshot. I think I am doing something dumb here:
$app->get('/origin', function($req,$res,$args)
{
$req= $req->withHeader('X-Http-Method-Override','POST');
return $res->withRedirect('/dest');
});
$app->post('/dest', function($req,$res,$args)
{
echo "this is destination page";
});
As noted in the comment, this is not possible as the request made by the browser is not in your control.
When you call ->withRedirect() you are sending a status code of 302 and a Location header to the HTTP client (web browser usually).
The web browser sees the 302 status code and then issues a new request to the URL in the Location header. The server has no control over this request and every web browser makes a GET request.
Now, if you want to redirect a POST request to another URL and keep the same POST method, then you can use the 307 status code with a Location header and the browser should do the right thing. Note that this code does not let you change a GET into a POST - it just keeps the same method as the original request for the followup redirection request.

Google drive api file_get_contents and refferer

I am trying to list files from google drive folder.
If I use jquery I can successfully get my results:
var url = "https://www.googleapis.com/drive/v3/files?q='" + FOLDER_ID + "'+in+parents&key=" + API_KEY;
$.ajax({
url: url,
dataType: "jsonp"
}).done(function(response) {
//I get my results successfully
});
However I would like to get this results with php, but when I run this:
$url = 'https://www.googleapis.com/drive/v3/files?q='.$FOLDER_ID.'+in+parents&key='.$API_KEY;
$content = file_get_contents($url);
$response = json_decode($content, true);
echo json_encode($response);
exit;
I get an error:
file_get_contents(...): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden
If I run this in browser:
https://www.googleapis.com/drive/v3/files?q={FOLDER_ID}+in+parents&key={API_KEY}
I get:
The request did not specify any referer. Please ensure that the client is sending referer or use the API Console to remove the referer restrictions.
I have set up referrers for my website and localhost in google developers console.
Can someone explain me what is the difference between jquery and php call and why does php call fails?
It's either the headers or the cookies.
When you conduct the request using jQuery, the user agent, IP and extra headers of the user are sent to Google, as well as the user's cookies (which allow the user to stay logged in). When you do it using PHP this data is missing because you, the server, becomes the one who sends the data, not the user, nor the user's browser.
It might be that Google blocks requests with invalid user-agents as a first line of defense, or that you need to be logged in.
Try conducting the same jQuery AJAX request while you're logged out. If it didn't work, you know your problem.
Otherwise, you need to alter the headers. Take a look at this: PHP file_get_contents() and setting request headers. Of course, you'll need to do some trial-and-error to figure out which missing header allows the request to go through.
Regarding the referrer, jQuery works because the referrer header is set as the page you're currently on. When you go to the page directly there's no referrer header. PHP requests made using file_get_contents have no referrer because it doesn't make much sense for them to have any.

PHP: How to detect a website redirect that returns a '404' status code?

I am writing a small php script that can distinguish two between different kinds of responses from a third-party website.
For the human visitor, recognizing the difference is fairly easy: Response #1 is a bare-bones 404 error page, whereas response #2 redirects to the main page.
For my script, this turns out to be somewhat more difficult. Both types return a '404' status code, file_get_contents() returns empty for both and the "redirect" doesn't really register as a redirect (like I said, there's a '404' status code, not a '30X'). Get_headers() shows no distinction, either (no "Location:" or anything of that sort).
Any way I can get this done?
There are many ways to do a redirect:
the HTTP response codes for redirect (usually 301 and 302) accompanied by the Location: header that contains the URL
HTTP/1.1 302 Found
Location: http://www.example.org
the HTTP header Refresh:; it contains a number of seconds to wait and the new URL:
Refresh: 0; url=http://www.example.org
the HTML meta element that emulates the Refresh HTTP header:
<meta http-equiv="Refresh" content="0; url=http://www.example.org">
Javascript:
<script>document.location = 'http://www.example.org';</script>
Note that there are countless possibilities to redirect using Javascript. What is common to all of them is the usage of the location property of document or window. location is an object of type Location that can be assigned directly using a string or can be changed using its href property or its methods assign() and replace().
If the requests to your URLs does not return any content, the both return status code 404 and no Location: header then check for the presence of the Refresh: header in the response.
You better use curl to make the requests instead of file_get_contents(). curl provides a better control of the headers sent and received.
I would suggest You to make a cURL request to desired site and see what kind of response it is.
As described in PHP manual,
curl_getinfo ($handle, CURLINFO_HTTP_CODE);
will give You an associative array, in it You will find the http_code key, which will hold Your status code.
If redirect case will give You non-30X status code, You can try to fetch redirect url by this:
curl_getinfo ($handle, CURLINFO_REDIRECT_URL);

Cross-domain AJAX request error on HTTP 200

I'm writing a very basic Facebook app, but I'm encountering an issue with cross-domain AJAX requests (using jQuery).
I've written a proxy page to make requests to the graph via cURL that I'm calling via AJAX. I can visit the page in the browser and see it has the correct output, but requesting the page via always causes jQuery to fire the error handler callback.
So I have two files:
Proxy, which does the cURL request
<?php
//Do some cURL requests, manipulate some data
//return it as JSON
print json_encode($data);
?>
The facebook canvas, which contains this AJAX call
$.getJSON("http://myDomain.com/proxy.php?get=stuff",
function(JSON)
{
alert("success");
})
.error(function(err)
{
alert("err");
});
Inspecting the call with Firebug shows it returns with HTTP code 200 OK, but the error handler is always fired, and no content is returned. This happens whether I set Content-Type: application/json or not.
I have written JSON-returning APIs in PHP before using AJAX and never had this trouble.
What could be causing the request to always trigger the error handler?
Recently I experienced the same issue and my problem was the fact that there was a domain difference between the webpage and the API, due to the SSL.
The web page got a HTTP address (http://myDomain.com) and the content I was requesting with JQuery was on the same domain but HTTPS protocol (https://myDomain.com). The browser (Chrome in this case) considered that the domains were differents (the first one with HTTP, the second one with HTTPS), just because of the protocol, and because the request response type was "application/json", the browser did not allowed it.
Basically, the request worked fine, but your browser did not allowed the response content.
I had to add a "Access-Control-Allow-Origin" header to make it work. If you're in the same case, have a look there: https://developer.mozilla.org/en/http_access_control.
I hope that'll help you, I got a headache myself.

Making PHP cURL skip binary data like images, video, etc

Setting up curl like this:
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$this->domain);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);
curl_setopt($ch,CURLOPT_FAILONERROR,TRUE);
curl_setopt($ch,CURLOPT_USERAGENT,"Useragent");
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,TRUE);
curl_setopt($ch,CURLOPT_MAXREDIRS,1);
$str = curl_exec($ch);
return $str;
$str = $this->cURL();
Pass the url to an html page and all is well - but pass a link direct to a .jpg for example and it returns a load of garbled data.
I'd like to ensure that if a page, say, redirects to a .jpg or .gif, etc - it's ignored and only html pages are returned.
I can't seem to find a setopt for curl that does this.
Any ideas?
-The Swan.
Curl doesn't care if the content's text (html) or binary garbage (a jpg), it'll just return what you tell it to fetch. You've told curl to follow redirects with the "CURLOPT_FOLLOWLOCATION" option, so it'll just follow the chain of redirects until it hits the regular limit, or gets something to download
If you don't know what the URL might contain ahead of time, you'd have to do some workarounds, such as issuing a custom HEAD request, which would return the URL's normal http headers, from which you can extract the mime type (Content-type: ...) of the response and decide if you want to fetch it.
Or just fetch the URL and then keep/toss the data based on the mime type in the full response's headers.
My idea - use HEAD request, check if content-type is interesting( eg. another HTML ) and after this make GET request for data.
set CURLOPT_NOBODY for HEAD request

Categories