Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/winhttp/request.c | 73 ++++++++++++++--------------------
dlls/winhttp/winhttp_private.h | 19 ++++++++-
2 files changed, 48 insertions(+), 44 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 7d0f64003d..dacb175fbb 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -3156,33 +3156,16 @@ static DWORD send_bytes( struct netconn *netconn, char *bytes, int len )
return (count == len) ? ERROR_SUCCESS : ERROR_INTERNAL_ERROR;
}
-/* rfc6455 */
-enum opcode
-{
- OPCODE_CONTINUE = 0x00,
- OPCODE_TEXT = 0x01,
- OPCODE_BINARY = 0x02,
- OPCODE_RESERVED3 = 0x03,
- OPCODE_RESERVED4 = 0x04,
- OPCODE_RESERVED5 = 0x05,
- OPCODE_RESERVED6 = 0x06,
- OPCODE_RESERVED7 = 0x07,
- OPCODE_CLOSE = 0x08,
- OPCODE_PING = 0x09,
- OPCODE_PONG = 0x0a,
- OPCODE_INVALID = 0xff,
-};
-
-static enum opcode map_buffer_type( WINHTTP_WEB_SOCKET_BUFFER_TYPE type )
+static enum socket_opcode map_buffer_type( WINHTTP_WEB_SOCKET_BUFFER_TYPE type )
{
switch (type)
{
- case WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE: return OPCODE_TEXT;
- case WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE: return OPCODE_BINARY;
- case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE: return OPCODE_CLOSE;
+ case WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE: return SOCKET_OPCODE_TEXT;
+ case WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE: return SOCKET_OPCODE_BINARY;
+ case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE: return SOCKET_OPCODE_CLOSE;
default:
FIXME("buffer type %u not supported\n", type);
- return OPCODE_INVALID;
+ return SOCKET_OPCODE_INVALID;
}
}
@@ -3194,10 +3177,10 @@ static DWORD send_frame( struct netconn *netconn, WINHTTP_WEB_SOCKET_BUFFER_TYPE
DWORD buflen, BOOL final )
{
DWORD i = 0, j, ret, offset = 2, len = buflen;
- enum opcode opcode = map_buffer_type( type );
+ enum socket_opcode opcode = map_buffer_type( type );
char hdr[14], byte, *mask;
- if (opcode == OPCODE_CLOSE) len += sizeof(status);
+ if (opcode == SOCKET_OPCODE_CLOSE) len += sizeof(status);
hdr[0] = final ? FIN_BIT : 0;
hdr[0] |= opcode;
@@ -3224,7 +3207,7 @@ static DWORD send_frame( struct netconn *netconn, WINHTTP_WEB_SOCKET_BUFFER_TYPE
RtlGenRandom( mask, 4 );
if ((ret = send_bytes( netconn, hdr, offset + 4 ))) return ret;
- if (opcode == OPCODE_CLOSE) /* prepend status code */
+ if (opcode == SOCKET_OPCODE_CLOSE) /* prepend status code */
{
byte = (status >> 8) ^ mask[i++ % 4];
if ((ret = send_bytes( netconn, &byte, 1 ))) return ret;
@@ -3331,34 +3314,39 @@ static DWORD receive_bytes( struct netconn *netconn, char *buf, DWORD len, DWORD
return ERROR_SUCCESS;
}
-static WINHTTP_WEB_SOCKET_BUFFER_TYPE map_opcode( enum opcode opcode )
+static WINHTTP_WEB_SOCKET_BUFFER_TYPE map_opcode( enum socket_opcode opcode, BOOL fragment )
{
switch (opcode)
{
- case OPCODE_TEXT: return WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE;
- case OPCODE_BINARY: return WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE;
- case OPCODE_CLOSE: return WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE;
+ case SOCKET_OPCODE_TEXT:
+ if (fragment) return WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE;
+ return WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE;
+
+ case SOCKET_OPCODE_BINARY:
+ if (fragment) return WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE;
+ return WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE;
+
+ case SOCKET_OPCODE_CLOSE:
+ return WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE;
+
default:
- ERR("opcode %u not handled\n", opcode);
+ FIXME("opcode %u not handled\n", opcode);
return ~0u;
}
}
-static DWORD receive_frame( struct netconn *netconn, DWORD *ret_len, WINHTTP_WEB_SOCKET_BUFFER_TYPE *ret_type )
+static DWORD receive_frame( struct netconn *netconn, DWORD *ret_len, enum socket_opcode *opcode )
{
- WINHTTP_WEB_SOCKET_BUFFER_TYPE type;
DWORD ret, len, count;
- enum opcode opcode;
char hdr[2];
if ((ret = receive_bytes( netconn, hdr, sizeof(hdr), &count ))) return ret;
- if (count != sizeof(hdr) || (hdr[0] & RESERVED_BIT) || (hdr[1] & MASK_BIT))
+ if (count != sizeof(hdr) || (hdr[0] & RESERVED_BIT) || (hdr[1] & MASK_BIT) ||
+ (map_opcode( hdr[0] & 0xf, FALSE ) == ~0u))
{
return ERROR_WINHTTP_INVALID_SERVER_RESPONSE;
}
-
- opcode = hdr[0] & 0xf;
- type = map_opcode( opcode );
+ *opcode = hdr[0] & 0xf;
len = hdr[1] & ~MASK_BIT;
if (len == 126)
@@ -3378,7 +3366,6 @@ static DWORD receive_frame( struct netconn *netconn, DWORD *ret_len, WINHTTP_WEB
}
*ret_len = len;
- *ret_type = type;
return ERROR_SUCCESS;
}
@@ -3387,7 +3374,7 @@ static DWORD socket_receive( struct socket *socket, void *buf, DWORD len, DWORD
{
DWORD count, ret = ERROR_SUCCESS;
- if (!socket->read_size) ret = receive_frame( socket->request->netconn, &socket->read_size, &socket->buf_type );
+ if (!socket->read_size) ret = receive_frame( socket->request->netconn, &socket->read_size, &socket->opcode );
if (!ret) ret = receive_bytes( socket->request->netconn, buf, min(len, socket->read_size), &count );
if (!ret)
{
@@ -3395,7 +3382,7 @@ static DWORD socket_receive( struct socket *socket, void *buf, DWORD len, DWORD
if (!async)
{
*ret_len = count;
- *ret_type = socket->buf_type;
+ *ret_type = map_opcode( socket->opcode, socket->read_size != 0 );
}
}
@@ -3405,7 +3392,7 @@ static DWORD socket_receive( struct socket *socket, void *buf, DWORD len, DWORD
{
WINHTTP_WEB_SOCKET_STATUS status;
status.dwBytesTransferred = count;
- status.eBufferType = socket->buf_type;
+ status.eBufferType = map_opcode( socket->opcode, socket->read_size != 0 );
send_callback( &socket->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, &status, sizeof(status) );
}
else
@@ -3558,8 +3545,8 @@ static DWORD socket_close( struct socket *socket, USHORT status, const void *rea
socket->state = SOCKET_STATE_SHUTDOWN;
}
- if ((ret = receive_frame( netconn, &count, &socket->buf_type ))) goto done;
- if (socket->buf_type != WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE || (count && count > sizeof(socket->reason)))
+ if ((ret = receive_frame( netconn, &count, &socket->opcode ))) goto done;
+ if (socket->opcode != SOCKET_OPCODE_CLOSE || (count && count > sizeof(socket->reason)))
{
ret = ERROR_WINHTTP_INVALID_SERVER_RESPONSE;
goto done;
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 41ada14c0c..4a94375006 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -221,6 +221,23 @@ enum socket_state
SOCKET_STATE_CLOSED = 2,
};
+/* rfc6455 */
+enum socket_opcode
+{
+ SOCKET_OPCODE_CONTINUE = 0x00,
+ SOCKET_OPCODE_TEXT = 0x01,
+ SOCKET_OPCODE_BINARY = 0x02,
+ SOCKET_OPCODE_RESERVED3 = 0x03,
+ SOCKET_OPCODE_RESERVED4 = 0x04,
+ SOCKET_OPCODE_RESERVED5 = 0x05,
+ SOCKET_OPCODE_RESERVED6 = 0x06,
+ SOCKET_OPCODE_RESERVED7 = 0x07,
+ SOCKET_OPCODE_CLOSE = 0x08,
+ SOCKET_OPCODE_PING = 0x09,
+ SOCKET_OPCODE_PONG = 0x0a,
+ SOCKET_OPCODE_INVALID = 0xff,
+};
+
struct socket
{
struct object_header hdr;
@@ -228,7 +245,7 @@ struct socket
enum socket_state state;
struct queue send_q;
struct queue recv_q;
- WINHTTP_WEB_SOCKET_BUFFER_TYPE buf_type;
+ enum socket_opcode opcode;
DWORD read_size;
USHORT status;
char reason[128];
--
2.20.1