C++发起Https连接请求
需要下载安装openssl
//stdafx.h
#pragma once
#include<iostream>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <iostream>
#include <string>#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")
//https.h
#pragma once
#include"stdafx.h"
#include <unordered_map>
using namespace std;
//class Head
//{
//public:
// string name, value;
// Head(const char*name,const char*value);
// Head(string lines);
// void load_str(string lines);
//};
class Https
{
private:bool is_ok,is_connect;int ResponseCode;
public:std::unordered_map<string, string> ResPons;static bool is_init;void Init();string Url;string Host;string Url_ssl;string request;SSL_CTX * ctx;BIO* bio;Https(string url);int connect();int getResponseCode();void disconnect();void set_headers(string headers);int read(char*buffer, int len);~Https();
};
//https.cpp
#include"https.h"
bool Https::is_init = false;
void Https::Init()
{SSL_library_init();SSL_load_error_strings();OpenSSL_add_all_algorithms();Https::is_init = true;
}
void ConfigureUnsafeSSLContext(SSL_CTX* ctx) {SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
}
Https::Https(string url)
{if (!Https::is_init){Https::Init();}this->ResponseCode = -1;this->is_ok = false;this->is_connect = false;if (url.find("https://", 0) == -1){std::cout << "链接格式不规范" << std::endl;return;}this->is_ok = true;int t1 = url.find("/", 8)-8;if (t1 <= -1)t1 = url.length() - 8;this->Host = url.substr(8, t1);this->Url = url;this->Url_ssl = this->Host;this->Url_ssl.append(":https");this->set_headers("");
}int Https::connect()
{this->is_connect = true;this->ctx = SSL_CTX_new(SSLv23_method());if (!ctx) {std::cerr << "Error creating SSL context\n";ERR_print_errors_fp(stderr);return 1;}// 配置不安全上下文(不验证证书)ConfigureUnsafeSSLContext(ctx);// 创建BIO连接this->bio = BIO_new_ssl_connect(ctx);if (!bio) {std::cerr << "Error creating BIO\n";SSL_CTX_free(ctx);return 1;}// 设置主机和端口BIO_set_conn_hostname(bio,this->Url_ssl.c_str());// 获取SSL指针SSL* ssl = nullptr;BIO_get_ssl(bio, &ssl);SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);// 建立连接if (BIO_do_connect(bio) <= 0) {std::cerr << "Error connecting\n";ERR_print_errors_fp(stderr);BIO_free_all(bio);SSL_CTX_free(ctx);return 1;}// 发送HTTP请求if (BIO_write(bio, request.c_str(), request.length()) <= 0) {std::cerr << "Error writing request\n";ERR_print_errors_fp(stderr);BIO_free_all(bio);SSL_CTX_free(ctx);return 1;}// 读取响应char buffer[1];int bytesRead = 0;string h1="";while ((bytesRead = BIO_read(bio, buffer, sizeof(buffer)))){if (bytesRead < 0) {std::cerr << "Error reading response\n";break;}if (buffer[0] == '\r'){BIO_read(bio, buffer, sizeof(buffer));break;}h1.push_back(buffer[0]);}if (h1.find("HTTP/1.1 ") == -1)this->ResponseCode = 500;h1 = h1.substr(9, h1.find(" OK", 9));sscanf_s(h1.c_str(), "%d", &(this->ResponseCode));for (int i = 0; i < 1000; i++){h1 = "";BIO_read(bio, buffer, sizeof(buffer));if (buffer[0] == '\r'){BIO_read(bio, buffer, sizeof(buffer));break;}h1.push_back(buffer[0]);while ((bytesRead = BIO_read(bio, buffer, sizeof(buffer)))){if (bytesRead < 0) {std::cerr << "Error reading response\n";break;}if (buffer[0] == '\r'){BIO_read(bio, buffer, sizeof(buffer));break;}h1.push_back(buffer[0]);}int sp = h1.find(": ");if (sp == -1)break;string name = h1.substr(0, sp);int sp1= h1.find("\r",sp+2);if (sp1 == -1)sp1 = h1.length() - sp - 2;string value= h1.substr(sp+2, sp1);this->ResPons.insert(std::make_pair(name, value));name.clear();value.clear();}// 清理资源
}int Https::read(char * buffer, int len)
{int bytesRead = BIO_read(bio, buffer, len);return bytesRead;
}
int Https::getResponseCode()
{return this->ResponseCode;
}void Https::disconnect()
{if (!(this->is_connect))return;BIO_free_all(bio);SSL_CTX_free(ctx);EVP_cleanup();
}void Https::set_headers(string headers)
{this->request = "GET ";this->request += this->Url;this->request+=" HTTP/1.1\r\n";this->request += "Host: ";this->request += this->Host.c_str();this->request += "\r\n";this->request += headers;this->request += "\r\n";cout << request << endl;
}Https::~Https()
{this->disconnect();
}
//
//Head::Head(const char * name, const char * value)
//{
// this->name = name;
// this->value = value;
//}
//
//Head::Head(string lines)
//{
// this->load_str(lines);
//}
//
//void Head::load_str(string lines)
//{
// int sp = lines.find(": ");
// if (sp == -1)
// return;
// this->name = lines.substr(0, sp);
// int sp1= lines.find("\r",sp+2);
// if (sp1 == -1)
// sp1 = lines.length() - sp - 2;
// this->value= lines.substr(sp+2, sp1);
//}
//1.cpp
#include"stdafx.h"
#include"https.h"int main() {Https *h = new Https("https://www.baidu.com/");h->connect();std::cout << h->getResponseCode() << std::endl;for (auto it = h->ResPons.begin(); it != h->ResPons.end(); ++it) {std::cout << it->first << ": " << it->second << std::endl;}char t[1024];int len1;while ((len1 = h->read(t, 1024))>0){std::fwrite(t, 1, len1, stdout);}return 0;
}