基于nghttp2的apns HTTP2 C++ 测试程序

这是一个关于如何利用nghttp2库进行Apple Push Notification Service (APNS)的HTTP2协议测试的C++程序,结合了openssl库进行安全连接。
摘要由CSDN通过智能技术生成

http2 nghttp2 apns openssl 测试程序, 版权所有! 不得转载!

http://blog.csdn.net/ll352071639/article/details/77868482

/*
 * nghttp2 - HTTP/2 C Library
 http://write.blog.csdn.net/postedit/77868482
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */

#include <inttypes.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif /* HAVE_NETDB_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>

#include <linux/sockios.h> //ioctl
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/resource.h>
#include <poll.h>
#include <memory.h>

#include <netdb.h>

#include <nghttp2/nghttp2.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/conf.h>

#ifdef NGHTTP2_NORETURN
#define NGHTTP2_NORETURN
#endif

enum { IO_NONE, WANT_READ, WANT_WRITE };

#define MAKE_NV(NAME, VALUE)                                                   \
  {                                                                            \
    (uint8_t *)NAME, (uint8_t *)VALUE, strlen(NAME), strlen(VALUE),    \
        NGHTTP2_NV_FLAG_NONE                                                   \
  }

#define MAKE_NV_CS(NAME, VALUE)                                                \
  {                                                                            \
    (uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE),        \
        NGHTTP2_NV_FLAG_NONE                                                   \
  }




static void deflate(nghttp2_hd_deflater *deflater,
                    nghttp2_hd_inflater *inflater, const nghttp2_nv *const nva,
                    size_t nvlen);

static int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
                                size_t inlen, int final);

int hpackInit(nghttp2_hd_deflater *deflater, nghttp2_hd_inflater *inflater) 
{
  int rv;

  rv = nghttp2_hd_deflate_new(&deflater, 4096);

  if (rv != 0) {
    fprintf(stderr, "nghttp2_hd_deflate_init failed with error: %s\n",
            nghttp2_strerror(rv));
    exit(EXIT_FAILURE);
  }

  rv = nghttp2_hd_inflate_new(&inflater);

  if (rv != 0) {
    fprintf(stderr, "nghttp2_hd_inflate_init failed with error: %s\n",
            nghttp2_strerror(rv));
    exit(EXIT_FAILURE);
  }

  return 0;
}


int hpackUnInit(nghttp2_hd_deflater *deflater, nghttp2_hd_inflater *inflater) 
{
	nghttp2_hd_inflate_del(inflater);
	nghttp2_hd_deflate_del(deflater);
}

static void deflate(nghttp2_hd_deflater *deflater,
                    nghttp2_hd_inflater *inflater, const nghttp2_nv *const nva,
                    size_t nvlen) {
  ssize_t rv;
  uint8_t *buf;
  size_t buflen;
  size_t outlen;
  size_t i;
  size_t sum;

  sum = 0;

  for (i = 0; i < nvlen; ++i) {
    sum += nva[i].namelen + nva[i].valuelen;
  }

  printf("Input (%zu byte(s)):\n\n", sum);

  for (i = 0; i < nvlen; ++i) {
    fwrite(nva[i].name, 1, nva[i].namelen, stdout);
    printf(": ");
    fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
    printf("\n");
  }

  buflen = nghttp2_hd_deflate_bound(deflater, nva, nvlen);
  buf = malloc(buflen);

  rv = nghttp2_hd_deflate_hd(deflater, buf, buflen, nva, nvlen);

  if (rv < 0) {
    fprintf(stderr, "nghttp2_hd_deflate_hd() failed with error: %s\n",
            nghttp2_strerror((int)rv));

    free(buf);

    exit(EXIT_FAILURE);
  }

  outlen = (size_t)rv;

  printf("\nDeflate (%zu byte(s), ratio %.02f):\n\n", outlen,
         sum == 0 ? 0 : (double)outlen / (double)sum);

  for (i = 0; i < outlen; ++i) {
    if ((i & 0x0fu) == 0) {
      printf("%08zX: ", i);
    }

    printf("%02X ", buf[i]);

    if (((i + 1) & 0x0fu) == 0) {
      printf("\n");
    }
  }

  printf("\n\nInflate:\n\n");

  /* We pass 1 to final parameter, because buf contains whole deflated
     header data. */
  rv = inflate_header_block(inflater, buf, outlen, 1);

  if (rv != 0) {
    free(buf);

    exit(EXIT_FAILURE);
  }

  printf("\n-----------------------------------------------------------"
         "--------------------\n");

  free(buf);
}

int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
                         size_t inlen, int final) {
  ssize_t rv;

  for (;;) {
    nghttp2_nv nv;
    int inflate_flags = 0;
    size_t proclen;

    rv = nghttp2_hd_inflate_hd(inflater, &nv, &inflate_flags, in, inlen, final);

    if (rv < 0) {
      fprintf(stderr, "inflate failed with error code %zd", rv);
      return -1;
    }

    proclen = (size_t)rv;

    in += proclen;
    inlen -= proclen;

    if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
      fwrite(nv.name, 1, nv.namelen, stderr);
      fprintf(stderr, ": ");
      fwrite(nv.value, 1, nv.valuelen, stderr);
      fprintf(stderr, "\n");
    }

    if (inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
      nghttp2_hd_inflate_end_headers(inflater);
      break;
    }

    if ((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && inlen == 0) {
      break;
    }
  }

  return 0;
}

struct Connection {
  SSL *ssl;
  nghttp2_session *session;
  /* WANT_READ if SSL/TLS connection needs more input; or WANT_WRITE
     if it needs more output; or IO_NONE. This is necessary because
     SSL/TLS re-negotiation is possible at any time. nghttp2 API
     offers similar functions like nghttp2_session_want_read() and
     nghttp2_session_want_write() but they do not take into account
     SSL/TSL connection. */
  int want_io;
};

struct Request {
  char *host;
  /* In this program, path contains query component as well. */
  char *path;
  /* This is the concatenation of host and port with ":" in
     between. */
  char *hostport;
  /* Stream ID for this request. */
  int32_t stream_id;
  uint16_t port;


  struct Connection *connect;
};

struct URI {
  const char *host;
  /* In this program, path contains query component as well. */
  const char *path;
  size_t pathlen;
  const char *hostport;
  size_t hostlen;
  size_t hostportlen;
  uint16_t port;
};

/*
 * Returns copy of string |s| with
kingate代理服务器说明 kingate代理服务器,受GPL协议保护,官方站点:http://sourceforge.net/projects/kingate/。 支持http,https,socks,ftp,pop3,smtp,dns,telnet代理。 客户端的设置及用法同wingate一样,可以上网查一下资料。 配置文件conf/kingate.conf 具体意思,配置文件有说明。 1:下载. http://sourceforge.net/projects/kingate/ 如果你是windows版本请看第8项. 2:解压 tar xzf kingate-xxxxx.tar.gz cd kingate 3:安装 ./configure --prefix=安装目录 如:./configure --prefix=/tmp/kingate make install 4:使用 prefix/bin/kingate 启动kingate prefix/bin/kingate -f 强行启动kingate,如果启动kingate提示有一个在运行,而你又确实kingate没有运行,可以使用这个。 prefix/bin/kingate -h 查看kingate用法 prefix/bin/kingate -q 关闭kingate prefix/bin/kingate -v 查看kingate版本 prefix/bin/kingate -d # 以调试方式运行程序。#为调试级别,(0-3)。数字越高显示信息也越多。 5:配置 kingate配置文件是etc/kingate.conf,打开这个文件,里面有详细的说明及用法. 6:关于Bug 请访问:http://sourceforge.net/tracker/?group_id=54802&atid=474891,说明bug的现象,及重现办法,以及kingate的版本号。注意,如果kingate在退出时产生了core文件,这很好, 使用: gdb prefix/bin/kingate core文件 再输入:bt 把显示的信息也帖上去. 7:关于dnsproxy 专门代理dns服务请求,请用root用户指行此程序. 8.windows用户 解压: 使用winzip或winrar之类的解压工具。 安装 c:\>prefix\bin\kingate --install c:\>prefix\bin\kingate -z 反安装 c:\>prefix\bin\kingate --uninstall 启动kingate代理 c:\>net start kingate 停止kingate代理 c:\>net stop kingate 启动dns代理: c:\>prefix\bin\dnsproxy.exe -h use_dns_host -b bindaddr -m max_thread 9.kingate教程 请看doc/manual.zh文件 有任何问题请访问(http://sourceforge.net/projects/kingate/)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值