Created
July 7, 2023 17:15
-
-
Save drushadrusha/ca522d3bf9bca2804a48c5b72892cc09 to your computer and use it in GitHub Desktop.
PHP Gemini Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is a simple PHP script that can be used to fetch a Gemini URL and return the contents. | |
// Example usage: | |
try { | |
echo gemini_get_contents('gemini://gemini.circumlunar.space'); | |
} catch(Exception $e) { | |
echo $e->getMessage(); | |
} | |
function gemini_get_contents($url, $redirectIndex = 0){ | |
if($redirectIndex > 5){ | |
throw new Exception("Too many redirects."); | |
} | |
$hostname = parse_url($url, PHP_URL_HOST); | |
$port = parse_url($url, PHP_URL_PORT); | |
if (!$port) { | |
$port = 1965; | |
} | |
$context = stream_context_create(['ssl' => ['verify_peer' => false]]); | |
$socket = stream_socket_client('ssl://' . $hostname . ':' . $port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context); | |
if (!$socket) { | |
throw new Exception("$errstr ($errno)"); | |
} | |
$request = $url . "\r\n"; | |
fwrite($socket, $request); | |
$response = ''; | |
while (!feof($socket)) { | |
$data = fgets($socket); | |
$response .= $data; | |
} | |
$status_code = substr($response, 0, 2); | |
switch($status_code){ | |
case 10: | |
case 11: | |
throw new Exception("Server requested input. Not supported."); | |
break; | |
case 20: | |
$response = substr($response, strpos($response, "\n")+1); | |
break; | |
case 30: | |
case 31: | |
$url = substr($response, 3, -2); | |
return gemini_get_contents($url, $redirectIndex + 1); | |
break; | |
case 40: | |
throw new Exception("Temporary failure."); | |
break; | |
case 41: | |
throw new Exception("Server unavailable."); | |
break; | |
case 42: | |
throw new Exception("CGI error."); | |
break; | |
case 43: | |
throw new Exception("Proxy error."); | |
break; | |
case 44: | |
throw new Exception("Slow down."); | |
break; | |
case 50: | |
throw new Exception("Permanent failure."); | |
break; | |
case 51: | |
throw new Exception("Not found."); | |
break; | |
case 52: | |
throw new Exception("Gone."); | |
break; | |
case 53: | |
throw new Exception("Proxy request refused."); | |
break; | |
case 59: | |
throw new Exception("Bad request."); | |
break; | |
case 60: | |
throw new Exception("Client certificate required."); | |
break; | |
case 61: | |
throw new Exception("Certificate not authorized."); | |
break; | |
case 62: | |
throw new Exception("Certificate not valid."); | |
break; | |
default: | |
throw new Exception("Invalid response code."); | |
break; | |
} | |
fclose($socket); | |
return $response; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment