2 کامیت‌ها 053e596769 ... 35a47c6873

نویسنده SHA1 پیام تاریخ
  Björn Wärmedal 35a47c6873 No need to instantiate before making request 4 سال پیش
  tinyrabbit 0470cf4ea2 Merge branch 'master' of MineRobber9000/geminilib.py into master 4 سال پیش
1فایلهای تغییر یافته به همراه37 افزوده شده و 30 حذف شده
  1. 37 30
      geminilib.py

+ 37 - 30
geminilib.py

@@ -8,36 +8,43 @@ import ssl
 urllib.parse.uses_relative.append("gemini")
 urllib.parse.uses_netloc.append("gemini")
 
-class GeminiClient():
-    def __init__(self):
-        pass # later, TOFU tracking can be added via instantiation of the GeminiClient object
-
-    def request(self,url):
-        parsed = urllib.parse.urlparse(url)
-        addresses = socket.getaddrinfo(parsed.hostname, parsed.port or 1965, family=0, type=socket.SOCK_STREAM)
-
-        # We don't do the CA cert verification
-        # We could implement it later but for now we won't
-        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+# If we want to keep an SSL context for some time, we need to instantiate this...
+
+# Methods:
+# - request(url, optionally a client cert, optionally server cert)
+#   - returns a response object: { status, meta, mimetype, body (byte array), servercert }
+#
+# - response(socket, status, meta, optionally body (byte array) )
+#   - returns success or failure?
+#
+# - genCert(...)
+#   - returns a cert (string?)
+class ResponseObject():
+    def __init__(self, serverCert, statusCode, metaField, mimeType, messageBody = ""):
+        self.serverCert = serverCert
+        self.statusCode = statusCode
+        self.metaField = metaField
+        self.mimeType = mimeType
+        self.messageBody = messageBody
+
+def request(url, clientCert = "", clientKey = "", serverCert = ""):
+    parsed = urllib.parse.urlparse(url)
+
+    context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+    context.minimum_version = ssl.TLSVersion.TLSv1_2
+
+    if clientCert and clientKey:
+        context.load_cert_chain(clientCert, clientKey)
+
+    if serverCert:
+        context.load_verify_locations(serverCert)
+    else:
         context.check_hostname = False
         context.verify_mode = ssl.CERT_NONE
-        context.minimum_version = ssl.TLSVersion.TLSv1_2
-
-        for address in addresses:
-            s = socket.socket(address[0], address[1])
-            s.settimeout(30)
-            s = context.wrap_socket(s, server_hostname = parsed.netloc)
-            try:
-                s.connect(address[4])
-                break
-            except OSError as e:
-                err = e
-        else:
-            # If we couldn't connect to *any* of the addresses, just
-            # bubble up the exception from the last attempt and deny
-            # knowledge of earlier failures.
-            raise err
-
-        s.sendall((url+"\r\n").encode("UTF-8"))
-        return s.makefile(mode = "rb")
+
+    sock = socket.create_connection((parsed.hostname, parsed.port or 1965))
+    ssock = context.wrap_socket(sock, server_hostname=parsed.hostname)
+    ssock.sendall((url+"\r\n").encode("UTF-8"))
+
+    return ssock.makefile(mode = "rb")