Здравствуйте.
Пишу сервер для бота работающий через Webhook. Вот код (только main):
int main()
{
//////////////////////////////////// ssl //////////////////////////////////////////
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
SSL_library_init();
SSL_CTX * sslctx = SSL_CTX_new(TLSv1_2_server_method());
///////////////////////////// read certificate ////////////////////////////////////
if(SSL_CTX_use_certificate_file(sslctx, "cert.pem", SSL_FILETYPE_PEM) <= 0) error_log("use_certificate_file!");
if(SSL_CTX_use_PrivateKey_file(sslctx, "cert.pem", SSL_FILETYPE_PEM) <= 0) error_log("use_PrivateKey_file!");
if(!SSL_CTX_check_private_key(sslctx)) error_log("check_private_key!");
/////////////////////////////////// server ////////////////////////////////////////
int sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0) error_log("descriptor socket!");
int one = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = INADDR_ANY;
s_addr.sin_port = htons(port);
if(bind(sd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0) error_log("binding!");
if(listen(sd, 5) == -1)
{
close(sd);
error_log("listen!");
}
char read_buffer[BREADSIZE] = {0,};
while(1)
{
printf("ROUTER WAIT CONNECTION.\n");
memset(read_buffer, 0, BREADSIZE);
int client = accept(sd, NULL, NULL);
///////////////////////////// ssl socket //////////////////////////////
SSL *ssl = SSL_new(sslctx);
if(SSL_set_fd(ssl, client) == 0) error_log("SSL_set_fd!");
int acc = SSL_accept(ssl);
if(acc <= 0)
{
SSL_free(ssl);
if(close(client) == -1) error_log("close client_2!");
error_log("Not SSL_accept.");
continue;
}
/////////////////////////////// fork ///////////////////////////////////
pid_t fpid;
signal(SIGCHLD, child_kill);
fpid = fork();
/////////////////////////// start child ////////////////////////////////
if(fpid != 0)
{
SSL_free(ssl);
if(close(client) == -1) error_log("close client_pid!");
continue;
}
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////// read header from telegram //////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
int n = SSL_read(ssl, read_buffer, BREADSIZE - 2); // first SSL_read
if(n <= 0)
{
SSL_free(ssl);
if(close(client) == -1) error_log("close client_3!");
printf("Disconnection:%d\n", n);
exit(0);
}
printf("READ_BUFER:%s_END\n\n", read_buffer);
////////////////////////////////////////////////////////////////////////
/////////////////////////// read json data /////////////////////////////
////////////////////////////////////////////////////////////////////////
memset(read_buffer, 0, BREADSIZE);
int m = SSL_read(ssl, read_buffer, BREADSIZE - 2); // second SSL_read
if(m <= 0)
{
SSL_free(ssl);
if(close(client) == -1) error_log("close client_8!");
}
printf("READ_JSON:%s_END\n\n", read_buffer);
//////////////////////////// telegram reply //////////////////////////////
SSL_write(ssl, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 38);
SSL_free(ssl);
if(close(client) == -1) error_log("close client_6!");
exit(0);
} // END while(1)
}
Код работает, но вот в чём вопрос: приходится делать SSL_read два раза. То есть, при первом чтении (first SSL_read) считывается заголовок:
READ_BUFER:POST /55454634:AAEJ2Z930r3oyno6kTA97gWGj2osSUXI HTTP/1.1
Host: 6.129.231.13
Content-Type: application/json
Content-Length: 308
Connection: keep-alive
Accept-Encoding: gzip, deflate
А во-втором (second SSL_read) читаются json-данные:
READ_JSON:{"update_id":33,"message":{"message_id":209,"from": бла-бла"}}_END
Если же делать такой же запрос к серверу с помощью curl'a, то всё читается в первом SSL_read.
Почему так происходит, может кто-нибудь объяснить? Может это особенность работы телеграмма? Или я всё неправильно делаю?
Спасибо.