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).
Related
We got a couple of apps, utilizing the car2go Rest-API with OAuth 1.0.
All our web apps stopped working 2 days ago. All curl POST requests are failing now with the following error:
400 Bad Request
Your browser sent a request that this server could not understand.
Error code: 53
Parser Error: [Content-Length: -]
I spend a lot of time trying to figure out if the problem is my oauth workflow. But in the end all parameters and signatures and stuff is correct. I successfully fire the POST via Postman (REST-Client)
So my conclusion is that somehow the php code for the curl is suddenly not working anymore.
This is the (very ugly) curl function. A difference to most tutorials about curl POST is, that I'm passing a full URL with all parameters already attached, so I don't need CURLOPT_POSTFIELDS.
function curlAPI($params) {
//open connection
$ch = curl_init();
$url = $params['url'];
curl_setopt($ch,CURLOPT_HEADER,false);
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch, CURLOPT_MAXREDIRS,50);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
if($params['type'] == 'POST') {
// POST
curl_setopt($ch,CURLOPT_POST, true);
} else if($params['type'] == 'DELETE') {
// DELETE
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
} else if($params['type'] == 'PUT') {
$update_json = array();
// PUT
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,'');
} else {
// GET
curl_setopt($ch,CURLOPT_POST,0);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//execute post
$result['result'] = curl_exec($ch);
// debug
if (FALSE === $result['result']) {
$result['errorInfo'] = curl_error($ch).' - '.curl_errno($ch);
}
$reponseInfo = array();
$reponseInfo['info'] = curl_getinfo($ch);
$reponseInfo['error'] = curl_error($ch);
//close connection
curl_close($ch);
$result['reponseInfo'] = $reponseInfo;
return json_encode($result);
}
Ok, this is what fixed this nightmare:
curl_setopt($ch,CURLOPT_HTTPHEADER ,array('Content-Length: 0'));
Aparrently it's not ok to send a curl POST without a header.
I'm trying to use Docverter to convert LaTeX/markdown files to PDF but am having trouble using PHP to do CURL to access Docverter via their API. I'm know I'm not a total idiot b/c i can get this to work adapting the shell script in this Docverter example and running from command line (Mac OSX).
Using PHP's exec():
$url=$_SERVER["DOCUMENT_ROOT"];
$file='/markdown.md';
$output= $url.'/markdown_to_pdf.pdf';
$command="curl --form from=markdown \
--form to=pdf \
--form input_files[]=#".$url.$file." \
http://c.docverter.com/convert > ".$output;
exec("$command");
This gives no error messages but doesn't work. Is there a path issue somewhere?
UPDATE Based on #John's suggestion, here's an example using PHP's curl_exec() adapted from here. Unfortunately this also doesn't work though at least it gives error messages.
$url = 'http://c.docverter.com/convert';
$fields_string ='';
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => $_SERVER['DOCUMENT_ROOT'].'/markdown.md',
);
//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_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
I solved my own problem. There were two main problems with the above code:
1) The $fields array was incorrectly formatted for the input_files[]. It needed a #/ and mime-type declaration (see code below)
2) The curl_exec() output (the actual newly created file contents) needed to be returned and not just true/false which is this function's default behavior. This is accomplished by setting the curl option curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); (see code below).
Full working example
//set POST variables
$url = 'http://c.docverter.com/convert';
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => "#/".realpath('markdown.md').";type=text/x-markdown; charset=UTF-8"
);
//open connection
$ch = curl_init();
//set options
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //needed so that the $result=curl_exec() output is the file and isn't just true/false
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
//write to file
$fp = fopen('uploads/result.pdf', 'w'); //make sure the directory markdown.md is in and the result.pdf will go to has proper permissions
fwrite($fp, $result);
fclose($fp);
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.
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.
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).