2

我已经编写了一个代理来拦截我的 tomcat 的 http 请求。

每个请求都会通过我的代理并在到达 tomcat 服务器之前进行一些检查。我通过使用用java编写的TCP/IP绑定端口来做到这一点。

除了文件上传(多部分 POST 表单)提交之外,所有请求(GET 和 POST)都能够成功路由到 tomcat 服务器。

即使我能够获取 TCP/IP 中的所有字节并且能够将数据刷新回 tomcat 服务器,但数据会以某种方式被截断/丢失

在处理文件流内容时,我需要做一些特殊的事情,比如编码等吗?

下面是我的示例代码...


protected void processData(InputStream input, OutputStream output) throws IOException
    {
        // reads a line of text from an InputStream
        StringBuffer data = new StringBuffer("");
        StringBuffer data2 = new StringBuffer("");
        StringBuffer data3 = new StringBuffer("");
        StringBuffer data4 = new StringBuffer("");
        int c;

        try
        {
            while ((c = input.read()) >= 0)
            {
                data.append((char) c);

                // check for an end-of-line character
                if ((c == 0) || (c == 10) || (c == 13))
                {
                    output.write(data.toString().getBytes(), 0, data.length());
                    data4.append(data.toString());
                    data = new StringBuffer();
                    count = 0;
                }
                else
                {
                    if (count > 6)
                    {
                        if (input.available() == 1)
                        {
                            data.append((char) input.read());
                        }
                        data2.append(data.toString());
                        data4.append(data.toString());
                        output.write(data.toString().getBytes(), 0, data
                            .toString().length());
                        data = new StringBuffer();
                    }
                    else
                    {
                        if (count == 6)
                        {
                            if (data.toString().toLowerCase()
                                .indexOf("get /") == 0
                                || data.toString().toLowerCase()
                                    .indexOf("post /") == 0)
                            {
                                count = 0;
                                contentLength = -1;

                                // continue read data(header info)
                                while ((line = readLine(input, data)) != null)
                                {
                                    data = new StringBuffer();

                                // do my own stuff here dealing with headers

                                    if (StringUtils.isBlank(line))
                                    {
data4.append(line);
                                        output.write(line.getBytes(), 0,
                                            line.length());

                                        break;
                                    }

                                    line += "\r\n";
                                    output.write(line.getBytes(), 0,
                                        line.length());
                                    data4.append(line);
                                    output.flush();

                                }
                            }
                            else
                            {
                                if (input.available() == 1)
                                {
                                    data.append((char) input.read());
                                }
                            }
                        }
                        else
                        {
                            if (input.available() == 1)
                            {
                                data.append((char) input.read());
                                output.write(data.toString().getBytes(), 0,
                                    data.toString().length());
                                data4.append(data.toString());
                                data3.append(data.toString());
                                data = new StringBuffer();
                            }
                        }
                    }
                    count++;
                }
                if (processbody)
                    total++;

                if (contentLength > 0 && contentLength == total)
                {
                    log.debug("post data2: "
                        + (data2.toString() != null ? data2.toString() : " "));
                    log.debug("post data3: "
                        + (data3.toString() != null ? data3.toString() : " "));
                    log.debug("post data4: "
                        + (data4.toString() != null ? data4.toString() : " "));
                    output.flush();
                }
            }
        }
        catch (Exception e)
        {
            log.error("Error ", e);
        }
        finally
        {
        }
    }


4

2 回答 2

1

您的代码中有一些缺陷:

  1. 您读取每个bytefromInputStream然后将其转换为 achar并将其附加到字符串生成器。如果流是编码字符,例如中文、希腊语、任何特殊字符,这将无法将流正确解码为可读字符串。或者,如果流是纯二进制或 ascii,则字符串不是存储流的最佳选择。当您提交文件多部分请求时,这很容易发生。

  2. 我不是并发方面的专家(所以我在这里可能会说无意义)但是如果同时有多个连接会发生什么。你应该小心这一点。

据我所知,您想处理 http 请求的标头,因此您没有理由不按照 Alexey Sviridov 的建议使用 servlet 过滤器。您可以实现自己的过滤器来拦截标头并对其进行处理。使用过滤器的好处是您可以让 servlet API 为您解析请求的标头,您无需担心何时读取/写入输入/输出流。

但是,如果您打算拦截请求的标头并决定是否应该将请求传递到您的 tomcat 或 servlet 容器,或者做任何不属于 servlet 能力范围的事情,您应该查看 http 代理库。这是示例:

http://proxies.xhaus.com/java/

以前有一个关于在堆栈溢出时用 Java 编写 HTTP 代理的问题。

遗憾的是,我不想鼓励您编写自己的 http 代理。你需要考虑的问题太多了。

于 2011-02-14T07:45:03.227 回答
0

你这样做太难了。只需读取字节并将它们写入另一端。您不关心字符串或字符串缓冲区或行终止字符。

于 2011-02-14T01:23:59.133 回答