I am using PHP 5.3.6 and it seems I am unable to make a PUT request using CURL for PUTting just a string.
function put_data($url, $data)
{
$useragent="SimpleAgent-1.0";
$fh = fopen('php://memory', 'rw');
fwrite($fh, $data);
rewind($fh);$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data));
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
fclose($fh);
return $result;
}
Here, $data is the string that I want to PUT.
Doesn't work and returns the following error:
500 Internal Server Error The server has either erred or is incapable
of performing the requested operation.
expected string or buffer
I used your code so defined a url and filled the data with a string and all worked as expected. Being I was rejected by the website as there was no receiving end that could deal with a put. To get info easily just add the line
curl_setopt($ch, CURLOPT_VERBOSE, true);
and you will get something like:
* About to connect() to yyyy.xxxx.com port 80 (#0)
* Trying 62.221.196.28...
* connected
* Connected to yyyy.xxxx.com (zz.221.196.28) port 80 (#0)
> PUT / HTTP/1.1
User-Agent: SimpleAgent-1.0
Host: yyyy.xxxx.com
Accept: */*
Content-Length: 14
Expect: 100-continue
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 405 Method Not Allowed
< Date: Thu, 09 Feb 2012 19:46:28 GMT
< Server: Apache
< Allow: GET,HEAD,POST,OPTIONS
< Vary: Accept-Encoding
< Content-Length: 231
< Content-Type: text/html; charset=iso-8859-1
<
* Connection #0 to host yyy.xxxx.com left intact
* Closing connection #0
As you can see from the logging the request went out, however when you want to put the data, the apache setting doesn't allow you to put data to that url. So depending upon the server you will have to take care of a receiving url that accepts the PUT.
I am only able to pass the array as a data with the versions I am using. So this is what I am doing now:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_COOKIE, $curl_cookie);
$arr = array();
if (isset($data)) {
$arr['my_data'] = $data;
}
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arr));
curl_exec($ch);
Related
I'm trying to make a script that makes things easier for Apple users, I don't really want to expose it right now but those are the steps I need to follow.
Login to Apple and saving the cookies.
Getting the data from apple with the saved cookies.
Creating automation tools.
And i'm stuck in the first step, Curl isn't submitting the custom headers as I need to submit the json header.
Here is my code:
<?php
function login($url,$data){
$data=json_encode($data);
$login = curl_init();
curl_setopt($login, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($login, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($login, CURLOPT_NOBODY, false);
curl_setopt($login, CURLOPT_HEADER, false);
curl_setopt($login, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($login, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($login, CURLOPT_TIMEOUT, 40000);
curl_setopt($login, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($login, CURLOPT_URL, $url);
curl_setopt($login, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($login, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($login, CURLOPT_POST, TRUE);
curl_setopt($login, CURLOPT_POST, 1);
curl_setopt($login, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data))
);
curl_setopt($login, CURLOPT_POSTFIELDS, $data);
//ob_start();
$rez=curl_exec ($login);
}
$data = array("accountName" => "myemail#me.com", "password" => "MyPassWord","rememberMe" => "true");
$url="https://idmsa.apple.com/appleauth/auth/signin";
login($url,$data);
?>
Whenever I try tampering the data when sending request, it never shows the custom headers
Apple uses X-Apple-Widget-Key like CSRF. I think you need to catch it. You can find it on source code. You can get status by using curl_getinfo()
// your code .....
curl_setopt($login, CURLOPT_POSTFIELDS, $data);
//ob_start();
$rez = curl_exec($login);
$status = curl_getinfo($login);
print_r($status);
This would be unmanageable as a comment, so here is how i see what goes on the wire:
$verbiage = null;
if ($this->verbose) {
curl_setopt($ch , CURLINFO_HEADER_OUT , false);
curl_setopt($ch , CURLOPT_VERBOSE , true);
$verbiage = fopen('php://temp' , 'w+');
curl_setopt($ch , CURLOPT_STDERR , $verbiage);
}
$resp = curl_exec($ch);
if ($this->verbose) {
rewind($verbiage);
$verboseLog = stream_get_contents($verbiage);
$log->info("Verbose information:\n$verboseLog");
fclose($verbiage);
}
curl_close($ch);
where $log is a log4php object, you pick your display method.
EDIT adding a sample log with this 'trace' option enabled
INFO - testCreateLabRequest starts.
TRACE - Query for lab request [dispensary[1]inboundLabRequest[2]ForPatient[1]] returned no records for feed [toubibCreamedFeedGuid]
DEBUG - Sending json
{ *redacted* , "trackingId":"5ac4473b-407f-4d7d-83eb-1a3f9abe5b8b"}
INFO - Verbose information:
* Trying fe80::3636:3bff:fecf:804c...
* Connected to darkmax.local (fe80::3636:3bff:fecf:804c) port 80 (#0)
> POST /ehr/feed/lab/request HTTP/1.1
Host: darkmax.local
Protocol_version : 1.1
Connection: Close
Content-Type: application/json ; charset=utf-8
Proxy-Connection: Close
User-Agent: Portable EHR(106)
Accept: application/json, text/html;
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
Content-Length: 851
* upload completely sent off: 851 out of 851 bytes
< HTTP/1.1 200 OK
< Date: Wed, 31 Aug 2016 02:04:03 GMT
< Server: Apachee/2.4.12
< Access-Control-Allow-Origin: *
< Origin: http://darkmax.local
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=utf-8
<
* Closing connection 0
The lines with a < correspond to what my cURL session is receiving from the remote peer. Having some visibility into the actual HTTP protocol flying from me-to-peer-back-to-me has helped me many times figure out the nature of some underlying issue.
I am opening a HTTPS page using cURL. The page I request issues a redirect request. I have set cURL to follow the redirect, but I cannot seem to be able to get it to request the correct page. I have tracked the same request in a browser and I see my browser making a different request to what cURL makes. What can I do to correct this? The correct URL is shown in the output of a verbose cURL dump. It follows the "* Issue another request to this URL"
Here is a snippet of the output from cURL's verbose output:
< HTTP/1.1 302 Moved Temporarily
< Location: /XXX
< Content-Type: text/html; charset=UTF-8
< Date: Tue, 31 Dec 2013 15:51:46 GMT
< Expires: Tue, 31 Dec 2013 15:51:46 GMT
< Cache-Control: private, max-age=0
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Alternate-Protocol: 443:quic
< Transfer-Encoding: chunked
<
* Ignoring the response-body
* Connection #0 to host 127.0.0.1 left intact
* Issue another request to this URL: 'XYYYZ'
* Re-using existing connection! (#0) with host 127.0.0.1
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> GET /??? HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0
The PHP code I use follows:
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_COOKIEJAR, COOKIE_FILE);
curl_setopt($ch, CURLOPT_COOKIEFILE, COOKIE_FILE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
$target = ADDR;
curl_setopt($ch, CURLOPT_URL, $target);
$page = curl_exec($ch);
cURL follows the Location: Header, but be sure to send the exact headers (content-language, referer) browser does using CURLOPT_HTTPHEADER option because some servers refuse connectios to prevent automated requests. In Firefox you have live http headers to see what browser does.
Also make sure the Location: header contains the absolute url and not a relative path according to http 1.1.
If that dosen't work you can use the option CURLOPT_HEADER with curl_info to catch the 302 and redirect it manually.
Here i post an example to do it manually so you check if would produce an infinite loop.
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_COOKIEJAR, COOKIE_FILE);
curl_setopt($ch, CURLOPT_COOKIEFILE, COOKIE_FILE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
$target = ADDR;
curl_setopt($ch, CURLOPT_URL, $target);
$page = curl_exec($ch);
$curl_info = curl_getinfo($ch);
if ($curl_info['http_code'] == 302 || $curl_info['http_code'] == 301)
{
$response_headers = substr($page, 0, $curl_info['header_size']);
if (preg_match('#Location: (.*)#', $response_headers, $location_header))
{
// Call again curl to follow location; Better to wrap the curl process in a function called follow_location
// echo $location_header return an Array
// echo $location_header[0] return "Location: http//blablabla"
// echo $location_header[1] return URL only "http://blablbalba.com" and you can process with cURL :D
echo $location_header[1];
}
}
I am using the following code for adding emails to a list in sendgrid. But it is returning inserted :0 response
$request_url = "https://sendgrid.com/api/newsletter/lists/email/add.json";
$data = array("email"=>"testemail#test.com");
$params = array(
'api_user' => $sengrid_user,
'api_key' => $sendgrid_pass,
'list'=>"TestAlwin",
'data' =>json_encode($data)
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $request_url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$resp = curl_exec($ch);
curl_close($ch);
This is returning inserted :0 response. It should insert the mailid to the list I have specified.
I am using the following as reference :
curl -d 'api_user=your_sendgrid_username&api_key=your_sendgrid_password&list=my_list&data[]={"email":"address1#domain.com","name":"contactName1"}&data[]={"email":"address2#domain.com","name":"contactName2"}' https://sendgrid.com/api/newsletter/lists/email/add.json
This is actually given in their api here :
http://sendgrid.com/docs/API_Reference/Marketing_Emails_API/emails.html
and I am adding the curl vebrose here :
* About to connect() to sendgrid.com port 80 (#0)
* Trying 1.1.1.1... * connected
* Connected to sendgrid.com (1.1.1.1) port 80 (#0)
> POST /api/newsletter/lists/email/add.json?list=TestAlwin HTTP/1.1
Host: sendgrid.com
Accept: */*
Content-Length: 395
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------4435bfc2eb00
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Server: nginx
< Date: Fri, 13 Sep 2013 07:04:42 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Vary: Accept-Encoding
<
* Connection #0 to host sendgrid.com left intact
* Closing connection #0
These 1.1.1.1 is just a test IP that I have added here instead of the actual one.
The SendGrid Newsletter API is broken- specifically you can't add more than a single email to a list at a time, making it unusable. I reported it a week ago- they confirmed the bug, gave no timeline for a fix. They don't seem too concerned...
The SendGrid Newsletter API requires both 'email' and 'name' parameters at a minimum (as seen in the docs: http://sendgrid.com/docs/API_Reference/Marketing_Emails_API/emails.html)
I updated your test code to include "name" => '' to the code and it works beautifully (also fixed typo in the api_user's $sendgrid_user variable).
Cheers!
--Jayson
$request_url = "https://sendgrid.com/api/newsletter/lists/email/add.json";
$data = array("email" => "hello#world.com", "name" => '');
$params = array(
'api_user' => $sendgrid_user,
'api_key' => $sendgrid_pass,
'list'=>"TestAlwin",
'data' =>json_encode($data)
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $request_url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$resp = curl_exec($ch);
curl_close($ch);
i want to change xml value in php but don't change ....
<?php
$url = "http://192.168.1.103:8080/ew.xml";
$xml = '<?xml version="1.0" ?>
<DDCConfig:getValue xmlns:DDCConfig="urn:SMUDDCConfiguration">
<DDCConfig:Network>
<DDCConfig:LocalIP>192.168.103.223</DDCConfig:LocalIP>
<DDCConfig:GlobalIP>168.188.127.123</DDCConfig:GlobalIP>
<DDCConfig:RootBridge>Yes</DDCConfig:RootBridge>
</DDCConfig:Network>
</DDCConfig:getValue>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_USERPWD, "lmk:alrud89");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, "$url");
curl_setopt($ch, CURLOPT_PORT, 8080);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,array($xml));
$http_result = curl_exec($ch);
if($http_result){
echo $http_result;
}else{
echo curl_error($ch);
}
curl_close($ch);
?>
error message is
* About to connect() to 192.168.1.103 port 8080 (#0)
* Trying 192.168.1.103...
* connected
* Server auth using Basic with user 'lmk'
> PUT /ew.xml HTTP/1.1
> Authorization: Basic bG1rOmFscnVkODk=
> Host: 192.168.1.103:8080 Accept: /
> Transfer-Encoding: chunked
> Expect: 100-continue
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
<
> WWW-Authenticate: Digest qop="auth", realm="mydomain.com",
nonce="1366254379"
* HTTP error before end of send, stop sending
* Closing connection #0
what is the problem & solution?
Your credentials are incorrect! (that's what error 401 means)
There's a wonderful plugin for Firefox called poster - install it and use it to double-check that the request is formatted correctly.
By the way, you might want to add the following header:
curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: application/xml"))
Another thing: PUT is not always supported, try POST - sometimes it'll work.
I'm trying to create a script that posts to an URL, using a list of proxies. The script seems to work fine without setting a proxy (CURLOPT_PROXY to null), but with a proxy set it does not seem to work. Does anybody know what I'm doing wrong here? The error I'm getting when posting with a proxy is:
ERROR
The requested URL could not be retrieved
Invalid Request error was encountered while trying to process the request:
POST /###/ HTTP/1.1
Host: ###
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 368
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------9b24e849cac0
Some possible problems are:
Missing or unknown request method.
Missing URL.
Missing HTTP Identifier (HTTP/1.0).
Request is too large.
Content-Length missing for POST or PUT requests.
Illegal character in hostname; underscores are not allowed.
And my code is:
$url = 'urltopost';
$proxy = 'proxy:port';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, true);
$data = array(
'postname1' => 'value1',
'postname2' => 'value2'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$curl_scraped_page = curl_exec($ch);
curl_close($ch);
echo $curl_scraped_page;
You are missing the PROXYPORT option... You can't use the proxy:port notation
curl_setopt($ch, CURLOPT_PROXY, "YOUR PROXY HOST");
curl_setopt($ch, CURLOPT_PROXYPORT, "YOUR PROXY PORT");