2016-12-11 12 views
0

私のコードに問題があります。フェイスブックサーバーにHTTPリクエストを送信しましたが、問題はHTTP/1.1を取得しました301 301 Moved Permanently メッセージ。 私がしたいのは、ヘッダレスポンスリンクに従って、リダイレクトされたページHTMLを返すことです。 また、別のHTTPリクエストを送信しようとしましたが、応答が得られないので、リンク。ソケットを使用したHTTP応答ヘッダーに従う

これは基本的に私がやろうとしているのは、私のユーザとパスワードを使ってfacebookサーバーにHTTPポストリクエストを送信することです。

可能であれば、私に正しい方法で案内してください。 PS:既にRFCを読みましたが、それでもまだ明確ではありません。 お時間をいただきありがとうございます。

私のコード

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <netdb.h> 
#include <iostream> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
using namespace std; 

int main() 
{ 
    int sockid, status; 
    unsigned strSize; 
    ssize_t count; // 

    struct sockaddr_in addr; // struct 
    ssize_t size = sizeof(addr); 

    sockid = socket(PF_INET, SOCK_STREAM, 0); // create socket 

    if(sockid < 0) //if error 
    { 
     cout<<"Cannot create sucket\n"; 
     close(sockid); 
     exit(EXIT_FAILURE); 
    } 
    // access struct 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(80); 
    if(inet_aton("31.13.90.36",&addr.sin_addr) == 0) 
    { 
     cout << "Wrong address"; 
     close(sockid); 
     exit(-1); 
    } 

    status = connect(sockid, (sockaddr*)&addr, sizeof(addr)); // attempt to establish a connection 
    // check 
    if(status < 0) 
    { 
     cout << "failed to establish a connection"; 
     close(sockid); 
     exit(EXIT_FAILURE); 
    } 

    // sending HTTP request 
    char msg[] = "POST /login.php HTTP/1.1\r\n" 
        "HOST: m.facebook.com\r\n" 
        "Content-type: application/x-www-form-urlencoded\r\n" 
        "Content-Length: 147\r\n" 
        "Connection: Keep-Alive\r\n" 
        "\r\n" 
        "lsd=AVp5UV4F&version=1&ajax=0&width=0&pxr=0&gps=0&dimensions=0&m_ts=1481464104&li=KFlNWFL78UFJkrUnTV_sFFDQ&email=Minglixe&pass=test123&login=Log+In"; 



    const int bufSize = 4000;  
    char * buf; 
    buf = new char [bufSize]; 
    //unsigned bufSize = strlen(buf); 
    strSize = strlen(msg); 


    send(sockid, msg, strSize, 0); // send request 

    while((count = recv(sockid, buf, bufSize, 0)) > 0)// receive the request 
    { 
     buf[count] = '\0'; 
     cout << buf << flush; 

    }  

    if(count < 0) 
    { 
     cout << "error" ; 
     exit(EXIT_FAILURE); 
    } 

    delete[] buf; 

    close(sockid); 

} 

答えて

4

あなたは301応答で与えられたリダイレクト先のURLに、別のHTTPリクエスト、GET要求を発行する必要があります。

このソケットを閉じて、新しい要求用の新しいソケットを作成する必要があります。リダイレクトされたURLが同じドメインの場合、HTTP/1.1パイプライニングを実装して、1つのソケットを破って新しいソケットを作成する手間を省くことができますが、それは過剰です。

さらに、301の応答によって、リダイレクトされたリクエストで、Facebookのサーバーがあなたに戻すことを期待するクッキーが与えられるということはほぼ確実です。そうしないと、あなたがしようとしていることのどれもが働く可能性がありません。

残念ながら、ここにはショートカットがなく、即座に満足できるものはありません。これを正しく行うには、HTTP全体を理解し、それに精通している必要があります。 HTTPのための標準的な参照が(そこもRFC 7232RFC 7233RFC 7234RFC 7235RFC 7236RFC 7237だが、私はあなたの特定の目的のためにそれらを必要とは考えていない)RFC 7230RFC 7231で構成されています。ここではそのコピーを貼り付けるのではなく、RFC 7230および7231の権威のあるソースに案内します。

HTTPは実際には複雑ではありませんが、数時間で吸収できるものではありません。 POP3のように。 HTTPの技術仕様を見直して勉強するのに数日を費やす準備をしてください。フル機能のHTTP 1.1クライアントを実装したところ、RFC 2616の前身を使い、クッキーをサポートするHTTP 1.1クライアントをハックアップするのに数ヶ月かかっていました。

さらに、HTTPクライアントがクッキーを処理できるようにするために、クッキーの処理方法の標準的な参照はRFC 6265です。あなたもそれを学ぶ必要があります。

P.S.うまくいけば、リダイレクトされたURLはhttps URLではないか、Facebookはログイン後に暗号化されていない接続でコンテンツを取得することができます。そうでなければ、あなたのプラットフォームのSSLライブラリをプルする必要があります。全体の上に

+0

ありがとうございます!だから私はそれのためのソケットを開く必要があるすべての要求のために?なぜなら、私はこれが正しい方法ではないと思っていました。また、GETリクエストの横に置く必要があるヘッダーパラメータも、301のURLをリダイレクトするようになっています。自動的に応答します。私があなたが上から下に言及したそれらのすべてのものを読むべきですか?また、同じドメインのために私は別のソケットを使用する必要がありますか? – Dota

+0

はい、それがHTTP 1.0の仕組みです。ソケット接続ごとに1つの要求。 301レスポンスは、Location:ヘッダーにリダイレクトされたURLを与えます。そのため、ホスト名を解析して解決し、接続する必要があります。前述のように、HTTP 1.1ではパイプラインが導入されているため、同じホスト名であればリクエストをパイプライン処理できます。これも、私が参照したドキュメントで説明されています。 –

+0

すみませんが、HTTPはすべて平文ですので、ヘッダレスポンスだけを変数に格納してGETリクエストでヘッダを再利用するのは難しいです。何か不足していますか? – Dota

関連する問題