ws:\\不正确' Sec-WebSocket-Accept' C服务器中的标头值

时间:2016-01-04 22:01:28

标签: c websocket

我有一个试图处理websocket握手的C程序。目前,当我发回握手时,我遇到了问题。我相当肯定这与我要么散列或编码Sec-WebSocket-Accept值的方式有关,但是我准备好试着找到它。代码如下。

// function handle_hash
// extracts and processes the hash
char* handle_hash(char *Buff,  size_t BuffSize, int dataCount) {
    char *EncodeHash;
    char *key1, *key2, *key3;
    unsigned char hash[SHA_DIGEST_LENGTH];
    char *testKey = "Sec-WebSocket-Key";
    char *additionalHashData = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    Buff[dataCount] = '\0'; // null terminate the buffer
    key1 = strtok(Buff, "\n");
    key1 = strtok(NULL, "\n");
    while (key2 != NULL) { //find the key to hash
        key2 = strtok(NULL, ":");
        key3 = strtok(NULL, "\n");
        if(strcmp(key2, testKey) == 0) { // if the correct key
            if( key3[(strlen(key3)-1)] =='\r'){
                key3[(strlen(key3)-1)]='\0';
            }
            char key4[200];
            strcpy(key4, key3);
            strcat(key4, additionalHashData);
            SHA1(key4, strlen(key4), hash); //Hash SHA1 to the correct reply value
            EncodeHash= base64(hash, sizeof hash);
            break; //Stop looping 
        }                   
    }   
    return EncodeHash; //success
}

// function base64
// encodes to base64
char *base64(const unsigned char *input, int length) {
    BIO *bmem, *b64;
    BUF_MEM *bptr;
    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);
    BIO_write(b64, input, length);
    BIO_flush(b64);
    BIO_get_mem_ptr(b64, &bptr);
    char *buff = (char *)malloc(bptr->length);
    memcpy(buff, bptr->data, bptr->length-1);
    buff[bptr->length-1] = 0;
    BIO_free_all(b64);
    return buff;
}

// function send_handshake
// sends the properly formatted response 
void send_handshake(int connfd, char *Buff,  int BuffSize, unsigned char *hash) {
    memset(Buff, 0, BuffSize); //clear the memory for the buffer
    char *data, *newLine;

    data = "HTTP/1.1 101 Switching Protocols\r\nSec-WebSocket-Accept: ";
    newLine = "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n\r\n";
    int dataCount =0;
    size_t lengVal = 0; 

    lengVal =strlen(data);
    memcpy(&Buff[dataCount], data, lengVal);
    dataCount =lengVal+ dataCount;

    lengVal =strlen(hash);
    memcpy(&Buff[dataCount], hash, lengVal);
    dataCount =lengVal+ dataCount;

    lengVal =strlen(newLine);
    memcpy(&Buff[dataCount], newLine, lengVal);
    dataCount =lengVal+ dataCount;

    int sentamount=send(connfd, Buff, dataCount, 0);
    fprintf(stdout, "handshake sent:\n%s\n", Buff); //Print out what you sent
}

我的代码输出如下:

connection opened
Received data GET /echo HTTP/1.1
Host: 192.168.6.247:5000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://192.168.6.247
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: PHPSESSID=lrmnl9ifh9qprlfn0br4m3tlg7
Sec-WebSocket-Key: 53tUrnM3muD9KznSNCUs/g==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits


handshake sent:
HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Accept: cUEcH+H7VbbhpJ1VaVZvBNlhNi0=
Upgrade: websocket
Connection: Upgrade

如果你们都需要剩下的代码,我可以发布它。

我从发送方控制台获得的错误是

failed: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

我仍然是C的新手,对套接字来说非常新,所以欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

发现了这个问题。当我解析Sec-WebSocket-Key值时,我忘记在值之前删除空格。因此,当我进行哈希和编码时,我最终得到了错误的答案。为了解决这个问题,我添加了key3 ++; strcpy之前(key4,key3);这一切现在都有效。

谢谢!