2011-02-13 2 views
2

내 바람둥이에 대한 HTTP 요청을 가로 채기 위해 하나의 프록시를 작성했습니다.TCP/IP를 사용하여 http 파일 업로드를 가로 채는 중

모든 요청은 내 프록시를 거치며 Tomcat 서버에 도달하기 전에 확인 작업을 수행합니다. 나는 자바로 작성된 TCP/IP를 사용하여 포트를 바인딩함으로써이 작업을 수행하고있다.

모든 요청 (GET 및 POST)은 파일 업로드 (멀티 파트 POST 양식)를 제외한 Tomcat 서버로 성공적으로 라우팅 할 수 있습니다. 내가 TCP/IP에 모든 바이트를 얻을 수 다시 바람둥이 서버에 데이터를 플러시 할 수 있어요 비록

, 어떻게 든 데이터가 잘린지고/

이되어 손실 인코딩 등과 같은 특별한 것들 .. 파일 스트림 내용을 다룰 때해야 할 일이 무엇입니까 ??

아래

 

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'만으로 작업 할 때 (그래서 ** no **'Reader' /'Writer') 인코딩 할 때 문제가되지 않습니다.구체적인 문제에 관해서는 문제를 (다시) 생성하는 가능한 최소 코드 스 니펫을 포함하도록 질문을 업데이트하고 실제 입력 및 출력 바이트의 실제 예를 완성하는 데 도움이됩니다. – BalusC

+1

필터로 구현하지 않는 이유는 무엇입니까? –

+0

@Alexey Sviridov 서블릿 필터에는 몇 가지 제한 사항이 있습니다. 완전히 수신되기 전에 요청 (예 : 공격의 경우)을 삭제하려는 경우 서블릿 필터를 사용하여 요청을 처리 할 수 ​​없습니다. Tomcat에 도달하기 전에 몇 가지 메커니즘을 제공해야합니다. – gigadot

답변

1

코드에서 몇 가지 결함이 있습니다

  1. 당신은 InputStreambyte를 읽고 다음 char에 캐스팅 및 문자열 빌더에 추가합니다. 스트림이 인코딩 된 문자 인 경우 (예 : 중국어, 그리스어, 특수 문자가 있으면 스트림을 읽을 수있는 문자열로 올바르게 디코딩하지 못합니다. 또는 스트림이 순전히 바이너리 또는 ASCII 인 경우 문자열이 스트림을 저장하는 것이 가장 좋습니다. 이것은 파일 다중 요청을 제출할 때 쉽게 발생할 수 있습니다.

  2. 나는 동시성의 전문가가 아니기 때문에 (여기서는 비합리적인 듯하다.) 동시에 하나 이상의 연결이있을 경우 어떻게 될까? 당신은 이것에 관해서 becareful해야합니다. 내가 보는 것과

, 당신은 HTTP 요청의 헤더를 처리 할, 그래서 알렉세이 Sviridov 제안대로 서블릿 필터를 사용하지 않아야 이유가 없다. 독자적인 필터를 구현하여 헤더를 가로 채고 그 헤더로 무언가를 할 수 있습니다. 필터를 사용하면 서블릿 API로 요청한 헤더를 구문 분석 할 수 있으므로 입/출력 스트림을 읽거나 쓸 때 걱정할 필요가 없습니다.

그러나 요청의 헤더를 가로 채서 요청을 Tomcat 또는 서블릿 컨테이너로 전달해야하는지 아니면 서블릿 기능의 범위에 속하지 않는지를 결정하려면 http 프록시 라이브러리.

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

스택 오버 플로우에 앞의 질문에 대한 writting HTTP Proxy in Java 있습니다 : 여기에 예입니다.

유감스럽게도, 나는 당신이 자신의 http 프록시를 작성하도록 장려하고 싶지 않습니다. 당신이 고려해야 할 너무 많은 관심사가 있습니다.

+0

답장을 보내 주셔서 대단히 감사드립니다. 네가 맞습니다. 문제는 바이트를 ** char **로 바꾸기 때문입니다. 내 코드를 변경하여 헤더 부분의 바이트를 읽고 char로만 변환합니다. 나머지는 방금 읽고 쓰는거야. – Venky

+0

코드를 수정하는 데 도움이되지는 않지만 문제는 없습니다. – gigadot

1

당신이 더 어려운 길을 일을하는지 ... 내 샘플 코드입니다. 그냥 바이트를 읽고 상대방에게 쓰십시오. 문자열이나 문자열 버퍼 또는 줄 종료 문자는 신경 쓰지 않습니다.

관련 문제