top of page

Klient HTTP/1.1 i HTTP/2

Do modułu “base” dodałem podstawową obsługę klienta HTTP/1.1 i HTTP/2, korzystając z szyfrowania TLS zapewnianego przez OpenSSL. Procedura inicjująca połączenie automatycznie negocjuje najwyższy możliwy standard HTTP spośród tych dwóch (nie ma możliwości wyboru).

Kod klienta znajduje się w plikach: “net-cli.cx”, “net-http.cx” i “net-http2.cx”.

Klient realizuje pojedyncze żądanie i wraca z tekstem odpowiedzi znajdującym się w pliku tymczasowym.


Procedura realizacji żądania

Najpierw należy utworzyć kontekst SSL procedurą “E_net_cli_Q_ssl_M”. Następnie połączyć się z serwerem procedurą “E_net_cli_Q_ssl_I_connect”, która wraca z flagą, czy udało się wynegocjować HTTP/2. Wtedy można wysłać żądanie pobrania ścieżki na serwerze przez HTTP/2 procedurą “E_net_http2_I_request” lub przez HTTP/1.1 procedurą “E_net_http_I_request”; zależnie od tego, której wersji wynegocjowano połączenie.

Klient HTTP wykorzystuje ‹raport› “ret” modułu “net”, więc można na niego czekać, oczekując na tekst odpowiedzi. Procedury *“_I_request” otrzymują jako argument procedurę ‘callback’, która jest wywoływana, gdy otrzymano tekst odpowiedzi z serwera. Ta procedura ‘callback’ otrzyma jako argument numer połączenia, a dla HTTP/2 dodatkowo identyfikator strumienia w połączeniu. Procedury ‘callback’ powinny usunąć plik tymczasowy po jego użyciu. Ponadto procedura ‘callback’ połączenia HTTP/1.1 musi zasygnalizować wykonanie, zerując wskaźnik do samej siebie w zmiennej “ret_func” struktury połączenia.

Na końcu można rozłączyć pozostałe połączenia z serwerami i wyrzucić kontekst SSL procedurą “E_net_cli_Q_ssl_W”.


Demonstracyjny kod

N E_main_Q_http_req_ret_count;

void
http_req_ret_func( N connection_i
){  E_main_Q_http_req_ret_count++;
    V0( unlink( E_net_http_S_connect[ connection_i ].file_name ) ){}
    E_net_http_S_connect[ connection_i ].ret_func = 0;
}

void
http2_req_ret_func( N connection_i
, I stream_id
){  E_main_Q_http_req_ret_count++;
    struct E_net_http2_Z_stream *stream = E_mem_Q_tab_R( E_net_http2_S_connect[ connection_i ].stream, stream_id );
    V0( unlink( stream->file_name ) ){}
}

SSL_CTX *ssl_ctx = E_net_cli_Q_ssl_M();
if( !ssl_ctx )
    goto End; // Nie udało się utworzyć kontekstu SSL.
B http2;
N connection = E_net_cli_Q_ssl_I_connect( ssl_ctx, "gentoo", &http2 );
if( !~connection )
    goto Skip; // Nie udało się utworzyć połączenia.
if(http2)
{   N ret = E_net_http2_I_request( connection, "/", http2_req_ret_func );
    if(ret)
        goto Skip; // Nie udało się wysłać ścieżki żądania.
    ret = E_net_http2_I_request( connection, "/", http2_req_ret_func );
    if(ret)
        goto Skip; // Nie udało się wysłać ścieżki żądania.
}else
{   N ret = E_net_http_I_request( connection, "/", http_req_ret_func );
    if(ret)
        goto Skip; // Nie udało się wysłać ścieżki żądania.
}
X_M( net, ret );
E_main_Q_http_req_ret_count = 0;
O{  X_B( net, ret, 0 )
        break;
    if(( http2
      && ( !E_net_http2_S_connect_n
        || E_main_Q_http_req_ret_count == 2 // Zrealizowano dwa połączenia HTTP/2.
      ))
    || ( !http2
      && ( !E_net_http_S_connect_n
        || E_main_Q_http_req_ret_count == 1 // Zrealizowano jedno połączenie HTTP/1.1.
    )))
        break;
}
Skip:
E_net_cli_Q_ssl_W( ssl_ctx );
End:;

W tym programie wykonywane jest dwukrotnie żądanie ścieżki “/”, jeśli połączono przez HTTP/2, a jednokrotnie, jeśli połączono przez HTTP/1.1. Stąd oczekiwanie na licznik zrealizowanych połączeń równy 2 lub 1.


Zewnętrzne wykorzystanie kodu klienta

Plik “net-http2.cx” zawiera procedury obsługi kodowania i inne w protokole HTTP/2, które mogą być wykorzystane w programach i są wykorzystywane w programie serwera ‟OUX/C+ web-srv”.

20 wyświetleń0 komentarzy

Ostatnie posty

Zobacz wszystkie

Duże liczby jakby zmiennoprzecinkowe – math-bignum.cx

Moduł dużych liczb pozwala przechowywać w postaci dwójkowej liczby większe niż liczba naturalna procesora i przeprowadzać na nich obliczenia. Są to liczby bardzo podobne do liczb zmiennoprzecinkowych.

Parser plików tekstowych – text-syntax.cx

W module “base” jest dostępny parser plików tekstowych kodowanych w UTF-8. Do przetworzenia takiego pliku tekstowego są potrzebne dwa pliki: plik opisu składni (zazwyczaj z rozszerzeniem “.syntax”) w

Menedżer plików – mem-file.cx

Menedżer plików obsługuje zarówno losowe jak i strumieniowe czytanie i zapisywanie do pliku. Przechowuje on w pamięci podręcznej dotychczas odczytaną zawartość pliku i w regularnych odstępach czasowyc

bottom of page