• Home
  • About
  • Who Am I?
  •  

    Latest CURL Issues with PHP (apache segmentation faults)

    March 1st, 2007

    Last couple of days i came across issues with CURL 7.15.3 , PHP 4.4.5 and Apache.

    There was this code i had to work on which was written by someone else , the guy was reusing the CURL handle more than one time and i was like …. eh? BUT interesting that code was working a few days ago , somehow during an update to apache etc that code stopped working. And the strangest behaviour was observed. Just imagine my surprise when a function wasnt returning control to the main script. Then i decided to check apache error logs and there it was … segmentation fault , with details

    glibc detected *** double free or corruption

    Now here is what was happening , a curl handle was generated , some post data was sent and then again that handle was used to send some more post data for a different page. The first request went through , but the second one errored out. Now ideally the handle shouldnt be reused in the first place. But earlier for some reason it was working fine and has been working great for a while.

    Now if you experiencing anything similar .. just stop reusing the handle , create a new one for every request and use that. Thats the way it should be done and thats the way you should do it. For instance the CURL wrapper class i have provided here does the same , it always creates a new handle , everything based on that class hasnt ever broken down. So watch out how you use your curl handles!



    PHP : CURL Insight and a PHP Alternative Example

    February 26th, 2007

    CURL has become increasingly popular over the past few years specially because of the fact that the web is becoming an active entity rather than a passive one , as it was in the yester years. CURL is a wonderful tool to communicate with other websites. CURL is also widely used in those “auto comment submit” type scripts. It makes the life of PHP developers easy. Alot of developers just consider it as a magic tool where as its nothing more than a way to format the request headers and play around with the response headers. Lets take a brief look at the insides of some of the CURL functions and what it really does. This article will be useful for situations where the curl library is not installed on the server.

    $ch = curl_init();
    Create the curl handle for use later.

    curl_setopt($ch, CURLOPT_URL,”http://www.abc.com/hello.php”);
    Tell curl the url you want to process.

    curl_setopt ($ch, CURLOPT_HEADER, true);
    Tell curl if it needs to return the response header as well along with the data.

    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

    Tell curl if it should oblige with the “Location:xyz.php” type response header command.

    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    This is the connection timeout limit.

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    Tell curl if it should return the data or not.

    curl_setopt($ch, CURLOPT_USERAGENT, “Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.1)”);
    Put the user agent type in the request header. This identifies what type of browser is requesting the page

    curl_setopt($ch, CURLOPT_REFERER, “http://www.google.com”);
    Put the referer url in the request header.Referer carries the page url where the user clicked on a link to request this page.

    curl_setopt($ch, CURLOPT_COOKIEJAR, “cookies.txt”);
    Provide the file name where curl will store the cookies sent by the web server in response headers.

    curl_setopt($ch, CURLOPT_COOKIEFILE, “cookies.txt”);
    Provide the file name where cookies are stored , and curl will send the cookies in there in the request headers.

    curl_setopt($ch, CURLOPT_POSTFIELDS, array(’username’=>’abc’ , ‘pass’=>’xyz’));
    Provide the post data if any as array , curl will put it in the request headers.

    curl_setopt($ch, CURLOPT_PROXY, “11.11.11.11:8080″ );
    Tell curl if it should send the request via a proxy , provide the ip and port.

    curl_setopt($ch, CURLOPT_PROXYUSERPWD,”user:pass”);
    If the above proxy requires authentication , provise the username and password here.

    $data = curl_exec($ch);
    Execute curl with all the above options and put the data in the $data variable.

    curl_close ($ch);
    Close the connection

    Now lets try to make some code which attempts to do the above with PHP.Please note that i am not trying ot create a full fledge CURL alternative here , i am just showing by example that it can be done easily with PHP , all you need to do is have some experience with headers. This is a not a perfect example script , so feel free to experiment around with it to get desired results.

    You can download the below code if my visual presentation skills with wordpress dont strike you as too good :) - Download the PHP CURL Alternative Example

    Code (php)
    1. <?
    2. $proxyip = "abc.com" ;
    3. $proxyport = "8080";
    4. $proxyuser= "proxy";
    5. $proxypass = "pass";
    6. $urltoprocess = "http://www.xyz.com/testit.php";
    7. $cookiefile = "cookies.txt"; // file must be set to be writable
    8. $referer = "http://www.google.com";
    9. $useragent = "Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.1)";
    10. $returntransfer = true; // — show return data
    11. $showresheader = true; // –show response header
    12. $shoreqheader  = true; // –show request header
    13. $parseurl = parse_url($urltoprocess);
    14. /////////////////
    15. //— make the post data string here
    16. $poststr = "";
    17. $postdata = array(‘username’=>‘abc’ , ‘pass’=>‘xyz’);
    18. foreach($postdata as $fldname => $fldval){
    19. $poststr .= "$fldname=".urlencode($fldval)."&";
    20. }
    21. /////////////////
    22. $contentlen = strlen($poststr);
    23. //– make the request header below
    24. //— check if proxy is to be used
    25. if($proxyip && $proxyport){
    26. $requestheader = "POST  $urltoprocess HTTP/1.1rn";
    27. $requestheader .= "Host: $proxyiprn";
    28. /////////////////
    29. if($proxyuser && $proxypass){
    30. $requestheader .= "Proxy-Authorization: Basic ".base64_encode("$proxyuser:$proxypass")."rn";
    31. }
    32. }else{
    33. $requestheader = "POST  $parseurl[path] HTTP/1.1rn";
    34. $requestheader .= "Host: $parseurl[host]rn";
    35. }
    36. //////////////////
    37. if($referer) $requestheader .= "Referer: http://www.google.comrn";
    38. if($useragent) $requestheader .= "User-Agent: $useragentrn";
    39. /////////////////
    40. //–add cookies to request header if cookies are to be used
    41. if($cookiefile){
    42. $allcookies = implode("" , file($cookiefile));
    43. if($allcookies){
    44. $requestheader .= "Cookie: $allcookiesrn";
    45. }
    46. }
    47. //////////////
    48. //–add post data to request header if any
    49. if($poststr){
    50. $requestheader .= "Content-Type: application/x-www-form-urlencodedrn";
    51. $requestheader .= "Content-Length: $contentlenrn";
    52. $requestheader .= "rn";
    53. $requestheader .= $poststr;
    54. }
    55. //////////////
    56. if($showreqheader){
    57. echo "<pre>";
    58. echo $requestheader;
    59. echo "</pre>";
    60. }
    61. /////////////////
    62. if($proxyip && $proxyport){
    63. $fp = fsockopen($proxyip , $proxyport , $errno , $errstr , 10);
    64. }else{
    65. if(!$parseurl[port]){
    66. if($parseurl[scheme] == "http") $parseurl[port] = 80;
    67. if($parseurl[scheme] == "https") $parseurl[port] = 443;
    68. }
    69. $fp = fsockopen($parseurl[host] , $parseurl[port] , $errno , $errstr , 10);
    70. }
    71. /////////////////
    72. /////////////////
    73. if(!$fp){
    74. echo "$errno : $errstr <br>";
    75. }
    76. /////////////////
    77. /////////////////
    78. fputs($fp , $requestheader);
    79. while(!feof($fp)){
    80. $raw .=fgets($fp , 1024);
    81. }
    82. fclose($fp);
    83. /////////////////
    84. /////////////////
    85. $setcookies = "";
    86. if($raw){
    87. $expl = preg_split("/(rn){2,2}/", $raw, 2) ;
    88. $header = $expl[0];
    89. $data = $expl[1];
    90. /////////////////
    91. /////////////////
    92. if($cookiefile){
    93. $headlines = explode("rn" , $header);
    94. foreach($headlines as $headline){
    95. if(substr_count($headline , "Set-Cookie")){
    96. $setcookies .= trim(str_replace("Set-Cookie: " , "" , $headline))."; ";
    97. }
    98. }
    99. }
    100. }
    101. /////////////////
    102. /////////////////
    103. if($setcookies){
    104. $fp = fopen($cookiefile , "w");
    105. fwrite($fp , $setcookies);
    106. fclose($fp);
    107. }
    108. /////////////////
    109. /////////////////
    110. if(!$returntransfer){
    111. $data = "";
    112. }
    113. /////////////////
    114. /////////////////
    115. if($showresheader){
    116. $data = $header."rnrn".$data;
    117. }
    118. /////////////////
    119. /////////////////
    120. echo $data;
    121. /////////////////
    122. ?>


    How to Easily Use CURL with PHP

    December 4th, 2006

    My Simple CURL Wrapper Class

    Alot of times i have to use CURL with PHP for getting data from remote sites. Its a wonderfull library which makes alot of things easier for developers who want to interact or get data from remote sites and use them inside their own code. This is where my class comes in handy :)
    For simpler uses you can get data easily simply by:
    $data = implode(”" , file(”http://www.abc.com/page1.html”));

    But what to do when you have to login to another site and get data from inside the secure page?

    So here is what i do with this class :

    include(’curl.class.php’);
    $browser = new extractor(true);

    $loginpost[’username’] = “xyz”;
    $loginpost[’password’] = “xyz”;
    $formaction = “http://www.abc.com/login.php”;
    $somesecurepage = “http://www.abc.com/myaccount.php”;

    $data = $browser->getdata($formaction , $loginpost , “” , true , false);
    $mypage = $browser->getdata($somesecurepage , array() , “” , true , true);

    and most of the time i end up logging in to the remote site and getting the page data from secure pages.

    Here is the what this class has to offer.

    Constructor function has 3 parameters :

    First parameter is to allow cookie usage or not , true or false.
    Second parameter is to set the time out of connections. Integer value in seconds.
    Third parameter is to allocate a filename for the storage of the cookie for this session. This can be usefull when you have to carry the login session of the remote site to multiple scripts in your own code. I generally pass the session id to this parameter , this way if i have to use the remote cookie on next pages as well , i can use it easily. You have to create a folder called “cookies” and set its permission to 0777 for this to work correctly. All cookies will be stored there.

    The class has some accessable variables as well. They help you use proxies for your remote requests ;)
    var $proxyaddr; //— you can set the proxy ip or host to use
    var $proxyport; //– proxy port
    var $proxyuser; //– proxy username
    var $proxypass; //– proxy password

    The getdata function lets you actually request the remote url and get its data. The function has these parameters.

    First parameter is the url you want to request.
    Second parameter is the post data you want to send to the remote url. For login, search etc.
    Third parameter is the custom referrer you want to send.
    Fourth parameter is wether to set cookie or not.
    Fifth parameter is wether to use the cookie made earlier.
    Sixth parameter is to send a custom user agent you want to send for the request.
    Seventh parameter is rarely used , sometimes even when you are doing every thing right , you dont get the expected results after sending post data. Setting this parameter to true , sends the post data as string to curl instead of sending it as an array.

    Another usefull function in the class is the search function. This helps you get specific regions out of the html. For instance if you want to get all the <p> inside the html , you can do this.

    $return_array = $browser->search(”<p” , “</p>” , $data);

    The last parameter of the search function lets you remove the start and end strings from the returned results. The result from this function is an array.

    This class i developed has made alot of things easier for me over the years . This makes alot of things easier for you when using curl with php , saves you a bundle of time.

    Hope this helps someone else as well. :)
    Here is the download link