cURL post data to asp.net page - php

I am trying to call the __doPostback javascript function in a asp.net page from php using curl.
I learnt that this can be done by making a post request to the asp.net page with the appropriate parameters.
So in curl,
I make a get request / just use file_get_contents to retrieve the initial page.
From this, I extract the values for __VIEWSTATE and __EVENTVALIDATION.
So far everything seems ok.
Now, I understand that we need to make a post request using cURL with __VIEWSTATE and other parameters required. ( values for the fields present in the asp.net form )
I am unable to construct the CURLOPT_POSTFIELDS correctly.
For instance, I am trying this out,
$postoptions1='__EVENTTARGET='.('ctl00$ContentPlaceHolder1$gRef').'&__EVENTARGUMENT='.('$2');
$postoptions2 = '&__VIEWSTATE='.urlencode($viewState) ;
$otherparams = '&ctl00$ContentPlaceHolder1$ddlName=Abc';
And before using setopt for CURLOPT_POSTFIELDS, I am doing,
urlencode ($postoptions1.$postoptions2.$otherparams)
This does not work. The submit results are not shown, which means, the required parameter __VIEWSTATE was not found in my post request.
If I change the order of the parameters and place __VIEWSTATE as the first parameter, the results page is shown but the other parameter values are not honoured.
I think there is some problem with the way I am encoding the parameters.
Please tell me how to construct the parameters for the post request to a asp.net page.
Thanks.
--Edited--
Here is the complete code:
$resultsPerPage='10';
$url = "www.example.com"; // url changed
$curl_connection = curl_init($url);
function sendCurl($curl_connection,$url,$params,$isPost=false) {
//$post_string = $params;
$post_string = http_build_query($params);
//$post_string = build_query_string($params);
//$post_string = urlencode($params);
echo 'After Encode'.$post_string;
$cookie="/cookie.txt";
//set options
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 300);
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_HEADER, 0); // don't return headers
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl_connection,CURLOPT_REFERER, $url);
if($isPost) {
curl_setopt ($curl_connection, CURLOPT_POST, true);
//set data to be posted
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($curl_connection,CURLOPT_COOKIEJAR,$cookie);
}
else {
curl_setopt($curl_connection,CURLOPT_COOKIEFILE,$cookie);
}
$response1 = curl_exec($curl_connection);
if($response1 === false)
{
echo 'Curl error: ' . curl_error($curl_connection);
}
else
{
echo 'Operation completed without any errors';
}
return $response1;
} **// First time, get request to asp.net page
$response1 = sendCurl($curl_connection,$url,'',false);
$viewState=getVStateContent($response1);
$eventValidation =getEventValidationContent($response1);
$simpleParams = '&__VIEWSTATE='.$viewState.'&ctl00$ContentPlaceHolder1$ddlManuf=&ctl00$ContentPlaceHolder1$ddlCrossType=&ctl00$ContentPlaceHolder1$ddlPageSize='.$resultsPerPage.'&ctl00$ContentPlaceHolder1$btnSearch=Search&ctl00_ToolkitScriptManager1_HiddenField=&__EVENTTARGET=&__EVENTARGUMENT=';
// Second post - for submitting the search form
$response2= sendCurl($curl_connection,$url,$simpleParams,true);
----**

What you want is http_build_query, which will format an array as proper HTTP parameters.
Edit: To clarify what this should probably look like:
$params = array(
'__EVENTTARGET' => 'ctl00$ContentPlaceHolder1$gRef',
'__EVENTARGUMENT' => '$2',
'__VIEWSTATE' => $viewState,
'ctl00$ContentPlaceHolder1$ddlName' => 'Abc'
);
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, http_build_query($params));
Also, what's ctl00$ContentPlaceHolder1$ddlName supposed to be?

Don't urlencode() the ampersands (&) linking the parameters together, just the keys & values (the stuff on either side of the ampersands).

Related

CURL won't get the data from this website

I'm trying to retrieve data from www.dotabuff.com for a list of steam ID, but I only get in return "We couldn't find what you are looking for!".
The goal is to go to the website, search a player with his steam ID and extract his win rate.
(This is intended for very small lists, which will not bother dotabuff).
Here is my code (example with a static steam ID):
//create array of data to be posted
$post_data['utf8'] = '✓';
$post_data['q'] = '76561198055615656';
$post_data['commit'] = 'Search';
//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('https://www.dotabuff.com//');
//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);
echo $result;
//close the connection
curl_close($curl_connection);
You are using POST with curl to do the search, but looking at the Dotabuff website the search form is using GET, so I suspect the website is looking for GET vars instead of POST vars. I haven't tested this but I would suggest doing a curl request to https://www.dotabuff.com/search?q=76561198055615656 (without the POSTFIELDS) and see what that gives you.
Init curl without the URL, or assemble a GET version of the URL and post it to the site.
For example, if you want info on user 'USH!' (I reandomly selected one). the URL you'd synthesize would look like this:
https://www.dotabuff.com/search?utf8=%E2%9C%93&q=USH%21&button=
I's suggest using urlencode to convert the player ID to a GET URI safe string
ex:
$safe_player_id = urlencode($player_id)
$URI = sprintf("https://www.dotabuff.com/search?q=%s&button=",$safe_player_id);
Or, if you know their player ID code (int) then this would work to get the page of stats (this works):
https://www.dotabuff.com/players/76561198055615656
Then you just need to parse the page for what you want.

PHP curl not sending post params

I have an online form to submit data as http post.
If no data is send as post , it will return the following error message
We are sorry, the form that you have submitted is invalid or no longer exists.
I am using the following code to send http post data using curl.But I am always getting the error message as output.
How to resolve this issue.Did I miss anything.I printed the curl request, and the post parameters are not sent.How can I fix this?
My code is given below
function curlUsingPost($url, $data)
{
$content_type = 'application/x-www-form-urlencoded';
if(empty($url) OR empty($data))
{
return 'Error: invalid Url or Data';
}
//url-ify the data for the POST
$fields_string = '';
foreach($data as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = http_build_query($data).'\n';
echo $fields_string;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
// curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: ' . $content_type]);
curl_setopt($ch, CURLOPT_HTTPHEADER,array($content_type));
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt( $curl_handle, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10); # timeout after 10 seconds, you can increase it
//curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); # Set curl to return the data instead of printing it to the browser.
curl_setopt($ch, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)"); # Some server may refuse your request if you dont pass user agent
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$info = curl_getinfo($ch);
print_r($info );
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
return $result;
}
$url = 'office.promptip.com:8443/his1.max/Services/Webform.aspx?request=submitwebform&token=202D36560E444E466658461615120F75411B09634C696C6F79454E795E7C7A5154505645414F456C584C17101B443D431D0B654D66686D7C454E795E2D7E5152565341404145625E4213141E4273421E5E66486B666F2A464B7A5B79785F54520645444F15635C454516134422421A0D664A3D68687C454E79587F7D5F52575714424043635E1611181D16704D1D0E654F69696F2A474A7A0A78785807525E45414E406350424016134422421A0D374C6F686C7C44482F59787D5E530150104218426D584316181A4177411B0F';
//echo $url;
$data = [
'C0IFirstName' => 'John Doe',
'C1ILastName' => 'Doe John',
'C2IPosition' =>'Father-Guardian',
'U3I80'=>'8129020464',
'U4I150'=>'johndoe#johndoe.com',
'U5I79'=>'This is the message buddy',
'U6I102' => 'Ann',
'U7I105' =>'Doe',
'U8I52' =>'FS1',
'C9IClientId'=> rand ( 0,100000 ),
'U10I21'=>'Website-Enquiry Form'
];
echo curlUsingPost($url,$data);
Solution
Add this to your curl request:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And replace & with & in URL you're requesting:
$url = 'office.promptip.com:8443/his1.max/Services/Webform.aspx?request=submitwebform&token=202D36560E444E466658461615120F75411B09634C696C6F79454E795E7C7A5154505645414F456C584C17101B443D431D0B654D66686D7C454E795E2D7E5152565341404145625E4213141E4273421E5E66486B666F2A464B7A5B79785F54520645444F15635C454516134422421A0D664A3D68687C454E79587F7D5F52575714424043635E1611181D16704D1D0E654F69696F2A474A7A0A78785807525E45414E406350424016134422421A0D374C6F686C7C44482F59787D5E530150104218426D584316181A4177411B0F';
Explenation
At first, you're requesting wrong URL, which was probably copied from some HTML documentation. Normally a & entity would be replaced by & char by HTML interpreter, but this does not work with curl and you have to replace the entity manually.
Also the server returns
We are sorry, the form that you have submitted is invalid or no
longer exists.
for each end every request in response body. But for successfull request it also provides a Location header. Normally browser would follow this location, make a second request and display success message. You have to tell cURL to do exactly the same with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true).

How to make Curl post Using Php involving cookies

I am developing a script involving Php Curl to send sms using http://www.gysms.com/freesms.php
The page stores a cookie PHPSESSID and also a hidden field named token is passed during the posting.
I have written a script involving two curl requests. 1st curl request parse the page and obtain the token value .
Here is the code for that:
<?php
$phone = '9197xxxxxxx';
$msg = 'Hi this is curlpost';
$get_cookie_page = 'http://www.gysms.com/freesms.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $get_cookie_page);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$sabin = curl_exec($ch);
$html=explode('<input type="hidden" name="trigger" value="',$sabin);
$html=explode('"/>',$html[1]);
//store the token value to $html[0]
?>
Curl post is done using the following code:
<?php
$fields = array(
'trigger'=>urlencode($html[0]), //token value
'number'=>urlencode($phone), //phone no
'message'=>urlencode($msg) //message
);
//posting curl request
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
$url = 'http://www.gysms.com/freesms.php';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//execute post
$result = curl_exec($ch);
echo $result;
curl_close($ch);
?>
The sms is not sending Using the above code.
If the sms is sent It should show sms is send to-No.
I don't Know where I went wrong. Please help, I am new to PHP.
Finally this attempt is only for my educational purpouse.
Here is some code I came up with that worked. Hope it helps. Some explanations and feedback about your code follow.
<?php
$number = '14155556666';
$message = 'This is my text in all its glory.';
$url = 'http://www.gysms.com/freesms.php';
$cookieFile = tempnam(null, 'SMS');
$userAgent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0';
if (strlen($message) > 100) {
die('Message length cannot exceed 100 characters.');
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); // empty user agents probably not accepted
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // enable this - they check referer on POST
$html = curl_exec($ch);
// <input type="hidden" name="trigger" value="CXXrtmqVC7KbUnJ22UBodFy1kBj4ign5PsQ3qNR91nH2055307b4xP4"/>
if (!preg_match('/name=.trigger.\s+value=.([^\'"]+)/i', $html, $trigger)) {
die('Failed to locate hidden input value');
}
sleep(5); // without a slight delay, i often would not receive sms
$trigger = $trigger[1];
// build array of post values - all are important
$post = array('number' => $number,
'trigger' => $trigger,
'message' => $message,
'remLen' => 100 - strlen($message),
$trigger => 'Send Message');
// switch request to POST, use http_build_query to encode post data for us
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$html = curl_exec($ch);
if (strpos($html, '<b>Message sent to</b>') !== false) {
echo "Message sent!";
} else {
echo "<b>Message not sent :(</b><br /><br />";
echo $html;
}
I think you may have had trouble for several reasons:
A User-Agent should be specified in the request, they seem to reject if you leave it empty
I used http_build_query to build the POST string (preference)
You were missing 2 fields in the request, remLen, and the trigger value as the submit button
I often would not receive the messages if I didn't sleep a few seconds before sending the message after getting the trigger value.
In most of the cases where I didn't get the message, it still showed the "Message sent to phone #" on the screen even though it never came. Once I combined all the right things (sleep time, user agent, valid post fields) I would see the success message but also get the response.
I think the most critical thing left out from your code was that on the first request where you grab the trigger value, they also set a cookie (PHPSESSID) that you are required to capture. Without sending that on the POST request it was probably an automatic reject.
To get around this, make sure you capture cookies on the first request as well as subsequent requests. I chose to re-use the same curl handle for both requests. You don't have to do it that way, but you would have to use the same cookie file and cookie jar between requests.
Hope that helps.

How to pass a nested array using php cURL

I am collecting form posts via jQuery via the.val() method, validating those posts and passing errors back to the form inputs, or passing true to the .$post method which invokes a PHP cURL script.
A typical var will look like this:
var industs_servedVal = $('#industs_served').val();
In this case it is a select multiple form field. I understand that the .val() method in jQuery passes an array, so that seems reasonable, and am I right in saying that the var will also collect the array.
I then pass var industs_servedVal to the $.post method like this ( then slide up a thank you note):
$.post('../inc/form_sendsf_modified.php', {
othervars: othervarsVal;
industs_served: industs_servedVal,
}, function(data) {
$('#sendEmail').slideUp('slow', 'swing', function() {
$('#sendEmail').replaceWith('<h3>Thank you!</h3><p>Your message was sent to us. We\'ll get back to you as soon as we can.</p>');
});
});
}
return false;
});
The file "form_sendSF_modified.php" handles those posts and sends to the Sales Force Cloud using cURL. This works; however, the problem is that Sales Force shows "array" as the values received for the multiple field array, not the array values themselves. Is there a problem in the way I am collecting the array and passing it to sales force. Is the foreach loop capable of sending the multiple field array values as well as the other values as an array as shown in the code.
$post_data['00N70000002U2fA'] = $_POST['industs_served']; //Array
//$otherpost data
//cURL CODE for post
//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 to SFDC
$curl_connection = curl_init('https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8');
//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);
//End cURL
You can use array itself (but it will change Content-Type header to multipart/form-data).
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_data);
Or you can use build string with http_build_query function, look example #3.
use this
$post = "ac=on&p=1&pr[]=0&pr[]=1&a[]=3&a[]=4&pl=on&sp[]=3&ct[]=3&s=1&o=0&pp=3&sortBy=date";
parse_str($post,$fields);
$url = 'http://example.com/';
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);

cURL response is 200, but it doesn't really post the values

I have the following code for cURL using PHP;
$product_id_edit="Playful Minds (1062)";
$item_description_edit="TEST";
$rank_edit="0";
$price_type_edit="2";
$price_value_edit="473";
$price_previous_value_edit="473";
$active_edit="1";
$platform_edit="ios";
//set POST variables
$url = 'https://www.domain.com/adm_test/phpgen/offline_items.php?operation=insert';
$useragent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1';
$fields = array(
'product_id_edit'=>urlencode($product_id_edit),
'item_description_edit'=>urlencode($item_description_edit),
'rank_edit'=>urlencode($rank_edit),
'price_type_edit'=>urlencode($price_type_edit),
'price_value_edit'=>urlencode($price_value_edit),
'price_previous_value_edit'=>urlencode($price_previous_value_edit),
'active_edit'=>urlencode($active_edit),
'platform_edit'=>urlencode($platform_edit)
);
$fields_string="";
//url-ify the data for the POST
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_VERBOSE, 1);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//add useragent
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_POST,count($fields));
//execute post
$result = curl_exec($ch);
if(curl_errno($ch)){
print "" . curl_error($ch);
}else{
//print_r($result);
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//echo "HTTP Response Code: " . curl_error($ch);
echo $httpCode;
//close connection
curl_close($ch);
I have $httpCode printed; I get the code 200; I presume this is OK as I have read in the Manual Pages, however, when I check against the site, the POSTed values does not exist,
does this have something to do with cross-domains as I am not posting it on the same domain?, I'm doing it on 127.0.0.1/site/scrpt.php but how do I get the response code 200 if its not successful?
I also tried to get a 404 which I did by removing a part on the request URL it did return a 404 (this means that cURL is working properly in my assumption)
Does having the url https://www.domain.com/adm_test/phpgen/offline_items.php?operation=insert with the "?operation=insert" has something to do with it?
Let's presume(tho not implied), I'm from another site and I want post values into the form of another website sort'a a robot. tho my objective does not imply any evil intentions, is it that I have to encode thousand lines of info if this is not doable.
Likewise, I don't need a response from the server (but if one is available, then its just fine)
The operation should be passed with CURLOPT_POSTFIELDS. Along with other paramters.
Cross-domain issue happens in case of browser. And your code seems to be a php server side code so this should not be an issue.
Not sure if this is the solution or the problem is different, but this line:
rtrim($fields_string,'&');
Should be this:
$fields_string = rtrim($fields_string,'&');
curl_setopt($ch,CURLOPT_POST,TRUE);
CURLOPT_POST - boolean, it's not a count of values, it's use post flag.
Code 200 indicates that the connection is set up correctly and received a response from the server, but it does not mean that the requested action has been implemented.
Print $result after request to see the response from a web server.

Categories