我有一个试图处理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的新手,对套接字来说非常新,所以欢迎任何帮助。
答案 0 :(得分:1)
发现了这个问题。当我解析Sec-WebSocket-Key值时,我忘记在值之前删除空格。因此,当我进行哈希和编码时,我最终得到了错误的答案。为了解决这个问题,我添加了key3 ++; strcpy之前(key4,key3);这一切现在都有效。
谢谢!