I have this cURL code in php.
curl_setopt($ch, CURLOPT_URL, trim("http://stackoverflow.com/questions/tagged/java"));
curl_setopt($ch, CURLOPT_PORT, 80); //ignore explicit setting of port 80
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, $v);
curl_setopt($ch, CURLOPT_VERBOSE, true);
The contents of HTTPHEADER are ;
Proxy-Connection: Close
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=blabla
Connection: Close
Each of them individual items in the array $v.
When I upload the file on my host and run the code, what I get is :
400 Bad request
Your browser sent an invalid request.
But when I run it on my system using command line PHP, what I get is
< HTTP/1.1 200 OK
< Vary: Accept-Encoding
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Encoding: gzip
< Date: Sat, 03 Mar 2012 21:50:17 GMT
< Connection: close
< Set-Cookie: buncha cokkies; path=/; HttpOnly
< Content-Length: 22151
<
* Closing connection #0
.
It's not only on stackoverflow, this happens, it happens also on 4shared, but works on google and others.
Thanks for any help.
This is more a comment than an answer: From your question it's not clear what specifically triggers the 400 error nor what especially means it or more concrete: the source of it.
Is that the output by your server? Is that some feedback (the curl response) that you output with your script?
To better debug things, I've come up with a slightly different form of configuration you might be interested in when using the curl extension. There is a nice function called curl_setopt_array which allows you to set multiple options at once. It will return false if one of the options fails. It allows you to configure your request in complete in front. So you can more easily inject and replace it with a second (debug) configuration:
$curlDefault = array(
CURLOPT_PORT => 80, // ignore explicit setting of port 80
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_ENCODING => '',
CURLOPT_HTTPHEADER => array(
'Proxy-Connection: Close',
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding: gzip,deflate,sdch',
'Accept-Language: en-US,en;q=0.8',
'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Cookie: __qca=blabla',
'Connection: Close',
),
CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
);
$url = "http://stackoverflow.com/questions/tagged/java";
$handle = curl_init($url);
curl_setopt_array($handle, $curlDefault);
$html = curl_exec($handle);
curl_close($handle);
This might help you to improve the code and to debug things.
Furthermore you're making use of the CURLOPT_VERBOSE option. This will put the verbose information into STDERR - so you can't track it any longer. Instead you can add it to the output as well to better see what's going on:
...
CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
CURLOPT_STDERR => $verbose = fopen('php://temp', 'rw+'),
);
$url = "http://stackoverflow.com/questions/tagged/java";
$handle = curl_init($url);
curl_setopt_array($handle, $curlDefault);
$html = curl_exec($handle);
$urlEndpoint = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
echo "Verbose information:\n<pre>", !rewind($verbose), htmlspecialchars(stream_get_contents($verbose)), "</pre>\n";
curl_close($handle);
Which gives sort of the following output:
Verbose information:
* About to connect() to stackoverflow.com port 80 (#0)
* Trying 64.34.119.12...
* connected
* Connected to stackoverflow.com (64.34.119.12) port 80 (#0)
> GET /questions/tagged/java HTTP/1.1
Host: stackoverflow.com
Proxy-Connection: Close
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=blabla
Connection: Close
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Encoding: gzip
< Vary: Accept-Encoding
< Date: Mon, 05 Mar 2012 17:33:11 GMT
< Connection: close
< Content-Length: 10537
<
* Closing connection #0
Which should provide you the information needed to track things down if they are request/curl related. You can then easily change parameters and see if it makes a difference. Also compare the curl version you have installed locally with the one on the server. To obtain it, use curl_version:
$curlVersion = curl_version();
echo $curlVersion['version']; // e.g. 7.24.0
Hope this helps you to track things down.
according to http://php.net/manual/en/function.curl-setopt.php
try setting CURLOPT_ENCODING to "gzip"
also, i'd try to avoid as many header lines as possible, for example use CURLOPT_COOKIE instead of Cookie: __qca__=blabla or CURLOPT_USERAGENT
EDIT: it seems that you're not using an array (key => value) for CURLOPT_HTTPHEADER, are you? in this case, use the array and with the other stuff, i wrote, you'll be fine. (how this is done, read the manual :P)
hope that helps.
this worked for me
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
Related
I've run manually the url from postman, and I've successfully connected and it printed it results.
But when I tried calling it from a method, no result is printing.
here's the curl code I used:
public function curlHandle($apiPath, $postArray)
{
$CI = & get_instance();
$conf = $CI->config->config;
$curlHandle = curl_init($apiPath);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_USERAGENT,"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36");
curl_setopt($curlHandle, CURLOPT_TIMEOUT , 300);
curl_setopt($curlHandle, CURLOPT_POST, 1);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $postArray);
curl_setopt($curlHandle, CURLOPT_VERBOSE, 1);
$fp = fopen('/var/www/html/logs/curl_log.txt', 'w');
curl_setopt($curlHandle, CURLOPT_STDERR, $fp);
$result = curl_exec($curlHandle);
print_r(curl_error($curlHandle));
if ($result === FALSE) {
die(curl_error($curlHandle));
} else {
$data = json_decode($result, TRUE);
}
curl_close($curlHandle);
return $data;
}
Here's the content of curl_log.txt
Hostname localhost/codeignitertest was found in DNS cache
Trying 127.0.0.1...
TCP_NODELAY set
Connected to alocalhost/codeignitertest (127.0.0.1) port 80 (#0)
POST /test/process HTTP/1.1 Host: localhost/codeignitertest User-Agent: Mozilla/5.0 (X11; Linux
x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57
Safari/537.36 Accept: / Content-Length: 142 Content-Type:
multipart/form-data; boundary=------------------------78a116d61ad4939d
< HTTP/1.1 200 OK < Date: Tue, 30 Apr 2019 21:19:43 GMT < Server:
Apache/2.4.29 (Ubuntu) < Cache-Control: no-store, no-cache,
must-revalidate < Pragma: no-cache < Set-Cookie:
ci_session=ag85kv438n0ukb1rvrkb5cdfkrd8s2q6; expires=Tue, 30-Apr-2019
21:49:43 GMT; Max-Age=1800; path=/; HttpOnly < Expires: Thu, 19 Nov
1981 08:52:00 GMT < Content-Length: 14 < Content-Type: text/html;
charset=UTF-8 <
* Connection #0 to host localhost/codeignitertest left intact
also note that curlHandle() is from another project and localhost/codeignitertest but both are running in my localhost
You've issued this option:
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
Which means that curl returns the output from the remote server instead of printing it.
You then capture that output into a variable:
$result = curl_exec($curlHandle);
Which you then encode and return to your caller:
return $data;
This code shouldn't print the results. It returns the results.
I'm trying to embed Facebook's posts (e.g. video) using oEmbed format. According to Facebook documentation, oEmbed is now supported. I'm trying this PHP code:
$json_post = #file_get_contents('https://www.facebook.com/plugins/video/oembed.json/?url={MY VIDEO URL HERE}');
$oembed = json_decode($json_post);
var_dump($oembed);
I already used the same code for Instagram with success, now I'm getting a NULL result. oEmbed works good if i directly write the URL on the browser. Am i missing something?
Thanks.
Update
I tried with Curl:
$url='https://www.facebook.com/plugins/video/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Ffacebook%2Fvideos%2F10153231379946729%2F';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
//curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$page = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print_r($page);
curl_close($ch);
Now i get:
HTTP/1.1 302 Found
Location: https://www.facebook.com/unsupportedbrowser
access-control-allow-method: OPTIONS
Access-Control-Expose-Headers: X-FB-Debug, X-Loader-Length
Access-Control-Allow-Origin: https://www.facebook.com
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: text/html
X-FB-Debug: gGcZzyllZadlcn/6jz2HqqouIcDnhTzxzR+etWXhZEnOcditfsaIUw0WjgO3nELHzveRCYa1UM86D3LA/nLnNw==
Date: Wed, 11 Jan 2017 10:18:47 GMT
Connection: keep-alive
Content-Length: 0
HTTP/1.1 200 OK
X-XSS-Protection: 0
public-key-pins-report-only: max-age=500; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ="; report-uri="http://reports.fb.com/hpkp/"
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: Sat, 01 Jan 2000 00:00:00 GMT
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=15552000; preload
X-Frame-Options: DENY
Vary: Accept-Encoding
Content-Type: text/html
X-FB-Debug: zwArox8KyM3BtwLymhiARCTltrrcE/pDqSWdqbHgstXVBEbIXG57Od2MfDnqgqSX5Tj43qoe8uYhphzwoZcXeg==
Date: Wed, 11 Jan 2017 10:18:48 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Still waiting for a reply.
Thank You.
Set the user agent with the curl and try,
$browser = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.16 (KHTML, like Gecko) \Chrome/24.0.1304.0 Safari/537.16';
curl_setopt($ch, CURLOPT_USERAGENT, $browser);
Here is the answer with file_get_content,
$options = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n" . // check function.stream-context-create on php.net
"User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10\r\n" // i.e. An iPad
)
);
$context = stream_context_create($options);
$json_post = #file_get_contents('https://www.facebook.com/plugins/video/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Ffacebook%2Fvideos%2F10153231379946729%2F', false, $context);
$oembed = json_decode($json_post);
var_dump($oembed)
How do I go about sending this information:
// build an associative array
$data["username"]="a";
$data["password"]="b";
$data["msisdn"]="447123121234";
$data["webhook"]="http://1f89e4a8.ngrok.io/testDir/getPost.php";
// turn it into json formatted string
$json_data=json_encode($data);
To the API:
$url = "http://ms.4url.eu/lookup";
Using cURL, I have currently been using :
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json_data);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
Of which I get the results (NGrok):
GET /testDir/curlPost.php HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, /
Accept-Language: en-GB
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79
Safari/537.36 Edge/14.14393
Accept-Encoding: gzip, deflate
Host: f0946724.ngrok.io
X-Forwarded-For: 92.11.143.199
200 OK HTTP/1.1 200 OK
Date: Thu, 08 Dec 2016 00:48:20 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/7.0.9
X-Powered-By: PHP/7.0.9
Content-Length: 161
Content-Type: text/html; charset=UTF-8
Error: call to URL http://ms.4url.eu/lookup failed with status 0,
response , curl_error Failed to connect to ms.4url.eu port 80:
Connection refused, curl_errno 7
As well as the error stated from cUrl:
Error: call to URL http://ms.4url.eu/lookup failed with status 0,
response , curl_error Failed to connect to ms.4url.eu port 80:
Connection refused, curl_errno 7
Any help much appreciated, thanks.
I figured out that the Error I was getting is due to the server expecting a Https(443) connection and not Http(80), this was easily solved by changing the URL to https://ms.4url.eu as opposed to http://ms.4url.eu when sending the request with cURL.
I'm trying to upload a file via cURL but something is missing. I forces this request to be HTTP 1.0 because cURL adds the Expect: 100 header if I use HTTP 1.1 so thats why the extra header. Here is a simple test code:
<?php
if(isset($_POST["id"])) {
$data = array("id" => $_POST["id"]);
$data["file"] = "#".realpath($_FILES["file"]["tmp_name"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453',
'Connection: keep-alive'
));
curl_setopt($ch, CURLOPT_URL, "http://localhost:8080/test-api/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
$response = curl_exec($ch);
var_dump($response);
exit;
}
?>
My Jersey based server picks it up, and I can see these headers:
INFO: 25 * Server has received a request on thread http-nio-8080-exec-1
25 > POST http://localhost:8080/test-api/upload
25 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
25 > connection: keep-alive
25 > content-length: 261
25 > content-type: multipart/form-data; boundary=------------------------53f7ba34739b4d9e
25 > host: localhost:8080
See the content-length? It's way too short. When I send the same file and the same request via my Postman REST client, I get these headers:
INFO: 26 * Server has received a request on thread http-nio-8080-exec-3
26 > POST http://localhost:8080/test-api/upload
26 > accept-encoding: gzip, deflate
26 > accept-language: hu-HU,hu;q=0.8,en-US;q=0.6,en;q=0.4
26 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
26 > cache-control: no-cache, no-cache
26 > connection: keep-alive
26 > content-length: 144954
26 > content-type: multipart/form-data; boundary=----WebKitFormBoundarye5Tg0kEqi10nEBwv
26 > cookie: ff_uvid=126143952; _ga=GA1.1.459454356.1439469592; CAKEPHP=9mffidqo8203ugktan4roc0u82
26 > host: localhost:8080
26 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
26 > user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36
The content-length now is set property. What could be wrong here?
It sounds like you're using PHP 5.6.0 or later. As of this release, the # prefix for file uploads is disabled by default. You can enable it with
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
This option was added in 5.5, but the default was false for backward compatibility; 5.6 changed the default incompatibly.
The preferred way to perform file uploads starting with 5.5 is with the CurlFile class.
$data["file"] = new CurlFile(realpath($_FILES["file"]["tmp_name"]));
You have to actually insert the filecontent, this differs from the cli-version of curl.
try:
$data["file"] = file_get_contents($_FILES["file"]["tmp_name"]);
I want to scrap some data, but I need to log in. So, my idea is to copy the cookies when I log in to my program. But I don't know why, but if I'm using my program, I kept redirect to login pages. I already compared it, but the cookies are same.
Here's the header if I login using my google chrome, (Copied it from request header):
GET /example/data/data.jsp?date=01-Jan-2001&_=1439020103330 HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ms;q=0.6
Cookie: SESSIONID=BA4BA42C628D5C6EB959D49DB745D94A.NGXA; __utma=77920972.1013585791.1438786361.1438966138.1439020034.5; __utmc=77920972; __utmz=77920972.1438786423.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
My curl code:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$f = fopen('request.txt', 'w');
curl_setopt($ch, CURLOPT_STDERR , $f);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding: gzip, deflate, sdch',
'Accept-Language: en-US,en;q=0.8,ms;q=0.6',
'Cookie: SESSIONID=BA4BA42C628D5C6EB959D49DB745D94A.NGXA; __utma=77920972.1013585791.1438786361.1438966138.1439020034.5; __utmc=77920972; __utmz=77920972.1438786423.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)',
'Upgrade-Insecure-Requests: 1',
'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36',
'X-DevTools-Emulate-Network-Conditions-Client-Id: 3A45EE97-D41F-45A3-AFCD-1540014377A7
'));
Here's my request.txt used to debug my program header:
* About to connect() to www.example.com port 80 (#0)
* Trying 202.43.163.203... * connected
* Connected to www.example.com (202.43.163.203) port 80 (#0)
> GET /example/data/data.jsp?date=01-Jan-2001&_=1439020103330 HTTP/1.1
Host: www.example.com
Accept: */*
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ms;q=0.6
Cookie: SESSIONID=BA4BA42C628D5C6EB959D49DB745D94A.NGXA; __utma=77920972.1013585791.1438786361.1438966138.1439020034.5; __utmc=77920972; __utmz=77920972.1438786423.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id: 3A45EE97-D41F-45A3-AFCD-1540014377A7
< HTTP/1.1 302 Found
< Date: Sat, 08 Aug 2015 09:44:06 GMT
< Server: Apache
< Set-Cookie: SESSIONID=7C8779894A3CE29D4BCED4B4D311E07E.NGXA; Path=/example/; HttpOnly
< Location: http://www.example.com/login.jsp
< Content-Length: 0
< Content-Type: text/plain
<
* Connection #0 to host www.example.com left intact
* Closing connection #0
This my first time scrapping data with login user, but did I miss something?
Cookies can be set via the CURLOPT_COOKIE. In your case
curl_setopt($ch, CURLOPT_COOKIE, 'SESSIONID=BA4BA42C628D5C6EB959D49DB745D94A.NGXA');
With semicolon space you can add more cookies to the request. See http://php.net/manual/en/function.curl-setopt.php for more information.
If you want to store and re-use the cookies you can also use CURLOPT_COOKIEFILE and CURLOPT_COOKIEJAR.