问题:当我第一次调用bytes = SSL_read(ssl, buf, sizeof(buf));
时,它总是返回-1,但是下一次调用会返回标题等。
你能帮我找一下我的错误吗?
示例请求:
POST /some/page HTTP/1.1
Connection: keep-alive
Content-Type: text/html;charset=UTF-8
Host: example.com
Content-Length: 123 (just for ex.)
<mytag /> <mysecondtag />
创建SSL对象
SSLConnection::SSLConnection(string _server, int _port)
{
int err = 0;
struct sockaddr_in address;
X509* scert;
char* txt;
char buff[4096];
SSL_METHOD *meth;
WORD wVersionRequested;
WSADATA wsaData;
SSLeay_add_ssl_algorithms();
meth = SSLv23_method();
SSL_load_error_strings();
ctx = SSL_CTX_new(meth);
printf("ctx created\n");
if (ctx == NULL) {
bad_ = true;
error_message_ = L"Context is NULL";
return;
}
if (err == -1) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
// Socket initialization and connection to the server.
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
error_message_ = wprintf_s(L"///eRROR EN WSASstartup//%d\n", err);
bad_ = true;
return;
}
sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd == -1) {
bad_ = true;
error_message_ = L"Socket not initialized";
return;
}
memset(&address, '\0', sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(_server.c_str());
address.sin_port = htons(_port);
address.sin_addr.S_un.S_addr = inet_addr(_server.c_str());
err = connect(sd, (struct sockaddr*) &address, sizeof(address));
if (err == -1) {
bad_ = true;
error_message_ = L"Connection not created";
return;
}
// We started the SSL negotiation
ssl = SSL_new(ctx);
if (ssl == NULL) {
bad_ = true;
error_message_ = L"SSL not created";
return;
}
SSL_set_fd(ssl, sd);
// Setting client certificate and key
int res = 0;
res = SSL_use_certificate_file(ssl, "path1", SSL_FILETYPE_PEM);
printf("Cert assigned: %d\n", res);
if (res <= 0) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
res = SSL_use_PrivateKey_file(ssl, "path2", SSL_FILETYPE_PEM);
printf("Key assigned: %d\n", res);
if (res <= 0) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
err = SSL_connect(ssl);
if (err == -1) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
} else printf("SSL Connection established\n");
if (!SSL_CTX_check_private_key(ctx)) {
printf("private key is not valid\r");
}
/* The next two steps are optional */
/* We get the cipher - optional */
// TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
printf("SSL connection using %s\n", SSL_get_cipher(ssl));
cipher = SSL_get_cipher(ssl);
/* We get the Server certificate - optional */
scert = SSL_get_peer_certificate(ssl);
CHK_NULL(scert);
txt = X509_NAME_oneline(X509_get_subject_name(scert), 0, 0);
CHK_NULL(txt);
cert_subject = txt;
OPENSSL_free(txt);
txt = X509_NAME_oneline(X509_get_issuer_name(scert), 0, 0);
CHK_NULL(txt);
cert_issuer = txt;
OPENSSL_free(txt);
X509_free(scert);
}
请求方法
int SSLConnection::request(const char *_request,
map<char *, char *> &_response_headers,
string &_response_body) {
if (bad_) {
bad_ = true;
error_message_ = L"There is no connection";
return -2;
}
// Sending request
printf("Sending request\n");
char buf[100000];
int bytes;
string _tmp_response;
SSL_write(ssl, _request, strlen(_request));
// Reading response
printf("Reading response\n");
int response_size = 0;
bool flag = 0;
int error_count = 0;
while (true) {
Sleep(1000);
bytes = SSL_read(ssl, buf, sizeof(buf));
printf("Bytes: %d\n", bytes);
if (bytes < 0) {
error_count++;
if (error_count > 3) {
bad_ = true;
error_message_ = L"SSL_read: something went wrong!";
printf("SSL_read: something went wrong!\n");
return -1;
}
}
if (bytes == 0) break;
printf("--------- Response (%d)---------\n", bytes);
for (int i = 0; i<bytes; ++i) printf("%c", buf[i]);
printf("\n--------- End response ---------\n");
//if (!flag) flag = 1;
//else {
for (int i = 0; i<bytes; ++i)
_tmp_response += buf[i];
response_size += bytes;
//}
buf[0] = 0;
}
_tmp_response.resize(response_size);
closesocket(sd);
SSL_free(ssl);
SSL_CTX_free(ctx);
return 1;
}