commit - d8c723115cf04e9d7d30fb3de5f4350fc895786a
commit + 99b2ef4a07275a0dd3e6fcc15bfc681d3be53b8a
blob - 1ecc5d408ab20f8d8457d1ebdc28afe9dd08a032 (mode 644)
blob + /dev/null
--- java/com/omarpolo/gemini/Gemini.java
+++ /dev/null
-package com.omarpolo.gemini;
-
-import javax.net.ssl.*;
-import java.io.*;
-import java.net.Socket;
-import java.net.URL;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.NoSuchElementException;
-import java.util.Scanner;
-
-public class Gemini {
- public static class DummyManager extends X509ExtendedTrustManager {
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) {
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- }
-
- public static class MalformedResponse extends Exception {
- public MalformedResponse() {}
- public MalformedResponse(String msg) {
- super(msg);
- }
- }
-
- public static class Response implements AutoCloseable {
- private final BufferedReader in;
- private final PrintWriter out;
- private final SSLSocket sock;
-
- private final int code;
- private final String meta;
-
- private Response(PrintWriter out, SSLSocket sock) throws IOException, MalformedResponse {
- var inStream = sock.getInputStream();
- this.in = new BufferedReader(new InputStreamReader(inStream));
- this.out = out;
- this.sock = sock;
-
- var reply = in.readLine();
- if (reply.length() > 1027) {
- throw new MalformedResponse("reply header too long");
- }
-
- var s = new Scanner(new StringReader(reply));
- try {
- code = s.nextInt();
- s.skip(" ");
- meta = s.nextLine();
- } catch (NoSuchElementException e) {
- throw new MalformedResponse();
- }
- }
-
- public int getCode() {
- return code;
- }
-
- public String getMeta() {
- return meta;
- }
-
- public BufferedReader body() {
- return in;
- }
-
- public void close() throws IOException {
- in.close();
- out.close();
- sock.close();
- }
- }
-
- public static SSLSocket connect(String host, int port) throws IOException {
- try {
- var params = new SSLParameters();
- params.setServerNames(Collections.singletonList(new SNIHostName(host)));
-
- var ctx = SSLContext.getInstance("TLS");
- ctx.init(null, new DummyManager[]{new DummyManager()}, new SecureRandom());
- var factory = (SSLSocketFactory) ctx.getSocketFactory();
-
- var socket = (SSLSocket) factory.createSocket(host, port);
- socket.setSSLParameters(params);
- socket.startHandshake();
- return socket;
- }
- catch (NoSuchAlgorithmException | KeyManagementException e) {
- throw new RuntimeException("Unexpected failure", e);
- }
- }
-
- public static Response get(URL url) throws IOException, MalformedResponse {
- int port = url.getPort();
- if (port == -1) {
- port = 1965;
- }
-
- String req = url.toString() + "\r\n";
- return get(url.getHost(), port, req);
- }
-
- public static Response get(String host, int port, String req) throws IOException, MalformedResponse {
- var sock = connect(host, port);
-
- var outStream = sock.getOutputStream();
- var out = new PrintWriter(
- new BufferedWriter(new OutputStreamWriter(outStream)));
-
- out.print(req);
- out.flush();
-
- return new Response(out, sock);
- }
-}
blob - /dev/null
blob + 927d6ec28e9215b8404f4807c36e635eb3d570ea (mode 644)
--- /dev/null
+++ java/com/omarpolo/gemini/Response.java
+package com.omarpolo.gemini;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.Socket;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.NoSuchElementException;
+import java.util.Scanner;
+
+public class Response implements AutoCloseable {
+
+ private final BufferedReader in;
+ private final PrintWriter out;
+ private final SSLSocket sock;
+
+ private final int code;
+ private final String meta;
+
+ public static class DummyManager extends X509ExtendedTrustManager {
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ }
+
+ public static class MalformedResponse extends Exception {}
+
+ public Response(URL url) throws IOException, MalformedResponse {
+ this(url.getHost(), url.getPort(), url.toString() + "\r\n");
+ }
+
+ public Response(String host, int port, String req) throws IOException, MalformedResponse {
+ if (port == -1) {
+ port = 1965;
+ }
+
+ sock = connect(host, port);
+
+ var outStream = sock.getOutputStream();
+ out = new PrintWriter(
+ new BufferedWriter(new OutputStreamWriter(outStream)));
+
+ out.print(req);
+ out.flush();
+
+ var inStream = sock.getInputStream();
+ in = new BufferedReader(new InputStreamReader(inStream));
+
+ var reply = in.readLine();
+
+ if (reply.length() > 1027) {
+ throw new MalformedResponse();
+ }
+
+ var s = new Scanner(new StringReader(reply));
+ try {
+ code = s.nextInt();
+ s.skip(" ");
+ meta = s.nextLine();
+ } catch (NoSuchElementException e) {
+ throw new MalformedResponse();
+ }
+ }
+
+ public SSLSocket connect(String host, int port) throws IOException {
+ try {
+ var params = new SSLParameters();
+ params.setServerNames(Collections.singletonList(new SNIHostName(host)));
+
+ var ctx = SSLContext.getInstance("TLS");
+ ctx.init(null, new DummyManager[]{new DummyManager()}, new SecureRandom());
+ var factory = (SSLSocketFactory) ctx.getSocketFactory();
+
+ var socket = (SSLSocket) factory.createSocket(host, port);
+ socket.setSSLParameters(params);
+ socket.startHandshake();
+ return socket;
+ }
+ catch (NoSuchAlgorithmException | KeyManagementException e) {
+ throw new RuntimeException("Unexpected failure", e);
+ }
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMeta() {
+ return meta;
+ }
+
+ public BufferedReader body() {
+ return in;
+ }
+
+ public void close() throws IOException {
+ in.close();
+ out.close();
+ sock.close();
+ }
+}
blob - 765c96e6315075eb5c60a7ed50d61b5930416cb8
blob + be7aae2769a2bfbb000e20794f4bb33d80f36120
--- src/blog/net_gemini.clj
+++ src/blog/net_gemini.clj
(ns blog.net-gemini
- (:import (com.omarpolo.gemini Gemini)))
+ (:import (com.omarpolo.gemini Response)))
(defn head [host port req]
- (with-open [res (Gemini/get host port (str req "\r\n"))]
+ (with-open [res (Response. host port (str req "\r\n"))]
{:code (.getCode res)
:meta (.getMeta res)}))