first version, gemini-socks5 proxy

This commit is contained in:
Alexander 2023-08-06 15:28:14 +02:00
parent 8a29583f17
commit 201a39a56b
6 changed files with 493 additions and 0 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true

188
.gitignore vendored Normal file
View File

@ -0,0 +1,188 @@
### Vert.x ###
.vertx/
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
### Intellij+iml ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-buildTool-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-buildTool.properties
fabric.properties
### Intellij+iml Patch ###
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
### Gradle ###
.gradle
/buildTool/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
### NetBeans ###
nbproject/private/
buildTool/
nbbuild/
dist/
nbdist/
.nb-gradle/
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.classpath
.project

32
README.adoc Normal file
View File

@ -0,0 +1,32 @@
= Gemini
image:https://img.shields.io/badge/vert.x-4.4.1-purple.svg[link="https://vertx.io"]
This application was generated using http://start.vertx.io
== Building
To launch your tests:
```
./mvnw clean test
```
To package your application:
```
./mvnw clean package
```
To run your application:
```
./mvnw clean compile exec:java
```
== Help
* https://vertx.io/docs/[Vert.x Documentation]
* https://stackoverflow.com/questions/tagged/vert.x?sort=newest&pageSize=15[Vert.x Stack Overflow]
* https://groups.google.com/forum/?fromgroups#!forum/vertx[Vert.x User Group]
* https://discord.gg/6ry7aqPWXy[Vert.x Discord]
* https://gitter.im/eclipse-vertx/vertx-users[Vert.x Gitter]

137
pom.xml Normal file
View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cx.lehmann.gemini</groupId>
<artifactId>gemini-proxy</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
<vertx.version>4.4.4</vertx.version>
<junit-jupiter.version>5.9.1</junit-jupiter.version>
<main.verticle>cx.lehmann.gemini.gemini_proxy.MainVerticle</main.verticle>
<launcher.class>io.vertx.core.Launcher</launcher.class>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>${launcher.class}</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
<configuration>
<mainClass>io.vertx.core.Launcher</mainClass>
<arguments>
<argument>run</argument>
<argument>${main.verticle}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,102 @@
package cx.lehmann.gemini.gemini_proxy;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetServerOptions;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.PemKeyCertOptions;
import io.vertx.core.net.ProxyOptions;
import io.vertx.core.net.ProxyType;
import io.vertx.core.streams.Pump;
public class MainVerticle extends AbstractVerticle {
private final static Logger log = LoggerFactory.getLogger(MainVerticle.class);
@Override
public void start(Promise<Void> startPromise) throws Exception {
NetServerOptions serverOptions=new NetServerOptions();
NetClientOptions clientOptions=new NetClientOptions();
ProxyOptions proxyOptions=new ProxyOptions();
proxyOptions.setHost("localhost")
.setPort(9150)
.setType(ProxyType.SOCKS5);
clientOptions.setProxyOptions(proxyOptions)
.setTrustAll(true)
.setSsl(true);
NetClient client=vertx.createNetClient(clientOptions);
vertx.exceptionHandler(ex -> {ex.printStackTrace();});
String certPath="c:/temp/cert.pem";
// String certPath="/home/lehmann/gemini-chat/cert.pem";
serverOptions.setPemKeyCertOptions(new PemKeyCertOptions()
.setCertPath(certPath)
.setKeyPath(certPath))
.setSsl(true);
vertx.createNetServer(serverOptions).connectHandler(conn -> {
conn.handler(event -> {
System.out.println(new Date().toString()+" accepted connection:"+conn.remoteAddress());
String line=event.toString("UTF-8");
if(!line.endsWith("\r\n")) {
conn.write("40 format error\r\n");
conn.close();
} else {
String url=line.substring(0, line.length()-2);
if(!url.startsWith("gemini://")) {
conn.write("40 format error\r\n");
conn.close();
}
else {
String url1=url.substring(9);
log.info("url:{}",url1);
int firstSlash=url1.indexOf('/');
String hostname=url1.substring(0,firstSlash);
String path=url1.substring(firstSlash);
client.connect(1965, hostname, res -> {
if(res.succeeded()) {
NetSocket clientConn = res.result();
clientConn.write(url+"\r\n");
Pump pump=Pump.pump(clientConn, conn).start();
clientConn.closeHandler(v -> {
pump.stop();
conn.close();
});
conn.closeHandler(v -> {
pump.stop();
clientConn.close();
});
} else {
log.info("connection failed", res.cause());
conn.write("40 connection error"+res.cause().getMessage()+"\r\n");
conn.close();
}
});
}
}
}
);
}).listen(1965, server -> {
if (server.succeeded()) {
startPromise.complete();
System.out.println("Gemini proxy started on port 1965 at "+new Date().toString());
} else {
server.cause().printStackTrace();
startPromise.fail(server.cause());
}
});
}
}

View File

@ -0,0 +1,23 @@
package cx.lehmann.gemini.gemini_proxy;
//import io.vertx.core.Vertx;
//import io.vertx.junit5.VertxExtension;
//import io.vertx.junit5.VertxTestContext;
//import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Test;
//import org.junit.jupiter.api.extension.ExtendWith;
//@ExtendWith(VertxExtension.class)
public class TestMainVerticle {
// @BeforeEach
// void deploy_verticle(Vertx vertx, VertxTestContext testContext) {
// vertx.deployVerticle(new MainVerticle(), testContext.succeeding(id -> testContext.completeNow()));
// }
//
// @Test
// void verticle_deployed(Vertx vertx, VertxTestContext testContext) throws Throwable {
// vertx.setTimer(10000000, l ->
// testContext.completeNow());
// }
}