锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / HTTPS协议、HTTPS协议开源、HTTPS协议经典代码
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

HTTPS协议、HTTPS协议开源、HTTPS协议经典代码


HTTPS协议就是HTTP+SSL,SSL一般是用OpenSSL实现,HTTPS协议在证书和加密套件基础上实现了一定程度上的数据安全,另外HTTPS协议的网站比HTTP协议的网站权重好评分一些。对于SSL开发,锐英源软件有丰富的经验,对于HTTPS通信相关的代理IP开发也做过,最近看httplib的代码,觉得里面的代码是HTTPS协议经典代码,里面有一些技巧和不常见的函数调用方式,就想注释下自己研究,觉得非常有用,也分享给大家。

CPPHTTPLIB_OPENSSL_SUPPORT是httplib里的SSL预编译宏,这个宏下面的代码就是SSL部分。

本文介绍两段代码,第一段是SSL的创建初始化和释放,第二段是客户端代理IP模式下的请求处理。

第一段SSL的创建初始化和释放:

template <typename U, typename V>
inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex,
                    U SSL_connect_or_accept, V setup) {
  SSL *ssl = nullptr;
  {
    std::lock_guard<std::mutex> guard(ctx_mutex);
    ssl = SSL_new(ctx);//ctx是全局的,所以要lock_guard保护
  }

  if (ssl) {
    set_nonblocking(sock, true);//先设置为非阻塞
    auto bio = BIO_new_socket(static_cast(sock), BIO_NOCLOSE);//显式转换更安全
    BIO_set_nbio(bio, 1);//bio设置为非阻塞
    SSL_set_bio(ssl, bio, bio);//bio和ssl绑定

    if (!setup(ssl) || SSL_connect_or_accept(ssl) != 1) {
      SSL_shutdown(ssl);
      {
        std::lock_guard<std::mutex> guard(ctx_mutex);
        SSL_free(ssl);
      }
      set_nonblocking(sock, false);
      return nullptr;
    }
    BIO_set_nbio(bio, 0);//bio设置为阻塞
    set_nonblocking(sock, false);//sock设置为非阻塞 
  }

  return ssl;
}

inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, socket_t sock,
                       bool shutdown_gracefully) {
  // sometimes we may want to skip this to try to avoid SIGPIPE if we know
  // the remote has closed the network connection
  // Note that it is not always possible to avoid SIGPIPE, this is merely a
  // best-efforts.
  if (shutdown_gracefully) {//优雅关闭
#ifdef _WIN32
    SSL_shutdown(ssl);
#else
    timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
               reinterpret_cast<const void *>(&tv), sizeof(tv));

    auto ret = SSL_shutdown(ssl);
    while (ret == 0) {//非windows还要用循环判断
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      ret = SSL_shutdown(ssl);
    }
#endif
  }

  std::lock_guard<std::mutex> guard(ctx_mutex);
  SSL_free(ssl);//保护下关闭
}

这里面ctx的保护和非阻塞阻塞切换有借鉴意义。

第二段客户端代理IP模式下的请求处理:

inline bool ClientImpl::process_request(Stream &strm, Request &req,
                                        Response &res, bool close_connection,
                                        Error &error) {
  // Send request
  if (!write_request(strm, req, close_connection, error)) { return false; }

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  if (is_ssl()) {
    auto is_proxy_enabled = !proxy_host_.empty() && proxy_port_ != -1;//判断是否开启代理模式
    if (!is_proxy_enabled) {//不是代理模式
      char buf[1];
      if (SSL_peek(socket_.ssl, buf, 1) == 0 &&
          SSL_get_error(socket_.ssl, 0) == SSL_ERROR_ZERO_RETURN) {//灵巧地判断和服务器通信是否正常
        error = Error::SSLPeerCouldBeClosed_;
        return false;
      }
    }
  }
#endif

  // Receive response and headers
  if (!read_response_line(strm, req, res) ||
      !detail::read_headers(strm, res.headers)) {
    error = Error::Read;
    return false;
  }

这里面灵巧地判断和服务器通信是否正常有借鉴意义。

HTTPS协议现在是主流,因为现在服务器的能力都强了,HTTP明文协议在逐渐淘汰。小公司有的买不起证书,HTTPS的配置也比较麻烦,一般不愿意升级到HTTPS。HTTPS好处明显,有资源和精力的站长建议升级到HTTPS上吧。

https协议开源
  
友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内南门附近