当前位置: 首页 > news >正文

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;
}

相关文章:

  • PyQt5基础:QWidget类的全面解析与应用实践
  • 利用多AI协作实现AI编辑器高效开发:创新架构与实践基本构想
  • 【typenum】 1 说明文件(README.md)
  • 【金仓数据库征文】政府项目数据库迁移:从MySQL 5.7到KingbaseES的蜕变之路
  • 数据库故障排查指南大纲
  • Tailwind CSS v4 主题化实践入门(自定义 Theme + 主题模式切换)✨
  • 边缘计算从专家到小白
  • MySQL开篇
  • vscode 中 tasks.json schema
  • 前端面试每日三题 - Day 30
  • AtCoder Beginner Contest 405(CD)
  • Qt中在子线程中刷新UI的方法
  • Day28 -js开发01 -JS三个实例:文件上传 登录验证 购物商城 ---逻辑漏洞复现 及 判断js的payload思路
  • MySQL:视图
  • 前端弹性布局:用Flexbox构建现代网页的魔法指南
  • Linux 离线安装 Docker 和 Docker Compose 最新版 的完整指南
  • 微机控制电子式持久蠕变慢应变应力腐蚀试验机
  • MATLAB安装常见问题及解决方案详解(含代码示例)
  • 在 Kubernetes 中使用 Docker 实现 GPU 支持的完整方案
  • Android 13 使能user版本进recovery
  • 母亲节|写给妈妈
  • 外交部发言人就印巴局势升级答记者问
  • 5天完成1000多万元交易额,“一张手机膜”畅销海内外的启示
  • 上海消防全面推行“检查码”,会同相关部门推行“综合查一次”
  • 新村回响:一周城市生活
  • “一嗨租车”陷“五年后扣费”疑云,用户:违章处理莫名消失