2011-02-13 58 views
2

我写了一个代理来拦截我的tomcat的http请求。使用TCP/IP拦截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 
     { 
     } 
    } 

 
+0

当您仅使用`InputStream` /`OutputStream`(因此**没有**`Reader` /`Writer`)时,编码是一个非问题。至于具体问题,如果您更新问题以包含尽可能最小的代码片段(重新产生问题),并附有实际输入和输出字节的实例,将会有所帮助。 – BalusC 2011-02-13 05:10:46

+1

为什么不通过过滤器来实现? – 2011-02-13 05:21:59

回答

1

有代码中的一些缺陷:

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

  2. 我不是并发专家(所以我可能会说这里没有意义),但如果有多个连接同时发生会发生什么。你应该谅解这一点。

从我所看到的,你要处理的HTTP请求的报头,所以你不应该使用Servlet过滤器作为阿列克谢·斯维里多夫建议没有理由。你可以实现你自己的过滤器来拦截标题并用它做一些事情。使用过滤器的好处是您可以让servlet API为您解析所请求的标题,并且不需要担心何时读取/写入输入/输出流。然而,如果你打算截取请求头并决定请求是否应该传递到你的tomcat或servlet容器,或者做任何不在servlet能力范围内的东西,你应该看看http代理库。下面是例子:

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

有上堆栈溢出前一个问题关于writting HTTP Proxy in Java

遗憾的是,我不想鼓励你编写自己的http代理。有太多担忧需要考虑。

1

你做这么多艰辛的道路。只需读取字节并将它们写入另一端。您不关心字符串或字符串缓冲区或行终止字符。