Java HTTP 代理

标签 java http proxy deflate

我正在用 Java 编写一个小型代理,基本上挑选出 2 个特定文件并对它们进行一些额外处理。一个 URL 它只是在传递内容之前从内容中获取一些信息。另一个文件我想过滤响应内容,它只是 xml deflate 编码(我想删除一些子元素)。

现在,当我传递所有内容时,代理工作正常。但是,当我尝试过滤 xml 文件时,它实际上并没有将内容发送到客户端???

这是一些代码:

在接受 Socket 连接时产生的 Thread run() 方法中,一旦我确定请求是针对我要过滤的文件,我调用:

filterRaceFile(serverIn, clientOut);     // This won't send content     
//streamHTTPData(serverIn, clientOut, true); // This passes through fine (but all content of course).

这是过滤方法本身:

private void filterRaceFile(InputStream is, OutputStream os) {
    // Pass through headers before using deflate and filtering xml
    processHeader(is, os, new StringBuilder(), new StringBuilder());        

    // Seems to be 1 line left, inflater doesn't like it if we don't do this anyway...?
    try {
        os.write(readLine(is, false).getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }       

    InflaterInputStream inflate = new InflaterInputStream(is);
    DeflaterOutputStream deflate = new DeflaterOutputStream(os);
    int c = 0;
    try {
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document xdoc = db.parse(inflate);
        Node id = xdoc.getElementsByTagName("id").item(0);
        Node msg = xdoc.getElementsByTagName("message").item(0);
        StringBuilder xml_buf = new StringBuilder("<race>\n");

        xml_buf.append("<id>").append(id.getTextContent()).append("</id>\n");
        xml_buf.append("<message>").append(msg.getTextContent()).append("</message>\n");
        xml_buf.append("<boats>\n");

        NodeList allBoats = xdoc.getElementsByTagName("boat");
        int N = allBoats.getLength();

        for (int i = 0; i < N; ++i)
        {
            Node boat = allBoats.item(i);
            Element boat_el = (Element)boat;                
            double lat = Double.parseDouble(boat_el.getElementsByTagName("lat").item(0).getTextContent());
            double lon = Double.parseDouble(boat_el.getElementsByTagName("lon").item(0).getTextContent());
            double dist = Geodesic.vincenty_earth_dist(proxy.userLat, proxy.userLon, lat, lon)[0];
            if (dist <= LOS_DIST)
            {
                String boatXML = xmlToString(boat);
                //<?xml version="1.0" encoding="UTF-8"?> is prepended to the xml
                int pos = boatXML.indexOf("?>")+2;
                boatXML = boatXML.substring(pos);
                xml_buf.append(boatXML);
                ++c;
            }
        }
        System.out.printf("%d boats within LOS distance\n", c);

        xml_buf.append("</boats>\n");
        xml_buf.append("</race>");

        byte[] xml_bytes = xml_buf.toString().getBytes("UTF-8");
        deflate.write(xml_bytes);

    } catch (Exception e) {
        e.printStackTrace();
    }

    // flush the OutputStream and return
    try {
        os.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }
    }

我还有一个简单的直通方法,它只是将服务器的 InputStream 写入客户端的 OutputStream,也使用 readLine 并且工作正常 - 即浏览器中显示的任何其他 url 都没有问题,所以 readLine 没问题。 boolean 参数是让它知道它正在从 deflate 流中读取,因为它在内部使用标记和读取,这在 deflate 流上不受支持。

XML 非常简单:

<race> 
  {some data to always pass thru}
    <boats>
       <boat>
          <id>1234</id>
          ....
          <lat>-23.3456</lat>
          <lon>17.2345</lon>
       </boat>
       {more boat elements}
     </boats>
   </race>

它生成了我希望它发送给客户端的 xml,但客户端只是没有收到它(在 web 调试器中显示 content-length 为 0,尽管在原始响应)

关于正在发生的事情,或者我应该做但我没有做的事情有什么想法吗??

最佳答案

我没有看到任何错误,但是如果您已经在使用 Document,难道您不能只修改文档然后使用您的 XML 库写出整个文档吗?这似乎比手动 XML 格式化更可靠。

关于Java HTTP 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4939091/

相关文章:

http - 由于来自服务器的 mime 不正确,无法使用 Go 打开 Zip

javascript - 如何验证我所有的 (JavaScript) AJAX 请求? (发送到 Node.js)

java - 在 Hibernate 中重新附加一个对象而不发出 SQL 语句?

Java泛型方法结构解释

JavaFX - 启动画面未显示

html - 如何让浏览器停止缓存服务器响应?

java - Spring AOP 代理没有按预期工作

python-3.x - 无法在企业防火墙后面更新 conda 包。更新了 .condarc 文件,代理设置仍然要求提供代理用户名和密码

java - 如何通过 BlueCoat 代理连接 Java 应用程序?

java - 在嵌套循环中填充数组