In Challenge 1, i successfully simulated a post request in native environment.
In challenge 2, i have to add a get request to fetch the question page, then use Regular Expression to get the random data.
After a hours coding, i can't wait to enjoy my work and got the mark. However, my script was too slow to post the result in 1 second.
Googled for a while with the keywords "php fsockopen slow", comed across this post:
[1]http://yubosun.akcms.com/tech/php-fsockopen-slow.htm PHP的fsockopen方式访问接口慢的原因与优化方案
It seems like the problem of connection paraments in the request header which wait for the response of remote server. When the server set a keep-connection section to 5-15s, my script will keep waiting until the remote server close the connection.
Then, i checked the fsockopen function in the PHP manual, found this:
"
EDITORS NOTE: HTTP/1.1 uses persistent connection causing this delay. Use "Connection: close" header to disable it.
"
So, i modified the header fileds, then, everything worked fine.
This is my code snippets:
<?php /* 发送数据,封装 */ function get_request($url,$referer='',$cookie='') { $url = parse_url($url); if($url['scheme'] != 'http') die('Error: only HTTP request are supported'); $host = $url['host']; $path = $url['path']; $fp = fsockopen($host,80,$errno,$errstr,30); if($fp){ fputs($fp,"GET $path HTTP/1.1\r\n"); fputs($fp,"Host: $host\r\n"); if($referer != ''){ fputs($fp,"Referer:$referer\r\n"); } fputs($fp,"Connection: close\r\n"); fputs($fp,"Cookie: $cookie\r\n\r\n"); $result = ''; while(!feof($fp)){ $result .= fgets($fp,1024); } } fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; // return as structured array: return array( 'status' => 'ok', 'header' => $header, 'content' => $content ); } /* * post带有cookie的数据包 * string $url:the url you will visit e.g: http://www.enigmagroup.org/missions/programming/2/ * array $data: post或者get的数据 * string $referer: refer section, defalut for '' * string $cookie: your can get it from fiddle2 */ function post_request($url,$data,$referer='',$cookie='') { $data = http_build_query($data); $url = parse_url($url); if($url['scheme'] != 'http') die('Error: only HTTP request are supported'); $host = $url['host']; $path = $url['path']; $fp = fsockopen($host,80,$errno,$errstr,30); if($fp){ fputs($fp,"POST $path HTTP/1.1\r\n"); fputs($fp,"Host: $host\r\n"); if($referer != ''){ fputs($fp,"Referer:$referer\r\n"); } fputs($fp,"Content-Type: application/x-www-form-urlencoded\r\n"); fputs($fp,"Content-length: ". strlen($data) ."\r\n"); fputs($fp,"Connection: close\r\n"); fputs($fp,"Cache-Control: max-age=0\r\n"); fputs($fp,"Cookie: $cookie\r\n\r\n"); fputs($fp,$data); $result = ''; while(!feof($fp)){ $result .= fgets($fp,128); } }else{ return array( 'status' => 'err', 'error' => "$errstr($errno)" ); } fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; // return as structured array: return array( 'status' => 'ok', 'header' => $header, 'content' => $content ); } $cookie = 'according-to-your-profile'; $gurl = 'http://www.enigmagroup.org/missions/programming/2/'; $ret = get_request($gurl,'',$cookie); echo "get data============\r\n{$ret['content']}\r\n"; $data = array(); echo "match process\n\n"; if(preg_match("/<form[^>]*?>(.*?)<\/form>/is",$ret['content'],$match_fulltext)){ echo "match_fulltext=>\n$match_fulltext[0]"; if(preg_match_all("/<input\s.*?>/is",$match_fulltext[0],$match)) { print_r($match); foreach($match[0] as $line){ echo $line; preg_match("/<input\s.*name=\"(?P<name>.*)\"\svalue=\"((?P<value>.*))\"/",$line,$rst); $data[$rst['name']] = $rst['value']; } $data['answer'] = $data['E[number]'] * 4; //$data['E[time]'] = time(); print_r($data); } } echo "match over\n\n"; $purl = 'http://www.enigmagroup.org/missions/programming/2/index.php'; $ret = post_request($purl,$data,'',$cookie); echo "post response============\r\n"; print_r($ret); ?>