PHP 5.3, Ampersand in URL passing not working - php

I have code that works fine for anything before 5.3, and now this code won't work in php 5.3:
foreach($_GET as $key => $value) {
$params .= "&";
$params .= $key."=".$value;
}
$fields = array(
'mode'=>urlencode('native'),
'cookie_file'=>urlencode($data['cookie_file']),
'full_status'=>urlencode('1'),
'remove_cookies'=>urlencode('1'),
'url'=>urlencode("http://www.domainblocked.com/blocked_name.php?" . $params)
);
//url-ify the data for the POST
$fields_string = "";
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = rtrim($fields_string,'&');
//open connection
$ch = curl_init();
$get_url = $proxy."?".$fields_string;
print $get_url;
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$get_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute post
$html = curl_exec($ch);
The file $proxy refers to a PHP proxy which complains it never gets the $_GET['url'] variable despite the $get_url being:
http://www.domainblocked.com/proxy.php?mode=native&cookie_file=%2Ftmp%2FCURLCOOKIEQ1N7ki&full_status=1&remove_cookies=1&url=http%3A%2F%2Fwww.domainblocked.com%2Fblocked_name.php%3F%26room%3D3043542%3B3332215%3B4875165%3B6917670%3B7055833%3B7454057%3B7747396%3B8321764%3B8331103%3B8362498%3B8406246%3B8406305%3B8406671%3B8406728%3B8406965%3B9213754%3B9895515%3B9898865%3B9904319%3B9904558%3B9908327%3B9910403%3B9910760%3B9916830%3B9918045%3B9919351%3B9919603%26avatar69323038%3D%26avatar1%3D6268520%3B6713654%3B7347874%3B7738193%3B7780315%3B8493140%3B8501371%3B8752968%3B9487253%3B9524370%3B9811618%3B10196605%3B10519485%26avatar69527829%3D%26avatar2%3D223055%3B2690693%3B4228334%3B6251471%3B6270797%3B6713654%3B7122151%3B7198849%3B7644202%3B7868916%3B8501371%3B8698810%3B8739013%3B8739767%3B9142768%26avatar38051172%3D%26avatar3%3D4792397%3B6285528%3B7204362%3B7518963%3B7773830%3B7776340%3B8403813%3B8501371%3B9481162%3B9520771%3B9751483%3B9971760%3B9997875%3B10109398%3B10117824%26avatar227598%3D%26avatar4%3D1962690%3B4223019%3B5707484%3B6127072%3B7162053%3B7172244%3B7988191%3B8239420
therefore $_GET['url'] on the proxy file should be http%3A%2F%2Fwww.domainblocked.com%2Fblocked_name.php%3F%26room%3D3043542%3B3332215%3B4875165%3B6917670%3B7055833%3B7454057%3B7747396%3B8321764%3B8331103%3B8362498%3B8406246%3B8406305%3B8406671%3B8406728%3B8406965%3B9213754%3B9895515%3B9898865%3B9904319%3B9904558%3B9908327%3B9910403%3B9910760%3B9916830%3B9918045%3B9919351%3B9919603%26avatar69323038%3D%26avatar1%3D6268520%3B6713654%3B7347874%3B7738193%3B7780315%3B8493140%3B8501371%3B8752968%3B9487253%3B9524370%3B9811618%3B10196605%3B10519485%26avatar69527829%3D%26avatar2%3D223055%3B2690693%3B4228334%3B6251471%3B6270797%3B6713654%3B7122151%3B7198849%3B7644202%3B7868916%3B8501371%3B8698810%3B8739013%3B8739767%3B9142768%26avatar38051172%3D%26avatar3%3D4792397%3B6285528%3B7204362%3B7518963%3B7773830%3B7776340%3B8403813%3B8501371%3B9481162%3B9520771%3B9751483%3B9971760%3B9997875%3B10109398%3B10117824%26avatar227598%3D%26avatar4%3D1962690%3B4223019%3B5707484%3B6127072%3B7162053%3B7172244%3B7988191%3B8239420
But it never gets it.
If I dont urlencode the $_GET['url'] then it this:
http://www.domainblocked.com/proxy.php?mode=native&cookie_file=%2Ftmp%2FCURLCOOKIEjtmYSU&full_status=1&remove_cookies=1&url=http://www.domainblocked.com/blocked_name.php?&room=3043542;3332215;4875165;6917670;7055833;7454057;7747396;8321764;8331103;8362498;8406246;8406305;8406671;8406728;8406965;9213754;9895515;9898865;9904319;9904558;9908327;9910403;9910760;9916830;9918045;9919351;9919603&avatar69323038=&avatar1=6268520;6713654;7347874;7738193;7780315;8493140;8501371;8752968;9487253;9524370;9811618;10196605;10519485&avatar69527829=&avatar2=223055;2690693;4228334;6251471;6270797;6713654;7122151;7198849;7644202;7868916;8501371;8698810;8739013;8739767;9142768&avatar38051172=&avatar3=4792397;6285528;7204362;7518963;7773830;7776340;8403813;8501371;9481162;9520771;9751483;9971760;9997875;10109398;10117824&avatar227598=&avatar4=1962690;4223019;5707484;6127072;7162053;7172244;7988191;8239420
Which the proxy receieve $_GET['url'] but it's only http://www.domainblocked.com/blocked_name.php?
So I think it has to do with something with the & or urlencode in 5.3

foreach($_GET as $key => $value) {
$params .= "&";
$params .= $key."=".$value;
}
Switch this (and similar code) with http_build_query(). It will handle all the encoding.

Related

PHP - CURL strange behaviour while setting headers

I have written a function in PHP to send a CURl request.
The code is given below.
function curl_post($url,$fields,$headers=[],$connect_timeout = 3,$timeout = 20) {
$ch = curl_init();
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$postvars = trim($postvars,'&');
$postvars = json_encode($fields);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,$connect_timeout);
curl_setopt($ch,$timeout, 20);
$refined_headers = [];
if(sizeof($headers)) {
foreach($headers as $name => $value) {
$refined_headers[] = "'".$name.": ".$value."'";
}
print_r($refined_headers);
//$refined_headers = ['Content-Type: application/json'];
//echo $refined_headers;exit;
curl_setopt($ch,CURLOPT_HTTPHEADER,$refined_headers);
}
$response = curl_exec($ch);
$info = curl_getinfo($ch,CURLINFO_CONTENT_TYPE);
print_r($info);
curl_close ($ch);
return $response;
}
So I called the function like this
$url = API_ENDPOINT.$method.'/';
$response = curl_post($url,$params_to_send,$headers);
echo $response;
where $url contains my API url and $params contain the parameters as associative array and $headers as follows
$headers = ['Content-Type'=>'application/json'];
My problem is that, the content type header is setting. But when I manually set it inside the curl_post function like
$refined_headers = ['Content-Type: application/json']
it is working perfectly.
What is the problem with my code.
Fixed the issue. The problem was
I put two single quotes before and after the header, which was not needed
$refined_headers[] = "'".$name.": ".$value."'";
I changed that to the following and the issueis resolved.
$refined_headers[] = $name.": ".$value;

webservice.php Vtiger update Query String php curl post

Does any one know how to properly format the update query in vtiger to update a record under the Leads module?
I have been following this: http://community.vtiger.com/help/vtigercrm/developers/third-party-app-integration.html
and have been able to login, query, and do the challenge response, but I have been unable to get the update function to work and it could be because I am not sure how they want the query to look. This is the error I get when I send the query:
stdClass Object ( [success] => [error] => stdClass Object ( [code] => ACCESS_DENIED [message] => Permission to perform the operation is denied for id ) )
Current Test Code:
function updatesomeone(){
global $createduserleadnum;
global $url;
global $sessionID;
global $createduserid;
$customdata = array(
'firstname'=> 'TestAPILead2',//Update First name
'lastname'=> 'TestAPILeadLast2', //Updated Last name
'leadstatus'=> 'New',
'leadsource'=> 'Some Lead Source', //Not Real Lead source
'assigned_user_id'=> 'User-Assigned', //not real user
'cf_755'=> 'A Custom Field', // A Custom Field
'lead_no' => $createduserleadnum, Acquired from other function/stored value
);
$customdata = json_encode($customdata);
$field = array(
'operation' => 'update',
'sessionName'=> $sessionID,
'element' => $customdata
);
$fields_string;
foreach($field as $key=>$value) { global $fields_string;
$fields_string .= $key.'='.$value.'&'; }
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($field));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
$pringjson = json_decode($result);
print_r($pringjson);
}
Figured it out. It was related to the $fieldstring variable. For some reason it was not staying local to the function so it was including some other variables. just changed the fieldstring variable with a digit at the end. In the final code I will write a better script for url-ify'ing the variables. I also had to use the full id given. Either way it was resolved now and the code works as it should.
I have a suggestion for your code. You have not remove & at the end of which will get generated after "foreach" loop. So just add rtrim after foreach and define your $fields_string variable as blank.
$fields_string = '';
foreach($field as $key=>$value) {
global $fields_string;
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');

Data stored without whitespace after cURL

The setup is simple. A Joomla eCommerce site (MySQL back-end) that sends data (cURL post) to another database backed application (ASP with MS SQL) after a Joomla account has been created.
The problem is that sometimes this data is stored on the receiving database without any white spaces. For example: an address collected on the Joomla site is stored in the database as "123 example road" but on the receiving database it's being stored as "123exampleroad". This doesn't happen all of the time - so I'm rather baffled at what the cause might be.
Has anyone experienced such an issue? Any help is appreciated.
This is what the cURL code looks like:
//create array of data to be posted
foreach( $registrationfields as $field ) {
if( $field->name == 'email') $field->name = 'user_email';
if( $field->name == 'delimiter_sendregistration') continue;
if( $field->type == 'captcha') continue;
if( $field->type == 'delimiter') continue;
switch($field->name) {
case 'country':
require_once(CLASSPATH.'ps_country.php');
$country = new ps_country();
$dbc = $country->get_country_by_code($dbbt->f($field->name));
if( $dbc !== false ) $val = $dbc->f('country_name');
break;
default:
$val = $dbbt->f($field->name);
break;
}
$post_data[$field->name] = $val;
}
$post_data['order_id'] = $order_id;
$post_data['order_date'] = $order_date;
$post_data['order_status'] = $order_status;
$post_data['username'] = $username;
//traverse array and prepare data for posting (key1=value1)
foreach ( $post_data as $key => $value) {
$post_items[] = $key . '=' . $value;
}
//create the final string to be posted using implode()
$post_string = implode ('&', $post_items);
//create cURL connection
$curl_connection =
curl_init('http://--url-here');
//set options
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl_connection, CURLOPT_USERAGENT,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
//set data to be posted
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
//perform our request
$result = curl_exec($curl_connection);
//show information regarding the request
print_r(curl_getinfo($curl_connection));
echo curl_errno($curl_connection) . '-' .
curl_error($curl_connection);
//close the connection
curl_close($curl_connection);
Try to send your data encoded as one parameter using base64. Don't use native phpfunctions as they may output special characters like slash. Use functions listed in first answer to this post.
I think that problem lays in how curl encodes spaces (%20) and how your destination script reads them.
example (using functions from link):
...
$post_string = implode ('&', $post_items);
$post_string = myBase64_encode($post_string);
...
This issue was fixed after I re-factored the code. Instead of modifying the array using a loop and then an "implode" to form a string - like so:
//traverse array and prepare data for posting (key1=value1)
foreach ( $post_data as $key => $value) {
$post_items[] = $key . '=' . $value;
}
//create the final string to be posted using implode()
$post_string = implode ('&', $post_items);
I used the "http_build_query" function instead, which accomplishes the same thing without causing errors.
$post_string = http_build_query($post_data) . "\n";

HTTPS link fetch issue

i have been trying for the last several days to fetch a request from a website but no success.
I keep getting error 301.
Is anyone able to help me grab the content of this page: https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET
I am looking forward to your reply.
EDIT:
This is the php function I've used:
function http_request(
$verb = 'GET', /* HTTP Request Method (GET and POST supported) */
$ip, /* Target IP/Hostname */
$port = 80, /* Target TCP port */
$uri = '/', /* Target URI */
$getdata = array(), /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$postdata = array(), /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$cookie = array(), /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
$timeout = 1000, /* Socket timeout in milliseconds */
$req_hdr = false, /* Include HTTP request headers */
$res_hdr = false /* Include HTTP response headers */
)
{
$ret = '';
$verb = strtoupper($verb);
$cookie_str = '';
$getdata_str = count($getdata) ? '?' : '';
$postdata_str = '';
foreach ($getdata as $k => $v)
$getdata_str .= urlencode($k) .'='. urlencode($v);
foreach ($postdata as $k => $v)
$postdata_str .= urlencode($k) .'='. urlencode($v) .'&';
foreach ($cookie as $k => $v)
$cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';
$crlf = "\r\n";
$req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
$req .= 'Host: '. $ip . $crlf;
$req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
$req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
$req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
$req .= 'Accept-Encoding: deflate' . $crlf;
$req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;
foreach ($custom_headers as $k => $v)
$req .= $k .': '. $v . $crlf;
if (!empty($cookie_str))
$req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;
if ($verb == 'POST' && !empty($postdata_str)){
$postdata_str = substr($postdata_str, 0, -1);
$req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
$req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
$req .= $postdata_str;
}
else $req .= $crlf;
if ($req_hdr)
$ret .= $req;
if (($fp = #fsockopen($ip, $port, $errno, $errstr)) == false)
return "Error $errno: $errstr\n";
stream_set_timeout($fp, 0, $timeout * 1000);
fputs($fp, $req);
while ($line = fgets($fp)) $ret .= $line;
fclose($fp);
if (!$res_hdr)
$ret = substr($ret, strpos($ret, "\r\n\r\n") + 4);
return $ret;
}
Firstly, 301 is not an "error" as such, it indicates that you are being redirected. You need to parse the response headers, take the value of the Location: header (which the HTTP protocol specification requires be present in a redirect response) and request that URI as well.
Secondly, the function above does not appear to provide any support for accessing HTTPS URLs. You need the OpenSSL extension installed for your PHP instance to do this, and you also need to actually call it some how. You could use the above function to do so by passing ssl:// or tls:// in front of the address in the $ip parameter, but you cannot simply pass the IP.
Thirdly, the usual way to do things like this is with the cURL extension. You would do something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET'); // Set the URL
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Follow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Get the result from the execution
if (($result = curl_exec($ch)) === FALSE) { // Execute the request
echo "cURL failed! Error: ".curl_error($ch);
} else {
echo "Success! Result: $result";
}
curl_close($ch);
Alternatively, if cURL is not available or you don't want to use it for some reason, you could have go with my HTTPRequest class, which is PHP4 compliant and requires no extensions (apart from OpenSSL for HTTPS requests). Documented(ish) in comments at the top of the script. You would do something like this:
$request = new httprequest(); // Create an object
// Set the request URL
if (!$request->setRequestURL('https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET')) echo "Failed! Error: ".$request->getLastErrorStr()."<br>\r\n";
// Send the request
if (!$request->sendRequest()) echo "Failed! Error: ".$request->getLastErrorStr()."<br>\r\n";
echo "Success! Result: ".$request->getResponseBodyData(TRUE);
On a side note, a lot of the Scene PreDB managers/providers are not too keen on automated scraping, and you may get yourself banned...

Make a PHP GET request from a PHP script and exit

Is there something simpler than the following.
I am trying to make a GET request to a PHP script and then exit the current script.
I think this is a job for CURL but is there something simpler as I don't want to really worry about enabling the CURL php extension?
In addition, will the below start the PHP script and then just come back and not wait for it to finish?
//set GET variables
$url = 'http://domain.com/get-post.php';
$fields = array(
'lname'=>urlencode($last_name),
'fname'=>urlencode($first_name)
);
//url-ify the data for the GET
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_GET,count($fields));
curl_setopt($ch,CURLOPT_GETFIELDS,$fields_string);
//execute GET
$result = curl_exec($ch);
//close connection
curl_close($ch);
I want to run the other script which contains functions when a condition is met so a simple include won't work as the if condition wraps around the functions, right?
Please note, I am on windows machine and the code I am writing will only be used on a Windows OS.
Thanks all for any help and advice
$url = 'http://domain.com/get-post.php?lname=' . urlencode($last_name) . '&fname=' . urlencode($first_name);
$html = file_get_contents($url);
If you want to use the query string assembly method (from the code you posted):
//set GET variables
$url = 'http://domain.com/get-post.php';
$fields = array(
'lname'=>urlencode($last_name),
'fname'=>urlencode($first_name)
);
//url-ify the data for the GET
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
$html = file_get_contents($url . '?' . $fields_string);
See:
http://php.net/manual/en/function.file-get-contents.php

Categories