27

我有一个巨大的 Java 应用程序(一个鲜为人知的应用服务器 GNUEnterprise 的客户端)及其源代码,我可以在对其进行一些更改后编译回来。该应用程序大量使用网络,我需要监控每个请求和响应。我可以使用像 Wireshark 这样的嗅探器,但该应用程序通过 SSL 与它的服务器一起工作,因此不知道 SSL 证书的私钥任何嗅探的流量都是毫无用处的。

我该怎么做才能使每个请求和响应都从应用程序本身记录下来?我需要查看所有发送和接收的标头。我不想更改所有负责网络交互的代码。我想要的是放一个代码

Network.setDefaultLogger(myCustomLoggerInstance);

在应用程序开始附近的某个地方,然后在myCustomLoggerInstance做我需要的所有日志记录。

此外,鉴于所有网络操作都是使用URLConnections 进行的,我可以使用 . 获取响应标头con.getHeaderFields()和使用con.getRequestProperties(). 但是为什么没有cookies呢?如何以相同的方式转储发送和接收的 cookie?

编辑:我想要达到的是模仿 RPC 应用程序通过 SSL 与其服务器的通信,例如,使用curl. 为此,我需要获取应用程序网络流量的详细日志。

4

5 回答 5

29

记录所有 SSL 流量的一种快速方法是使用以下命令启动 java:

-Djavax.net.debug=all

或将其设置为系统属性:

System.setProperty("javax.net.debug","all");

振作起来。如果您这样做,标准输出会变得嘈杂!

(*注意:仅记录 SSL 流量和 SSL 调试信息(握手等)。不记录常规套接字。)

于 2014-04-18T20:05:19.823 回答
22

您不能使用日志代理服务器,例如http://www.charlesproxy.com/http://fiddler2.com/吗?Charles Proxy 还可以解码 AMF 请求,Fiddler 是 SSL 拦截的冠军。

IIRC,您可以将系统属性 http.proxyHost 和 http.proxyPort 设置为 127.0.0.1 和 8888,java URLConnections 将通过您的日志代理服务器自动连接,您可以很好地查看 HTTP 流量。

或者,如果打算能够重放通信,请使用 JMeter HTTP 代理,它以适合重放的格式记录。它还内置了对处理 cookie 的支持。

如果应用程序使用了不错的 Web 服务,SoapUI 也有一个监视代理,它拦截您已为其导入 WSDL 的 Web 服务调用。

于 2013-09-03T10:55:46.923 回答
3

我进一步挖掘,显然,HttpURLConnection 带有默认启用的 java.util.logging。

请参阅相关问题: Java:在发送之前显示 HttpURLConnection 的请求以及如何为 java HttpURLConnection 流量启用线路日志记录?

Java.util.logging 是 Sun 在 Java 1.4 中标准化日志提供程序的(失败的)尝试。如果您想避免调整系统属性,可以通过 jul-to-slf4j 模块将其桥接到 SLF4J。

但我仍然更喜欢 Fiddler 或 JMeter 代理:-)

于 2013-09-05T11:29:04.760 回答
2

我只想发布一段您可以在起点使用的代码片段。我没有“全局”记录器,但只需对现有代码进行少量更改,您就可以实现目标。我在标准输出上“记录”,因为您的问题可以分为两部分:从 UrlConnection 获取信息并将其存储以供进一步参考。

此代码记录请求:

public class URLConnectionReader {

  public static void main(String[] args) throws Exception {
  URL oracle = new URL("http://www.google.com/");
  URLConnection yc = oracle.openConnection();

  String headerName = null;
  for (int i = 1; (headerName = yc.getHeaderFieldKey(i)) != null; i++) {
    if (headerName.equals("Set-Cookie")) {
      String cookie = yc.getHeaderField(i);
      System.out.println("Cookie  ::  " + cookie);
    } else {
      System.out.println("Header: "+ yc.getHeaderField(i));
    }
  }

  BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
  String inputLine;
  while ((inputLine = in.readLine()) != null)
    System.out.println(inputLine);
  in.close();
}

}

将所有这些数据保存到一个或多个文件中并不难。如果您认为我正在为您解决问题,我很乐意根据需要使用其他详细信息编辑答案。

于 2013-08-29T21:48:36.667 回答
1

如果你想记录网络流量并且你有 URLConnection 对象,那么问题已经解决了!
如果要在流级别记录,则需要在 I/O 流之上编写一个小包装器并在将所有数据传输到较低的网络层之前记录它们,否则您可以直接使用连接对象来获取所需的信息并记录它们.
要管理 cookie,您应该使用java.net.HttpCookiejava 6 中引入的。您只需创建一个 CookieManager 实例并将其设置为默认 cookie 管理器:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

并且您可以使用它来管理连接 cookie!

于 2013-09-06T17:41:13.970 回答