3

http自動化フレームワークを作成していますが、問題は認証されたhttpで保護された接続との通信です。調査を行った後、既存のクライアントアーキテクチャと簡単に統合できるC#のSslStreamオブジェクトを発見しました。問題は; 特定のWebサーバーとの接続を認証できるにもかかわらず、「GET [website] HTTP / 1.1」コマンドはヘッダーのみを返し、実際のWebページは返さないようです。

Webリクエストを適切に作成していないように感じますが、本当にわかりません。私は午前中ずっと調査を行っていますが、この特定の問題に関する多くのリソースを見つけることができません。これが私のプロジェクトのコードサンプルです。

    private IAsyncResult Request(HttpRequestToken token, ReceiveEvent callback) 
    {
        if (token == null)
            throw new Exception("Error. No request information provided. Aborting operation.");

        //Setup the TCP Information. (_port is set to 443 for SSL purposes)
        var client = new TcpClient(token.Host, _port);

        //Get a handle to a networkstream for writing data.
        var requestStream = new SslStream(client.GetStream(), false, null);

        //Authenticate the request
        requestStream.AuthenticateAsClient(token.Host);

        //Translate the data.
        byte[] sendBuffer = UTF8Encoding.UTF8.GetBytes(token.ToString());

        //NOTE: The results of the above command will look like this:
        //GET [website] HTTP/1.1
        //Host: [host]
        //passive: true
        //Accepts: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        //User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1

        //Send the data.
        requestStream.Write(sendBuffer);

        //Get the string value with a function that just iterates over the stream.
        string val = readStream(requestStream);

        //Breakpoint here, this code is not complete but "functions".
        return null;
    }

基本的に、私のコードの結果は、いくつかのヘッダー情報を含む「HTTP /1.1200OK」を返すだけです。ヘッダー以外のHTMLなどは返されません。

要求に応じて、ここにいくつかの詳細情報があります:

    private string readStream(Stream stream)
    {
        byte[] resultBuffer = new byte[2048];
        string value = "";
        //requestStream.BeginRead(resultBuffer, 0, resultBuffer.Length, new AsyncCallback(ReadAsyncCallback), new result() { buffer = resultBuffer, stream = requestStream, handler = callback, asyncResult = null });
        do
        {
            try
            {
                int read = stream.Read(resultBuffer, 0, resultBuffer.Length);
                value += UTF8Encoding.UTF8.GetString(resultBuffer, 0, read);

                if (read < resultBuffer.Length)
                    break;
            }
            catch { break; }
        } while (true);
        return value;
    }

テストの目的で、私はgoogle android開発者ポータルにアクセスしようとしています(SSLを使用しているため)。これは単にログインページをロードするためのものであり、ページのロード要求以外の情報はこの時点では送信されていません。これが私の正確な要求です。

GET https://accounts.google.com/ServiceLogin HTTP/1.1
Host: accounts.google.com
passive: true
nui: 1
continue: https://market.android.com/publish
followup: https://market.android.com/publish
Accepts: text/html,application/xhtml+xml,application/xml;q=0.9,
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1

これはサーバーの応答です。

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=2592000; includeSubDomains
Set-Cookie: GAPS=1:0bFTJDze2Zz8WL_x3F7-OQfOjEOycg:rG8nLpBEwdG67aU_;Path=/;Expires=Mon, 27-Jan-2014 21:31:48 GMT;Secure;HttpOnly
Set-Cookie: GALX=KaXGmr2TI-I;Path=/;Secure
Cache-control: no-cache, no-store
Pragma: no-cache
Expires: Mon, 01-Jan-1990 00:00:00 GMT
X-Frame-Options: Deny
X-Auto-Login: realm=com.google&args=continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount
Transfer-Encoding: chunked
Date: Sat, 28 Jan 2012 21:31:48 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Server: GSE

私の質問をご覧いただきありがとうございます、ありがとうございます!私からの詳細情報が必要な場合は、喜んでお知らせします。私の間違いはおそらくばかげたフォーマットの問題だと思うので、これ以上の情報が必要になるとは思いませんでした。

繰り返しになりますが、ありがとうございます。

4

2 に答える 2

8

このreadStream関数は、読み取りがフル バッファー未満になると終了します。

ただし、これは現在利用可能なデータがこれ以上ないことを意味します。将来的にはさらに利用できるようになるかもしれません。

stream.Read0 バイトが返されるまで読み取りを停止しないでください。

于 2012-01-28T21:55:02.037 に答える
3

HTTPメッセージを読み取る場合:

  • ヘッダー内にいる場合は、ヘッダーの最後まで(つまり、2つの連続したCRLFシーケンス、つまり空の行に遭遇したとき)読み続ける必要があります。次に、本文の読み取りを開始する必要があります。
  • メッセージ本文にいるとき:
    • ヘッダーがある場合は、Content-Lengthこのヘッダーから予想されるバイト数を読み取るまで読み取りを続ける必要があります。
    • Chunked Transfer Encodingを使用している場合(ここではこれが当てはまりますTransfer-Encoding: chunked)、終了文字を探す必要0があります(ただし、すべてのチャンクを分析して接着する必要があります。これは、次の場合に停止したくないためです。実際のコンテンツには0)が含まれています。

一般に、突然閉じられたTCP接続と、何も送信していない接続を区別する方法はありません。から0バイトを読み取るかどうかにstream.Read関係なく、受信する必要のあるすべてのメッセージがあることを知る唯一の方法は、この分析を行うことです。(チャンク転送エンコーディングを処理すると、独自のライブラリが希望よりも少し軽量になる場合があります。)

于 2012-01-29T18:23:30.297 に答える