- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试编写一个 HTTP 隧道,因为我们希望能够通过我们的 Web 应用程序连接到远程计算机。虽然我知道其中涉及的安全风险,但这是我们愿意做的事情。它不托管在 Internet 上,而是托管在专用网络上,因此风险被认为很低。
基本要求是允许 Java 调试工具通过 servlet 连接到机器。我们有一些客户坚持让开发盒在他们的防火墙一侧,并且由于 java 调试服务器上的返回端口不固定,我们不能简单地要求他们打开一个特定的端口。
代码还不完善。我一直在尝试以双向方式进行通信。
有几个组件。 Eclipse 中的 java 调试连接到的独立服务器。该服务器配置为根据连接的端口知道它的前进方向。因此,如果端口 1166 被命中,它就知道连接到机器 x 上的一个 servlet。
即Eclipse 调试器 --> 调试代理服务器 --> 应用程序 Servlet --> 应用程序 JVM
到目前为止,就我的努力而言,我似乎能够连接,但数据流功能不全。 Eclipse 向 JVM 发送 JDWP-Handshake,JVM 应该用 JDWP-Handshake 回复。我发现当 Eclipse 发送 JDWP-Handshake 时,它被写入调试代理服务器,然后中继到 Servlet,但看起来这在 servlet 中被忽略了。我收到的日志如下:
[INFO] Started Jetty Server
2012-06-18 10:00:53,356 INFO ProxySocket - Connection received, forwarding to tidevwls03:1166 via http://localhost:8080/tunnel/debug-proxy
2012-06-18 10:00:53,361 INFO ProxySocket - Connected to http://localhost:8080/tunnel/debug-proxy
2012-06-18 10:00:53,603 INFO ProxyServlet - Received incoming http connection, attempting to forward to endpoint tidevwls03:1166
2012-06-18 10:00:53,604 INFO ProxyServlet - Connecting to endpoint tidevwls03:1166
2012-06-18 10:00:53,613 INFO StreamProxy - [endpoint-read -> http-write ] beginning proxy transport.
2012-06-18 10:00:53,613 INFO StreamProxy - [http-read -> endpoint-write] beginning proxy transport.
2012-06-18 10:00:53,619 INFO ProxySocket - Response Header: HTTP/1.1 200 OK
2012-06-18 10:00:53,619 INFO ProxySocket - Response Header: Content-Length: 0
2012-06-18 10:00:53,623 INFO ProxySocket - Response Header: Server: Jetty(6.1.22)
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] beginning proxy transport.
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'J'
2012-06-18 10:00:53,624 INFO StreamProxy - [servlet-read -> client-write ] beginning proxy transport.
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'D'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'W'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'P'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] '-'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'H'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'a'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'n'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'd'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 's'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'h'
2012-06-18 10:00:53,624 INFO StreamProxy - [client-read -> servlet-write ] 'a'
2012-06-18 10:00:53,625 INFO StreamProxy - [client-read -> servlet-write ] 'k'
2012-06-18 10:00:53,625 INFO StreamProxy - [client-read -> servlet-write ] 'e'
我想知道我是否需要改变我对此的想法,以便将流分解为多个请求并使用基于 session 的连接。一个请求将成为一个永无止境的下游(即无限响应),然后当客户端发送到 servlet 时,它会每次创建一个新请求。这是让它正常工作的关键吗?
下面是调试代理服务器的代码,它可以独立运行,或者我临时将其配置为在 Jetty 服务器上作为 servlet 运行,以便快速测试周转时间。 (ProxySocket.java)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.List;
import javax.net.SocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProxySocket extends HttpServlet {
private static final Logger logger = Logger.getLogger( ProxySocket.class );
private static final ApplicationContext springContext = new ClassPathXmlApplicationContext( "env-spring/applicationContext*.xml" );
@Override
public void init() throws ServletException {
List<HttpDebugConfig> configs = ( List<HttpDebugConfig> ) springContext.getBean( "DebugProxyHosts" );
for ( HttpDebugConfig config : configs ) {
ProxyServer proxyServer = new ProxyServer( config );
proxyServer.start();
}
}
class ProxyServer extends Thread {
private HttpDebugConfig config;
public ProxyServer( HttpDebugConfig config ) {
this.config = config;
}
public void run() {
ServerSocket ss = null;
StreamProxy streamToTunnel = null;
StreamProxy streamToClient = null;
try {
ss = new ServerSocket( config.getLocalPort() );
Socket inbound = null;
Socket outbound = null;
logger.info( String.format( "Listening for connections on port %d. Proxying to %s:%d", config.getLocalPort(), config.getRemoteHost(), config.getRemotePort() ) );
while ( ( inbound = ss.accept() ) != null ) {
try {
logger.info( String.format( "Connection received, forwarding to %s:%d via %s", config.getRemoteHost(), config.getRemotePort(), config.getProxyUrl() ) );
URL proxy = new URL( config.getProxyUrl() );
outbound = SocketFactory.getDefault().createSocket( proxy.getHost(), proxy.getPort() );
logger.info( String.format( "Connected to %s", config.getProxyUrl() ) );
OutputStream out = outbound.getOutputStream();
BufferedReader in = new BufferedReader( new InputStreamReader( outbound.getInputStream() ) );
writeLine( out, String.format( "POST %s HTTP/1.1", config.getProxyUrl() ) );
writeLine( out, String.format( "Host: http://%s:%s", proxy.getHost(), proxy.getPort() ) );
writeLine( out, "Connection: keep-alive" );
writeLine( out, String.format( "tunnel_host: %s", config.getRemoteHost() ) );
writeLine( out, String.format( "tunnel_port: %s", String.valueOf( config.getRemotePort() ) ) );
writeLine( out, "" );
// read the http response and then we can start tunnelling.
for ( String line = ""; StringUtils.isNotBlank( line = in.readLine() ); ) {
logger.info( String.format( "Response Header: %s", line ) );
}
streamToTunnel = new StreamProxy( "[client-read -> servlet-write ]", inbound.getInputStream(), outbound.getOutputStream() );
streamToClient = new StreamProxy( "[servlet-read -> client-write ]", outbound.getInputStream(), inbound.getOutputStream() );
streamToTunnel.start();
streamToClient.start();
while ( streamToClient.isAlive() || streamToTunnel.isAlive() ) {
try { Thread.sleep( 100 ); } catch ( InterruptedException e ) { }
}
logger.info( String.format( "Shutting down socket-to-%s.", config.getProxyUrl() ) );
} finally {
IOUtils.closeQuietly( inbound );
IOUtils.closeQuietly( outbound );
}
}
} catch ( IOException e ) {
logger.error( String.format( "No longer listening for connections on port %d. Proxying to %s:%d", config.getLocalPort(), config.getRemoteHost(), config.getRemotePort() ), e );
} finally {
if ( ss != null ) {
try { ss.close(); } catch ( Exception e ) { }
}
}
}
private void writeLine( OutputStream out, String msg ) throws IOException {
out.write( String.format( "%s\n", StringUtils.defaultString( msg ) ).getBytes() );
}
}
}
下一段代码是spring配置(/env-spring/applicationContext.xml)。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
">
<util:list id="DebugProxyHosts" list-class="java.util.ArrayList">
<bean class="HttpDebugConfig">
<property name="localPort" value="1166" />
<property name="proxyUrl" value="http://localhost:8080/tunnel/debug-proxy" />
<property name="remoteHost" value="tidevwls03" />
<property name="remotePort" value="1166" />
</bean>
</util:list>
</beans>
配置 bean (HttpDebugConfig.java)。
public class HttpDebugConfig {
private int localPort;
private String remoteHost;
private int remotePort;
private String proxyUrl;
public int getLocalPort() {
return localPort;
}
public void setLocalPort( int localPort ) {
this.localPort = localPort;
}
public String getRemoteHost() {
return remoteHost;
}
public void setRemoteHost( String remoteHost ) {
this.remoteHost = remoteHost;
}
public int getRemotePort() {
return remotePort;
}
public void setRemotePort( int remotePort ) {
this.remotePort = remotePort;
}
public String getProxyUrl() {
return proxyUrl;
}
public void setProxyUrl( String proxyUrl ) {
this.proxyUrl = proxyUrl;
}
}
输入流到输出流的复制器(StreamProxy.java)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
public class StreamProxy extends Thread {
private static final Logger logger = Logger.getLogger( StreamProxy.class );
private InputStream in;
private OutputStream out;
private boolean kill = false;
public StreamProxy( String name, InputStream in, OutputStream out ) {
this.in = in;
this.out = out;
setName( name );
}
@Override
public void interrupt() {
this.kill = true;
super.interrupt();
}
@Override
public void run() {
try {
logger.info( String.format( "%s beginning proxy transport.", getName() ) );
do {
int n = 0;
while ( -1 != ( n = in.read() ) ) {
logger.info( getName() + " '" + ( char ) n + "'" );
out.write( n );
// out.flush();
}
try { Thread.sleep( 1 ); } catch ( Exception e ) { }
} while ( ! kill );
logger.info( String.format( "%s completed proxy transport.", getName() ) );
} catch ( IOException e ) {
logger.error( String.format( "%s Failed to copy from input stream to output stream. Aborting thread.", getName() ), e );
kill = true;
} finally {
IOUtils.closeQuietly( in );
IOUtils.closeQuietly( out );
}
}
}
这部分是Tunnel Servlet (ProxyServlet.java)
import java.io.IOException;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger;
public class ProxyServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger( ProxyServlet.class );
private static final long serialVersionUID = -686421490573011755L;
@Override
protected void service( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
new Runner( request, response ).start();
}
class Runner extends Thread {
private HttpServletRequest request;
private HttpServletResponse response;
public Runner( HttpServletRequest request, HttpServletResponse response ) {
this.request = request;
this.response = response;
}
@Override
public void run() {
Socket endpoint = null;
StreamProxy streamToHttp = null;
StreamProxy streamToEndpoint = null;
String host = StringUtils.defaultIfEmpty( request.getHeader( "tunnel_host" ), "localhost" );
int port = NumberUtils.toInt( request.getHeader( "tunnel_port" ), 8000 );
try {
logger.info( String.format( "Received incoming http connection, attempting to forward to endpoint %s:%d", host, port ) );
logger.info( String.format( "Connecting to endpoint %s:%d", host, port ) );
endpoint = SocketFactory.getDefault().createSocket( host, port );
streamToHttp = new StreamProxy( "[endpoint-read -> http-write ]", endpoint.getInputStream(), response.getOutputStream() );
streamToEndpoint = new StreamProxy( "[http-read -> endpoint-write]", request.getInputStream(), endpoint.getOutputStream() );
streamToHttp.start();
streamToEndpoint.start();
while ( streamToEndpoint.isAlive() || streamToHttp.isAlive() ) {
try { Thread.sleep( 100 ); } catch ( InterruptedException e ) { }
}
logger.info( String.format( "Safely shut down servlet-to-%s:%d proxy.", host, port ) );
} catch ( IOException e ) {
logger.error( String.format( "Shutting down servlet-to-%s:%d proxy.", host, port ), e );
} finally {
if ( streamToHttp != null ) {
streamToHttp.interrupt();
}
if ( streamToEndpoint != null ) {
streamToEndpoint.interrupt();
}
IOUtils.closeQuietly( endpoint );
}
}
}
}
应用容器配置(web.xml)
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>tunnel</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:env-spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Debug Proxy</servlet-name>
<servlet-class>ProxyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Debug Proxy</servlet-name>
<url-pattern>/debug-proxy</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Debug Socket</servlet-name>
<servlet-class>ProxySocket</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Debug Socket</servlet-name>
<url-pattern>/debug-socket</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
最后,我正在使用 maven 构建的 pom.xml。
<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>tunnel</groupId>
<artifactId>tunnel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<version.spring>3.1.1.RELEASE</version.spring>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version>
<configuration>
<webApp>${project.build.directory}/${project.build.finalName}.${project.packaging}</webApp>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- Utilities -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.2</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${version.spring}</version>
</dependency>
</dependencies>
</project>
我使用以下 Maven 目标运行 Jetty 服务器
jetty:stop clean install jetty:run-war
希望您觉得这个小项目很有趣!我期待听到您的想法和意见。
谢谢,斯图尔特
最佳答案
SSH 隧道 - 我的选择 http://en.wikipedia.org/wiki/Tunneling_protocol
ssh -L [bind_address:]port:sshserverhostname:targetmachinehostname port
-L 指定将本地(客户端)主机上的给定端口转发到给定主机 和远程端的端口。这通过分配一个套接字来监听本地端口来工作 端,可选地绑定(bind)到指定的 bind_address。每当连接到此 端口,连接通过安全通道转发,并与主机建立连接 来自远程机器的端口主机端口。端口转发也可以在配置中指定 口粮文件。可以通过将地址括在方括号中来指定 IPv6 地址。 只有 super 用户可以转发特权端口。默认情况下,本地端口绑定(bind)在accor- 与 GatewayPorts 设置共舞。但是,可以使用显式 bind_address 来绑定(bind) 连接到特定地址。 `localhost'' 的 bind_address 表示 listen-
*' 表示该端口 应该可以从所有界面访问。
ing 端口仅供本地使用,而空地址或
关于java - HTTP 隧道 Servlet (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11079816/
是否有任何解决方案/补丁可以使 nginx 与上游的 socks 一起工作? 像这样: server { location / { proxy_pass socks5://ip:port
我的连接隧道有问题。因此,我正在使用两个安装了oracle xe(端口1521)的ubuntu服务器虚拟机,我们将它们称为uvm1和uvm2。我的目标是为两个服务器创建两个隧道,并将端口映射到主机,并
我正在使用 sshd 通过托管 Debian 的远程计算机隧道传输我所有的互联网流量。但是我的互联网连接变得很慢(大约 5 到 10 kbps!)。默认配置有什么问题会导致此问题吗? 提前致谢 最佳答
有没有办法在 OpenStreetMap 上显示所有隧道 + 道路?我正在为旅行制作自行车导航系统。在隧道中,我们丢失了 GPS 位置,因为隧道中没有 GPS 数据。我想知道我的位置进入隧道和离开隧道
我目前正在尝试在 Java 客户端(包括 Netty)和服务器之间实现一个 Http 隧道,所以我想知道是否有任何服务器也基于 Netty 来支持这个隧道,或者我应该构建服务器端我自己? 最佳答案 我
我希望从远程主机通过 SSH 建立一个端口。我希望将此实现为 oclif 插入;我希望用户体验如下所示: laptop$ give-jupyter http://localhost:4040/ lap
我正在寻找一种允许我使用 SSH 隧道连接到 R 中的 MySQL 服务器(而不是文件)的方法;我假设它需要 RCurl 和 RODBC 的组合,但我似乎无法让它正常工作。 我遇到了this post
基本上我想以编程方式通过代理服务器创建 SSL 隧道。我正在使用 openssl 创建 ssl 隧道,我可以创建它,但不确定如何通过代理服务器创建隧道。 最佳答案 快速谷歌搜索给我这个 pytunne
我想设置一个简单的 ssh 隧道,从本地机器到互联网上的机器。 我在用着 ssh -D 8080 -f -C -q -N -p 12122 @ 设置工作正常(我认为)导致 ssh 返回要求我提供的凭据
昨天,我接受了一家公司的 UI 开发面试。重点是面试官问了一个重要问题what is HTTP tunneling . 我从未遇到过有关 javascript、HTML 和 jquery 等 UI 内
对不起,长篇大论,我试图说得一清二楚。 * 一点背景 * 作为项目的一部分,我们需要能够使用远程桌面 (RDP) 从具有有效 IP 地址的服务器访问某些计算机(以下称为客户端)。这些客户端位于 NAT
我尝试了命令 killall ngrok,但我得到'killall' 未被识别为内部或外部命令、可操作程序或批处理文件。 killall 不应该和 ngrok 一起出现吗?我在互联网上找不到任何关于该
我需要连接到特定的 API,但该 API 只接受来 self 的配对服务器的请求。然后将这些信息包含在我们的网站中。 所以基本上我需要连接到服务器,使请求接收到答案并将其传输到我的主机,以便我可以使用
使用虚拟主机而不是部署的 Docker 容器,创建 ssh 隧道以便从我的本地机器访问分隔的机器对我来说是一个正常的工作过程。例如,将我的 psql 客户端连接到我只能从堡垒箱访问的 Postgres
我有一个从 Cloud Foundry 数据库转储数据的脚本,它的工作方式如下: cf ssh -L 33001:db.host:3306 --skip-remote-execution App &
我对以下系统架构有疑问: 假设我们有三台机器: SERVER A SERVER B EXTERNAL A SERVER A 正在提供一些流媒体服务,它在一个未知的网络后面,所以它在指定的端口上打开一个
我想从家庭计算机访问位于防火墙后面的工作计算机。 由于工作防火墙阻止意外的传入连接,我必须打开从工作计算机到家庭计算机的反向 SSH 隧道,如下所示: ssh -R 12345:localhost:2
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我遇到了 SSH 隧道问题,我知道这可能是我的本地端口的权限问题,很可能是 127.0.0.1:3308。但是,我已经以管理员身份运行了我的程序(sudo python3 myprogram.py),
我使用此链接在 centos linux 中创建 ip 隧道 http://www.techonia.com/create-tunnel-interface-linux . 然后我想删除现有的隧道,我
我是一名优秀的程序员,十分优秀!