OpenSSL 偶尔打印随机垃圾
OpenSSL occasionally printing random garbage
我刚开始使用 OpenSSL 来发出 HTTPS 请求。我正在使用 C++。有时,我会得到一个看起来像这样的正确响应:
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 09 Aug 2020 12:14:03 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 159
Connection: keep-alive
Access-Control-Allow-Credentials: true
Vary: Origin
{"status":"success","symbol":"AAPL","last":{"price":446.71,"size":200,"exchange":2,"cond1":14,"cond2":12,"cond3":41,"cond4":0,"timestamp":1596835355456000000}}
有时我会收到如下所示的有问题的响应:(向右滚动)
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 09 Aug 2020 12:14:06 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 159
Connection: keep-alive
Access-Control-Allow-Credentials: true
Vary: Origin
{"status":"success","symbol":"AAPL","last":{"price":446.71,"size":200,"exchange":2,"cond1":14,"cond2":12,"cond3":41,"cond4":0,"timestamp":15968353554560000?????`9??????p???????p?#???????`???????u???????@???????U?????? ??????5??????
我 认为 这个问题与 SSL_read 函数向缓冲区添加东西有关,但我不确定。我知道此问题并非特定于该网站,因为我已尝试向其他网站发出请求并且得到了相同的结果。这是请求方法的代码:
Response* Requests::get(const char* ip_addr, std::string& route, datastructures::hash::HashTable& headers, datastructures::hash::HashTable& parameters){
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server;
server.sin_port = htons(443);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ip_addr);
connect(sock, (struct sockaddr*)&server, sizeof(server));
cout<<SSL_load_error_strings()<<endl;
cout<<SSL_library_init()<<endl;
SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
SSL* conn = SSL_new(ctx);
cout<<SSL_set_fd(conn, sock)<<endl;
cout<<SSL_connect(conn)<<endl;
std::vector<datastructures::hash::Key> params = parameters.getTable();
std::vector<datastructures::hash::Key> heads = headers.getTable();
std::ostringstream os;
os << "GET " << route <<"?";
std::string request = os.str();
os.str("");
{
int i;
for(i=0;i<params.size();i++){
os << params[i].key << "="<< *(std::string*)(params[i].value) << "&";
request+=os.str();
os.str("");
}
request += " HTTP/1.1 \r\n";
request+=os.str();
for(i=0;i<heads.size();i++){
os << heads[i].key << ": " << *(std::string*)(heads[i].value) << "\r\n";
request+=os.str();
os.str("");
}
request += "\r\n";
}
SSL_write(conn, (const char*)request.c_str(), request.size());
std::string ret;
const char* retc = (const char*)malloc(10240*sizeof(char));
int recv = SSL_read(conn, (void *)retc, 10240);
while(true){
ret+=retc;
free((char*)retc);
if(recv < 10240){
break;
} else{
recv = SSL_read(conn, (void *)retc, 10240);
retc = (const char*)malloc(10240*sizeof(char));
}
}
SSL_free(conn);
close(sock);
return new Response(ret);
下面是我在主函数中调用方法的方式:
std::cout << requests::Requests::get("35.186.171.205", route, headers, parameters)->getRawResponse() << std::endl;
//Get raw response is a method in my response class that just returns the raw http response
显示的代码中存在多个错误。
ret+=retc;
这仅在 retc
是普通 char *
时有效,当它指向的字符串以 '[=14=]'
结尾时。 SSL_read
不会做任何类似的事情。您应该使用 std::string
的 append()
重载,它接受一个指针和要添加到此字符串的确切字符数。
free((char*)retc);
// ...
recv = SSL_read(conn, (void *)retc, 10240);
retc = (const char*)malloc(10240*sizeof(char));
这段代码序列:
取消分配 retc
。该指针现在无效。
尝试将某些内容读入 retc
,这不再有效。
分配一个新的 retc
指针。
在读取内容之前应该分配一个新缓冲区。此外,甚至没有必要首先完成所有这些工作。以前用于 SSL_read
某些东西的缓冲区完全可以用于 SSL_read
其他东西。它完全适合这份工作。 free
缓冲区,只是为了再次 malloc
它,绝对没有任何用处。
最后,如果您真的打算编写现代 C++ 代码,则无需 malloc
或 free
任何东西。只需使用 std::vector<char>
并让向量本身为您处理所有内存分配和释放。你很少在现代 C++ 代码中看到手动内存分配和释放,它使用容器正确处理和跟踪所有内存,并自动为你清理它以避免内存泄漏。
只需将所有手动分配内存的实例替换为 std::vector<char>
。
我刚开始使用 OpenSSL 来发出 HTTPS 请求。我正在使用 C++。有时,我会得到一个看起来像这样的正确响应:
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 09 Aug 2020 12:14:03 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 159
Connection: keep-alive
Access-Control-Allow-Credentials: true
Vary: Origin
{"status":"success","symbol":"AAPL","last":{"price":446.71,"size":200,"exchange":2,"cond1":14,"cond2":12,"cond3":41,"cond4":0,"timestamp":1596835355456000000}}
有时我会收到如下所示的有问题的响应:(向右滚动)
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 09 Aug 2020 12:14:06 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 159
Connection: keep-alive
Access-Control-Allow-Credentials: true
Vary: Origin
{"status":"success","symbol":"AAPL","last":{"price":446.71,"size":200,"exchange":2,"cond1":14,"cond2":12,"cond3":41,"cond4":0,"timestamp":15968353554560000?????`9??????p???????p?#???????`???????u???????@???????U?????? ??????5??????
我 认为 这个问题与 SSL_read 函数向缓冲区添加东西有关,但我不确定。我知道此问题并非特定于该网站,因为我已尝试向其他网站发出请求并且得到了相同的结果。这是请求方法的代码:
Response* Requests::get(const char* ip_addr, std::string& route, datastructures::hash::HashTable& headers, datastructures::hash::HashTable& parameters){
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server;
server.sin_port = htons(443);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ip_addr);
connect(sock, (struct sockaddr*)&server, sizeof(server));
cout<<SSL_load_error_strings()<<endl;
cout<<SSL_library_init()<<endl;
SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
SSL* conn = SSL_new(ctx);
cout<<SSL_set_fd(conn, sock)<<endl;
cout<<SSL_connect(conn)<<endl;
std::vector<datastructures::hash::Key> params = parameters.getTable();
std::vector<datastructures::hash::Key> heads = headers.getTable();
std::ostringstream os;
os << "GET " << route <<"?";
std::string request = os.str();
os.str("");
{
int i;
for(i=0;i<params.size();i++){
os << params[i].key << "="<< *(std::string*)(params[i].value) << "&";
request+=os.str();
os.str("");
}
request += " HTTP/1.1 \r\n";
request+=os.str();
for(i=0;i<heads.size();i++){
os << heads[i].key << ": " << *(std::string*)(heads[i].value) << "\r\n";
request+=os.str();
os.str("");
}
request += "\r\n";
}
SSL_write(conn, (const char*)request.c_str(), request.size());
std::string ret;
const char* retc = (const char*)malloc(10240*sizeof(char));
int recv = SSL_read(conn, (void *)retc, 10240);
while(true){
ret+=retc;
free((char*)retc);
if(recv < 10240){
break;
} else{
recv = SSL_read(conn, (void *)retc, 10240);
retc = (const char*)malloc(10240*sizeof(char));
}
}
SSL_free(conn);
close(sock);
return new Response(ret);
下面是我在主函数中调用方法的方式:
std::cout << requests::Requests::get("35.186.171.205", route, headers, parameters)->getRawResponse() << std::endl;
//Get raw response is a method in my response class that just returns the raw http response
显示的代码中存在多个错误。
ret+=retc;
这仅在 retc
是普通 char *
时有效,当它指向的字符串以 '[=14=]'
结尾时。 SSL_read
不会做任何类似的事情。您应该使用 std::string
的 append()
重载,它接受一个指针和要添加到此字符串的确切字符数。
free((char*)retc);
// ...
recv = SSL_read(conn, (void *)retc, 10240);
retc = (const char*)malloc(10240*sizeof(char));
这段代码序列:
取消分配
retc
。该指针现在无效。尝试将某些内容读入
retc
,这不再有效。分配一个新的
retc
指针。
在读取内容之前应该分配一个新缓冲区。此外,甚至没有必要首先完成所有这些工作。以前用于 SSL_read
某些东西的缓冲区完全可以用于 SSL_read
其他东西。它完全适合这份工作。 free
缓冲区,只是为了再次 malloc
它,绝对没有任何用处。
最后,如果您真的打算编写现代 C++ 代码,则无需 malloc
或 free
任何东西。只需使用 std::vector<char>
并让向量本身为您处理所有内存分配和释放。你很少在现代 C++ 代码中看到手动内存分配和释放,它使用容器正确处理和跟踪所有内存,并自动为你清理它以避免内存泄漏。
只需将所有手动分配内存的实例替换为 std::vector<char>
。