PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/network/http/Browser.php

http://rhaco.googlecode.com/
PHP | 317 lines | 252 code | 18 blank | 47 comment | 49 complexity | a91c0bb3566992dc1cf0173a5e1d60c3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. Rhaco::import("lang.ArrayUtil");
  3. Rhaco::import("network.http.Http");
  4. Rhaco::import("network.Url");
  5. Rhaco::import("tag.model.TemplateFormatter");
  6. Rhaco::import("tag.model.SimpleTag");
  7. Rhaco::import("exception.ExceptionTrigger");
  8. Rhaco::import("exception.model.NotFoundException");
  9. /**
  10. * ????
  11. *
  12. * @author Kazutaka Tokushima
  13. * @license New BSD License
  14. * @copyright Copyright 2006- rhaco project. All rights reserved.
  15. */
  16. class Browser{
  17. var $cookie = array();
  18. var $variables = array();
  19. var $agent = "Rhaco Browser";
  20. var $user = "";
  21. var $password = "";
  22. var $form = array();
  23. var $status = 200;
  24. var $bodys = array();
  25. var $headers = array();
  26. var $urls = array();
  27. var $requestHeader = array();
  28. var $history = 20;
  29. /**
  30. * POST???
  31. *
  32. * @param string $url
  33. * @return string
  34. */
  35. function post($url,$variables=array()){
  36. /*** unit("network.http.BrowserTest"); */
  37. $this->setVariable($variables);
  38. return $this->_request($url,"POST");
  39. }
  40. /**
  41. * GET???
  42. *
  43. * @param string $url
  44. * @return string
  45. */
  46. function get($url,$variables=array()){
  47. /*** unit("network.http.BrowserTest"); */
  48. $this->setVariable($variables);
  49. return $this->_request($url,"GET");
  50. }
  51. /**
  52. * agent?????
  53. *
  54. * @param string $agent
  55. */
  56. function setAgent($agent){
  57. $this->agent = $agent;
  58. }
  59. /**
  60. * ????????????????????
  61. *
  62. * @param string $user
  63. * @param string $password
  64. */
  65. function setBasicAuthorization($user,$password){
  66. $this->user = $user;
  67. $this->password = $password;
  68. }
  69. function setHistory($size){
  70. $this->history = intval($size);
  71. }
  72. /**
  73. * ??????????
  74. *
  75. * @param array $headers ????????=>?
  76. */
  77. function setRequestHeader($headers){
  78. $this->requestHeader = ArrayUtil::arrays($headers);
  79. }
  80. /**
  81. * ??????????
  82. * get???post????????
  83. *
  84. */
  85. function setVariable(){
  86. $argList = func_get_args();
  87. if(is_array($argList[0])){
  88. foreach($argList[0] as $key => $value){
  89. $this->variables[$key] = $value;
  90. }
  91. }else{
  92. $this->variables[$argList[0]] = $argList[1];
  93. }
  94. }
  95. function status(){
  96. /*** unit("network.http.BrowserTest"); */
  97. return $this->status;
  98. }
  99. function body($num=0){
  100. /*** unit("network.http.BrowserTest"); */
  101. if($num < 0) $num *= -1;
  102. return isset($this->bodys[$num]) ? $this->bodys[$num] : null;
  103. }
  104. function header($num=0){
  105. /*** unit("network.http.BrowserTest"); */
  106. if($num < 0) $num *= -1;
  107. return isset($this->headers[$num]) ? $this->headers[$num] : null;
  108. }
  109. function url($num=0){
  110. /*** unit("network.http.BrowserTest"); */
  111. if($num < 0) $num *= -1;
  112. return isset($this->urls[$num]) ? $this->urls[$num] : null;
  113. }
  114. function _request($url,$method="GET"){
  115. $cookies = "";
  116. $variables = "";
  117. $headers = $this->requestHeader;
  118. foreach(ArrayUtil::arrays($this->cookie) as $name => $cookie){
  119. $cookies .= sprintf("%s=%s; ",$name,$cookie);
  120. }
  121. if(!empty($this->variables)){
  122. if(strtoupper($method) == "GET"){
  123. $url = (strpos($url,"?") === false) ? $url."?" : $url."&";
  124. $url .= TemplateFormatter::httpBuildQuery($this->variables);
  125. }else{
  126. $headers["Content-Length"] = strlen($variables);
  127. $headers["var"] = $this->variables;
  128. }
  129. }
  130. if(!empty($cookies)) $headers["Cookie"] = $cookies;
  131. if(!empty($this->agent)) $headers["User-Agent"] = $this->agent;
  132. if(!empty($this->user)){
  133. if(preg_match("/^([\w]+:\/\/)(.+)$/",$url,$match)){
  134. $url = $match[1].$this->user.":".$this->password."@".$match[2];
  135. }else{
  136. $url = "http://".$this->user.":".$this->password."@".$url;
  137. }
  138. }
  139. list($head,$body) = Http::request($url,$method,$headers);
  140. $this->_parseHeader($head);
  141. $this->_parseBody($body,$url);
  142. array_unshift($this->bodys,$body);
  143. array_unshift($this->headers,$head);
  144. array_unshift($this->urls,$url);
  145. if(count($this->bodys) > $this->history){
  146. array_pop($this->bodys);
  147. array_pop($this->headers);
  148. array_pop($this->urls);
  149. }
  150. if(!empty($head)){
  151. $this->status = Http::parseStatus($head);
  152. if($this->status != 200){
  153. if(Http::isRedirect($redirectUrl,$this->status,$head)){
  154. return $this->_request($redirectUrl,$method);
  155. }
  156. return null;
  157. }else if(SimpleTag::setof($tag,$body,"head")){
  158. foreach($tag->getIn("meta") as $meta){
  159. if(strtolower($meta->param("http-equiv")) == "refresh"){
  160. if(preg_match("/^[\d]+;url=(.+)$/i",$meta->param("content"),$refresh)){
  161. $this->variables = array();
  162. return $this->get(URL::parseAbsolute(dirname($url),$refresh[1]));
  163. }
  164. }
  165. }
  166. }
  167. }
  168. $this->variables = array();
  169. return $body;
  170. }
  171. function submit($form=0,$submit=null){
  172. /*** unit("network.http.BrowserTest"); */
  173. foreach($this->form as $key => $f){
  174. if($f["name"] == $form || $key == $form){
  175. $form = $key;
  176. break;
  177. }
  178. }
  179. if(!isset($this->form[$form])) return ExceptionTrigger::raise(new NotFoundException($form));
  180. $inputcount = 0;
  181. $onsubmit = false;
  182. foreach($this->form[$form]["element"] as $element){
  183. switch($element["type"]){
  184. case "hidden":
  185. case "textarea":
  186. if(!array_key_exists($element["name"],$this->variables)) $this->setVariable($element["name"],$element["value"]);
  187. break;
  188. case "text":
  189. case "password":
  190. $inputcount++;
  191. if(!array_key_exists($element["name"],$this->variables)) $this->setVariable($element["name"],$element["value"]); break;
  192. break;
  193. case "checkbox":
  194. case "radio":
  195. if($element["selected"] !== false){
  196. if(!array_key_exists($element["name"],$this->variables)) $this->setVariable($element["name"],$element["value"]);
  197. }
  198. break;
  199. case "submit":
  200. case "image":
  201. if(($submit === null && $onsubmit === false) || $submit == $element["name"]){
  202. $onsubmit = true;
  203. if(!array_key_exists($element["name"],$this->variables)) $this->setVariable($element["name"],$element["value"]);
  204. break;
  205. }
  206. break;
  207. case "select":
  208. if(!array_key_exists($element["name"],$this->variables)){
  209. if($element["multiple"]){
  210. $list = array();
  211. foreach($element["value"] as $option){
  212. if($option["selected"]) $list[] = $option["value"];
  213. }
  214. $this->setVariable($element["name"],$list);
  215. }else{
  216. foreach($element["value"] as $option){
  217. if($option["selected"]){
  218. $this->setVariable($element["name"],$option["value"]);
  219. }
  220. }
  221. }
  222. }
  223. break;
  224. case "button":
  225. break;
  226. }
  227. }
  228. if($onsubmit || $inputcount == 1){
  229. return ($this->form[$form]["method"] == "post") ?
  230. $this->post($this->form[$form]["action"]) :
  231. $this->get($this->form[$form]["action"]);
  232. }
  233. return false;
  234. }
  235. function _parseBody($body,$url){
  236. $tag = SimpleTag::anyhow($body);
  237. $this->form = array();
  238. foreach($tag->getIn("form") as $key => $formtag){
  239. $form = array();
  240. $form["name"] = $formtag->param("name",$formtag->param("id",$key));
  241. $form["action"] = URL::parseAbsolute(dirname($url),$formtag->param("action",$url));
  242. $form["method"] = strtolower($formtag->param("method","get"));
  243. $form["element"] = array();
  244. $form["multiple"] = false;
  245. foreach($formtag->getIn("input") as $count => $input){
  246. $form["element"][] = array("name"=>$input->param("name",$input->param("id","input_".$count)),
  247. "type"=>strtolower($input->param("type","text")),
  248. "value"=>TemplateFormatter::htmldecode($input->param("value")),
  249. "selected"=>("selected" === strtolower($input->param("checked",$input->attr("checked"))))
  250. );
  251. }
  252. foreach($formtag->getIn("textarea") as $input){
  253. $form["element"][] = array("name"=>$input->param("name",$input->param("id","textarea_".$count)),
  254. "type"=>"textarea",
  255. "value"=>TemplateFormatter::htmldecode($input->getValue()),
  256. "selected"=>true
  257. );
  258. }
  259. foreach($formtag->getIn("select") as $count => $input){
  260. $options = array();
  261. foreach($input->getIn("option") as $count => $option){
  262. $options[] = array("value"=>TemplateFormatter::htmldecode($option->param("value",$option->getValue())),
  263. "selected"=>("selected" == strtolower($option->param("selected",$option->attr("selected"))))
  264. );
  265. }
  266. $form["element"][] = array("name"=>$input->param("name",$input->param("id","select_".$count)),
  267. "type"=>"select",
  268. "value"=>$options,
  269. "selected"=>true,
  270. "multiple"=>("multiple" == strtolower($input->param("multiple",$input->attr("multiple"))))
  271. );
  272. }
  273. $this->form[] = $form;
  274. }
  275. }
  276. function _parseHeader($header){
  277. if(preg_match_all("/Set-Cookie: (.+)/i",$header,$matchs)){
  278. $unsetcookie = array();
  279. $setcookie = array();
  280. foreach($matchs[1] as $cookies){
  281. foreach(explode(";",$cookies) as $cookie){
  282. $cookie = trim($cookie);
  283. if(preg_match("/^(.+?)=(.+)$/",$cookie,$match)){
  284. if(strtolower($match[1]) == "expires" && DateUtil::parseString($match[1]) < time()){
  285. $unsetcookie[$cookies] = 1;
  286. }else{
  287. $setcookie[$cookies][$match[1]] = $match[2];
  288. }
  289. }
  290. }
  291. }
  292. foreach($setcookie as $cookies){
  293. foreach($cookies as $cookie => $value) $this->cookie[$cookie] = $value;
  294. }
  295. foreach($unsetcookie as $cookies => $value) unset($this->cookie[$cookie]);
  296. }
  297. }
  298. }
  299. ?>