├── README ├── parse.php └── webparse.php /README: -------------------------------------------------------------------------------- 1 | /*********************************\ 2 | HTTP Parse 3 | A minimal HTTP parsing tool. 4 | Written by Twitch 5 | \*********************************/ 6 | 7 | This was originally designed as part of a Web Application Mapping framework project that I joined. The project, as so many do, withered and died. I may well port this to a more broadly used language or build upon it at a later date, though. -------------------------------------------------------------------------------- /parse.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*********************************\ 4 | parse.php 5 | A minimal HTTP parsing thing 6 | Written by Benjamin.Sauls 7 | Twitch 8 | \*********************************/ 9 | 10 | 11 | function get_heads ($host, $port, $path) { 12 | // A function to get the response headers from a site. 13 | // This currently uses a connection for each request, but I would like to work in pipelined requests in the future. 14 | 15 | // Build the query. 16 | $q = "GET $path HTTP/1.1\n"; 17 | $q .= "Host: $host\n"; 18 | $q .= "Connection: Close\n"; 19 | // Insert extra request headers here, to your heart's content. 20 | 21 | $q .= "\n"; 22 | 23 | // Open the socket and/or report errors. 24 | $sock = fsockopen($host, $port, $errno, $errmsg); 25 | if(!$sock) { die("*** Socket Error #$errno: $errmsg.\n"); } 26 | 27 | // Set a boolean to mark/check for the end of the headers. 28 | $in_header = true; 29 | $hi = 0; 30 | 31 | // Send the request down the socket. 32 | fwrite($sock, $q); 33 | // Parse the response as long as we are in the headers. 34 | while($in_header == true) { 35 | $li = fgets($sock); 36 | // Check for the empty line signaling the end of the headers. 37 | if($li == "\r\n") { $in_header = false; } 38 | else { 39 | // Remove the \n from the lines, we can add these manually as needed. 40 | $li = trim($li); 41 | $lines[$hi] = $li; 42 | } 43 | $hi++; 44 | } 45 | // Close the socket. 46 | fclose($sock); 47 | // This leads to interesting TCP behavior. 48 | // The script FINs and tears down the connection as soon as the headers are received, but the server continues to send the response in packets which are reset by the script. 49 | // We could use a HEAD method rather than a GET, but some servers may not support this. 50 | 51 | // Now, parse through the response lines. 52 | // Set up some easier to use variables. 53 | foreach($lines As $lin => $lv) { 54 | if($lin == "0") { 55 | preg_match("/(HTTP\/...) ([0-9]{3}) (.*)/", $lv, $rsline); 56 | $header["response"] = $rsline; 57 | } else { 58 | preg_match("/^([A-Za-z0-9-]*):(.*)/", $lv, $hname); 59 | $header[$hname[1]] = $hname[2]; 60 | } 61 | } 62 | 63 | return $header; 64 | 65 | // Return values: 66 | // This will return an associative array using the header names for 67 | // associative indecies. 68 | // There is also a special array 'response' which contains the first 69 | // line of the response. The sub elements of this are then broken further. 70 | 71 | // ["response"] 72 | // - [1] = "HTTP/1.1" 73 | // - [2] = "200" 74 | // - [3] = "OK" 75 | } 76 | 77 | if(isset($argv[1])) { 78 | $host = $argv[1]; 79 | } else { 80 | $host = "localhost"; 81 | } 82 | if(isset($argv[2])) { 83 | $port = $argv[2]; 84 | } else { 85 | $port = "80"; 86 | } 87 | if(isset($argv[3])) { 88 | $path = $argv[3]; 89 | } else { 90 | $path = "/"; 91 | } 92 | 93 | 94 | $header = get_heads($host, $port, $path); 95 | 96 | 97 | 98 | 99 | echo $header["response"][1]; 100 | echo " ".$header["response"][2]; 101 | echo " ".$header["response"][3]."\n"; 102 | 103 | foreach($header As $header_name => $header_value) { 104 | if($header_name == "response") { 105 | } else { 106 | echo "$header_name:$header_value\n"; 107 | } 108 | } 109 | 110 | preg_match("/([A-Za-z0-9\=\-\:]*);/", $header["Set-Cookie"], $ck); 111 | echo $ck[1]."\n"; 112 | $cookies = explode(":", $header["Set-Cookie"]); 113 | 114 | //var_dump($cookies); 115 | 116 | ?> 117 | -------------------------------------------------------------------------------- /webparse.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*********************************\ 4 | webparse.php 5 | A minimal HTTP parsing thing 6 | Written to interface via the web. 7 | Written by Benjamin.Sauls 8 | Twitch 9 | \*********************************/ 10 | 11 | 12 | function get_heads ($host, $port, $path, $method, $version, $headers = NULL) { 13 | // A function to get the response headers from a site. 14 | // This currently uses a connection for each request, but I would like to work in pipelined requests in the future. 15 | 16 | // Make sure we have the leading slash for the resource. 17 | if($path[0] != "/") { 18 | $path = "/".$path; 19 | } 20 | 21 | // Build the query. 22 | $q = "$method $path HTTP/$version\n"; 23 | $q .= $headers; 24 | 25 | $q .= "\n\n"; 26 | 27 | // Open the socket and/or report errors. 28 | $sock = fsockopen($host, $port, $errno, $errmsg); 29 | if(!$sock) { die("*** Socket Error #$errno: $errmsg.\n"); } 30 | 31 | // Set a boolean to mark/check for the end of the headers. 32 | $in_header = true; 33 | $hi = 0; 34 | 35 | // Send the request down the socket. 36 | fwrite($sock, $q); 37 | // Parse the response as long as we are in the headers. 38 | while($in_header == true) { 39 | $li = fgets($sock); 40 | // Check for the empty line signaling the end of the headers. 41 | if($li == "\r\n") { $in_header = false; } 42 | else { 43 | // Remove the \n from the lines, we can add these manually as needed. 44 | $li = trim($li); 45 | $lines[$hi] = $li; 46 | } 47 | $hi++; 48 | } 49 | // Close the socket. 50 | fclose($sock); 51 | // This leads to interesting TCP behavior. 52 | // The script FINs and tears down the connection as soon as the headers are 53 | // received, but the server continues to send the response in packets which 54 | // are reset by the script. We could use a HEAD method rather than a GET, 55 | // but some servers may not support this. 56 | 57 | // Now, parse through the response lines. 58 | // Set up some easier to use variables. 59 | foreach($lines As $lin => $lv) { 60 | if($lin == "0") { 61 | preg_match("/(HTTP\/...) ([0-9]{3}) (.*)/", $lv, $rsline); 62 | $header["response"] = $rsline; 63 | } else { 64 | preg_match("/^([A-Za-z0-9-]*):(.*)/", $lv, $hname); 65 | $header[$hname[1]] = $hname[2]; 66 | } 67 | } 68 | $header["q"] = $q; 69 | return $header; 70 | 71 | // Return values: 72 | // This will return an associative array using the header names for 73 | // associative indecies. 74 | // There is also a special array 'response' which contains the first 75 | // line of the response. The sub elements of this are then broken further. 76 | 77 | // ["response"] 78 | // - [1] = "HTTP/1.1" 79 | // - [2] = "200" 80 | // - [3] = "OK" 81 | } 82 | 83 | // Build an array of methods, even though some aren't fully supported by most servers. 84 | // This will make it easier to add/remove these as needed. 85 | $methods = array( 86 | "GET", 87 | "POST", 88 | "HEAD", 89 | "OPTIONS", 90 | "PUT", 91 | "DELETE", 92 | "TRACE", 93 | "CONNECT" 94 | ); 95 | 96 | // Build our request form now. 97 | 98 | ?> 99 | 100 | 101 |
102 |";
181 | echo "";
182 |
183 | // This is sort of confusing. I needed to reference the actual response line
184 | // and wanted to be able to print out the query, as well. To do this, though
185 | // I needed to pass them in the return value. So we have to make sure we don't
186 | // confuse these for being headers.
187 | //
188 | // Excluding the query and response, let's spit out the headers.
189 |
190 |
191 | foreach($header As $header_name => $header_value) {
192 | if($header_name == "response" || $header_name == "q") {
193 | } else {
194 | echo "$header_name:$header_value
";
195 | }
196 | }
197 |
198 | // I believe I was aiming to set variables for each cookie here, or something.
199 | // Honestly I don't recall. I'll update if I do. =/
200 | preg_match("/([A-Za-z0-9\=\-\:]*);/", $header["Set-Cookie"], $ck);
201 | echo $ck[1]."\n";
202 | $cookies = explode(":", $header["Set-Cookie"]);
203 |
204 | }
205 |
206 |
207 | ?>
208 |
209 |