2011-07-27 18 views
1

URLホスト/ getdataを持つサーバーに接続する必要がありますか?&ログイン= xxx & pass = xxx & dest = yyy SSLを使用しています。指定されたポートでOpenSSLとのSSL接続

下記のコードスニペットを使用していますが、サーバーからデータを取得できません。

CRYPTO_malloc_init(); 
SSL_library_init(); 
SSL_load_error_strings(); 
ERR_load_BIO_strings(); 
OpenSSL_add_all_algorithms(); 

SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); 
SSL* ssl; 
BIO* bio = BIO_new_ssl_connect(ctx); 

char *host = "host:8888"; 
char *con_protocol = ""; 

const char *REQUEST_PROTO = "GET /getdata?reqtype=generate&login=xxx&pass=xxx&dest=yyy HTTP/1.1\nHost: %s\nAccept: */*\nConnection: keep-alive\n\n"; 

char *con_string = (char*)calloc((strlen(host)+strlen(con_protocol))+1, sizeof(char)); 

strcat(con_string, host); 
strcat(con_string, con_protocol); 

// Failure? 
if (bio == NULL) { 
    printf("Error creating BIO!\n"); 
     ERR_print_errors_fp(stderr); 
    // We need to free up the SSL_CTX before we leave. 
     SSL_CTX_free(ctx); 
     return; 
} 
// Makes ssl point to bio's SSL object. 
BIO_get_ssl(bio, &ssl); 
// Set the SSL to automatically retry on failure. 
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 
printf("connection string : %s\n", con_string); 
BIO_set_conn_hostname(bio, con_string); 

// Same as before, try to connect. 
int y = BIO_do_connect(bio); 
if (y <= 0) { 
    printf("Failed to connect!\nError code : %d\n", y); 
    BIO_free_all(bio); 
    SSL_CTX_free(ctx); 
    return; 
} 

// Now we need to do the SSL handshake, so we can communicate. 
if (BIO_do_handshake(bio) <= 0) { 
    printf("Failed to do SSL handshake!\n"); 
    BIO_free_all(bio); 
    SSL_CTX_free(ctx); 
    return; 
} 

// Create a buffer for grabbing information from the page. 
char buf[1024]; 
memset(buf, 0, sizeof(buf)); 
// Create a buffer for the reqest we'll send to the server 
char send[1024]; 
memset(send, 0, sizeof(send)); 


size_t total_size = strlen(REQUEST_PROTO)+strlen(host); 
int t_size = (int)total_size+1; 
    char *my_buf = malloc(t_size*sizeof(char)); 

    snprintf(my_buf, t_size, REQUEST_PROTO, host); 

    printf("my_buf : %s\n", my_buf); 

    BIO_puts(bio, my_buf); 
    int temp = 0; 
    int begin = 0; 
    char *key_buff = (char *)calloc(32, sizeof(char)); 

    while (1) { 
    int bytes_read = BIO_read(bio, buf, sizeof(buf) - 1); 
     printf("bytes_read == %d\n", bytes_read); 

     if (bytes_read == 0) { 
      break; 
     } 
     else if (bytes_read < 0) { 
      if (!BIO_should_retry(bio)) { 
       printf("\nRead Failed!\n"); 
       BIO_free_all(bio); 
       SSL_CTX_free(ctx); 
       return; 
      } 
     } 
     // We actually got some data, without errors! 
     else { 
      // Null-terminate our buffer, just in case 
      buf[bytes_read] = 0; 
      if ((bytes_read != 0) && (temp)) { 
       for (begin; begin<(bytes_read+begin); begin++) { 
        key_buff[begin] = buf[begin]; 
       } 
      } 
      if (!temp) { 
       temp = bytes_read; 
      } 

     } 
    } 

    BIO_free_all(bio); 
    SSL_CTX_free(ctx); 
    printf("key : %s\n\n", buf); 

私はCURLとの接続をチェックしました。 コマンドを使用しているとき curl --insecure 'https://localhost:8888/getdata?reqtype=generate&login=xxx&pass=xxx&dest=yyy' すべてが機能しますが、コマンドから 'http'を削除すると、アプリケーションと同様に空の応答が得られます。残念ながら、私はBIO_set_conn_hostname()関数に 'http'を追加できません。 いくつかのアイデア何が間違っていますか?

+0

カールのようなHTTPライブラリを使用してあなたのために苦労しない理由はありますか? – duskwuff

答えて

2

あなたは明らかにhttps経由で接続しているので、cURLとしてより高いレベルを使用する方が簡単です(libcurlを使用してプログラムで使用できます)。それ以外の場合は、プロトコルのHTTP部分をすべて自分で処理する必要があります。

これは問題ありません。あなたのBIOがバッファリングされていないという問題があると思います。そのため、BIO_putsを使用してサーバーからデータを取得できないのです。ことを提供する代わりにSSL_writeを(使用する

)とSSL_read()、あなたは(BIO_putsを呼び出してデータを送信することができます)とBIO_gets()、およびBIO_write()とBIO_read()、:この優れたturorialも参照バッファーBIOが作成され、以下のように設定されます。 ...

2つのBIO(SSLの場合は1つ、バッファリングの場合)は問題を解決するはずです。

+0

このチュートリアルは私に多くの助けてくれてありがとう。 – Kamil

+0

問題は、cURLが制御できない場合や問題がある場合があることをHTTPヘッダーに送信することです。特定のヘッダーを必要とするサーバーと通信するアプリケーションを作成する場合、cURLはオプションではありません。 –

関連する問題