Chinaunix首页 | 论坛 | 博客
  • 博客访问: 973163
  • 博文数量: 120
  • 博客积分: 6454
  • 博客等级: 准将
  • 技术积分: 1739
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-28 17:45
文章分类

全部博文(120)

文章存档

2014年(1)

2013年(1)

2012年(11)

2011年(16)

2010年(6)

2009年(11)

2008年(30)

2007年(44)

分类: C/C++

2008-04-27 18:35:10

     通过OpenSSL发送HTTPS请求只需通过一下步骤:
     建立普通socket-->初始化SSL-->将socket与SSL进行关联-->连接SSL-->通过SSL发送请求-->接收https应答-->关闭SSL连接和socket

int getPages(const char* host_addr, const int host_port, const char* pObject)
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 0), &wsaData);
    
    SOCKET sockfd;
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        DebugMsg("Socket Error: %s", strerror(errno));
        return -1;
    }
    
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(host_port);
    server_addr.sin_addr.s_addr = inet_addr(host_addr);
    
    if (connect(sockfd, (struct sockaddr *) (&server_addr), sizeof(struct sockaddr)) == -1)
    {
        DebugMsg("Connect Error:%s", strerror(errno));
        return -1;
    }
    
    SSL *ssl;
    SSL_CTX *ctx;
    // SSL initialize
    SSL_library_init();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL)
    {
        DebugMsg("SSL CTX new failed!");
        return -1;
    }
    
    ssl = SSL_new(ctx);
    if (ssl == NULL)
    {
        DebugMsg("SSL new failed!");
        return -1;
    }
    
    // link socket & SSL
    int ret = SSL_set_fd(ssl, sockfd);
    if (ret == 0)
    {
        DebugMsg("SSL link socket failed!");
        return -1;
    }
    
    RAND_poll();
    while (RAND_status() == 0)
    {
        unsigned short rand_ret = rand() % 65536;
        RAND_seed(&rand_ret, sizeof(rand_ret));
    }
    
    // SSL connect
    ret = SSL_connect(ssl);
    if (ret != 1)
    {
        DebugMsg("SSL connect failed!");
        return -1;
    }
    
    char getRequest[1024];
    sprintf(getRequest, "GET %s HTTP/1.0\r\nHost: %s\r\nCookie: %s\r\n\r\n", pObject, "10.18.4.80", cookie);
    
    // send https request
    int totalsend = 0;
    int requestLen = strlen(getRequest);
    while (totalsend < requestLen)
    {
        int send = SSL_write(ssl, getRequest + totalsend, requestLen - totalsend);
        if (send == -1)
        {
            DebugMsg("SSL send failed!");
        }
        totalsend += send;
        DebugMsg("%d bytes send OK!", totalsend);
    }
    
    // receive https response
    int responseLen = 0;
    int i = 0;
    char buffer[8];
    memset(buffer, 0, 8);
    char returnBuffer[1024];
    memset(returnBuffer, 0, 1024);
    int p = 0;
    while ((responseLen = SSL_read(ssl, buffer, 1)) == 1 && p<1024)
    {
        returnBuffer[p] = buffer[0];
        p++;
        if (i < 4)
        {
            if (buffer[0] == '\r' || buffer[0] == '\n')
                i++;
            else
                i = 0;
        }
    }
    
    DebugMsg("%s", returnBuffer);
    
    // shutdown community 
    ret = SSL_shutdown(ssl);
    if (ret != 1)
    {
        DebugMsg("SSL shutdown failed!");
        return -1;
    }
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    ERR_free_strings();
    closesocket(sockfd);
    WSACleanup();
    return 0;
}

阅读(14667) | 评论(5) | 转发(1) |
给主人留下些什么吧!~~

nkloverene2008-08-28 10:26:17

我在windows下用的,不过我想这个和平台没什么关系。 GET的话应该可以不用cookie值的,去掉就好了,只要知道你GET的东西的相对路径。 至于下载认证,我感觉也没必要,https归根到底也就是一些数据传来传去,只不过数据加密了而已,而这个加密动作,Openssl都帮忙做了。 所以我觉得https的做法和http其实是一样的。

nick198420002008-08-28 09:53:05

我在Linux下用C,采用此方式,不过对方的https似乎不需要我登录,我只要每次GET带有参数的值,就会立即返回。我的感觉是可能第一次需要下载一个认证什么的,不知是不是这要?这个认证又该如何下载呢? 是不是就是这个Cockie中存的东西。

nkloverene2008-08-27 22:06:04

先作登录模拟,得到response后就自己分析出cookie值,以后就用这个咯~

chinaunix网友2008-06-03 10:44:04

FreeEIM 企业即时通讯软件