2

Tomcat の http 要求をインターセプトするためのプロキシを 1 つ作成しました。

すべてのリクエストはプロキシを通過し、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. byteからそれぞれを読み取り、InputStreamそれを a にキャストして、char文字列ビルダーに追加します。ストリームがエンコードされた文字 (中国語、ギリシャ語、その他の特殊文字など) である場合、ストリームを読み取り可能な文字列に適切にデコードできません。または、ストリームが純粋なバイナリまたは ascii の場合、文字列はストリームを保存するのに最適ではありません。これは、ファイル マルチパート リクエストを送信するときに簡単に発生する可能性があります。

  2. 私は同時実行の専門家ではありません (そのため、ここでは無意味なことを言っている可能性があります) が、同時に複数の接続がある場合はどうなるでしょうか。これには気をつけなければなりません。

私が見たところ、http リクエストのヘッダーを処理したいので、Alexey Sviridov が提案したようにサーブレット フィルターを使用しない理由はありません。独自のフィルターを実装して、ヘッダーをインターセプトし、それで何かを行うことができます。フィルターを使用する利点は、要求されたヘッダーをサーブレット API に解析させることができ、入力/出力ストリームをいつ読み書きするかについて心配する必要がないことです。

ただし、リクエストのヘッダーをインターセプトし、リクエストを tomcat コンテナーまたはサーブレット コンテナーに渡すかどうかを決定する場合、またはサーブレット機能の範囲外のことを行う場合は、http プロキシ ライブラリを確認する必要があります。次に例を示します。

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

スタック オーバーフロー時に Java で HTTP プロキシを記述することについて、以前に質問があります。

残念ながら、独自の http プロキシを作成することはお勧めしません。考慮しなければならない懸念事項が多すぎます。

于 2011-02-14T07:45:03.227 に答える
0

あなたはこれを非常に難しい方法でやっています。バイトを読み取って反対側に書き込むだけです。文字列、文字列バッファー、または行末文字は気にしません。

于 2011-02-14T01:23:59.133 に答える