http.sys: Allow receiving entity body data.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6360ea8932
commit
9200897849
|
@ -411,9 +411,9 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
const struct http_receive_request_params params
|
const struct http_receive_request_params params
|
||||||
= *(struct http_receive_request_params *)irp->AssociatedIrp.SystemBuffer;
|
= *(struct http_receive_request_params *)irp->AssociatedIrp.SystemBuffer;
|
||||||
DWORD irp_size = (params.bits == 32) ? sizeof(struct http_request_32) : sizeof(struct http_request_64);
|
DWORD irp_size = (params.bits == 32) ? sizeof(struct http_request_32) : sizeof(struct http_request_64);
|
||||||
|
ULONG cooked_len, host_len, abs_path_len, query_len, chunk_len = 0, offset, processed;
|
||||||
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
||||||
const DWORD output_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
const DWORD output_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
ULONG cooked_len, host_len, abs_path_len, query_len, chunk_len = 0, offset;
|
|
||||||
const char *p, *name, *value, *host, *abs_path, *query;
|
const char *p, *name, *value, *host, *abs_path, *query;
|
||||||
USHORT unk_headers_count = 0, unk_header_idx;
|
USHORT unk_headers_count = 0, unk_header_idx;
|
||||||
int name_len, value_len, len;
|
int name_len, value_len, len;
|
||||||
|
@ -758,8 +758,10 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
assert(offset == irp->IoStatus.Information);
|
assert(offset == irp->IoStatus.Information);
|
||||||
|
|
||||||
conn->available = FALSE;
|
conn->available = FALSE;
|
||||||
memmove(conn->buffer, conn->buffer + conn->req_len, conn->len - conn->req_len);
|
processed = conn->req_len - (conn->content_len - chunk_len);
|
||||||
conn->len -= conn->req_len;
|
memmove(conn->buffer, conn->buffer + processed, conn->len - processed);
|
||||||
|
conn->content_len -= chunk_len;
|
||||||
|
conn->len -= processed;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1216,6 +1218,13 @@ static NTSTATUS http_send_response(struct request_queue *queue, IRP *irp)
|
||||||
{
|
{
|
||||||
if (send(conn->socket, response->buffer, response->len, 0) >= 0)
|
if (send(conn->socket, response->buffer, response->len, 0) >= 0)
|
||||||
{
|
{
|
||||||
|
if (conn->content_len)
|
||||||
|
{
|
||||||
|
/* Discard whatever entity body is left. */
|
||||||
|
memmove(conn->buffer, conn->buffer + conn->content_len, conn->len - conn->content_len);
|
||||||
|
conn->len -= conn->content_len;
|
||||||
|
}
|
||||||
|
|
||||||
conn->queue = NULL;
|
conn->queue = NULL;
|
||||||
conn->req_id = HTTP_NULL_ID;
|
conn->req_id = HTTP_NULL_ID;
|
||||||
WSAEventSelect(conn->socket, request_event, FD_READ | FD_CLOSE);
|
WSAEventSelect(conn->socket, request_event, FD_READ | FD_CLOSE);
|
||||||
|
@ -1242,6 +1251,44 @@ static NTSTATUS http_send_response(struct request_queue *queue, IRP *irp)
|
||||||
return STATUS_CONNECTION_INVALID;
|
return STATUS_CONNECTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS http_receive_body(struct request_queue *queue, IRP *irp)
|
||||||
|
{
|
||||||
|
const struct http_receive_body_params *params = irp->AssociatedIrp.SystemBuffer;
|
||||||
|
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
||||||
|
const DWORD output_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
struct connection *conn;
|
||||||
|
NTSTATUS ret;
|
||||||
|
|
||||||
|
TRACE("id %s, bits %u.\n", wine_dbgstr_longlong(params->id), params->bits);
|
||||||
|
|
||||||
|
EnterCriticalSection(&http_cs);
|
||||||
|
|
||||||
|
if ((conn = get_connection(params->id)))
|
||||||
|
{
|
||||||
|
TRACE("%u bits remaining.\n", conn->content_len);
|
||||||
|
|
||||||
|
if (conn->content_len)
|
||||||
|
{
|
||||||
|
ULONG len = min(conn->content_len, output_len);
|
||||||
|
memcpy(irp->AssociatedIrp.SystemBuffer, conn->buffer, len);
|
||||||
|
memmove(conn->buffer, conn->buffer + len, conn->len - len);
|
||||||
|
conn->content_len -= len;
|
||||||
|
conn->len -= len;
|
||||||
|
|
||||||
|
irp->IoStatus.Information = len;
|
||||||
|
ret = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = STATUS_END_OF_FILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = STATUS_CONNECTION_INVALID;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&http_cs);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
||||||
{
|
{
|
||||||
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
||||||
|
@ -1262,6 +1309,9 @@ static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
||||||
case IOCTL_HTTP_SEND_RESPONSE:
|
case IOCTL_HTTP_SEND_RESPONSE:
|
||||||
ret = http_send_response(queue, irp);
|
ret = http_send_response(queue, irp);
|
||||||
break;
|
break;
|
||||||
|
case IOCTL_HTTP_RECEIVE_BODY:
|
||||||
|
ret = http_receive_body(queue, irp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unhandled ioctl %#x.\n", stack->Parameters.DeviceIoControl.IoControlCode);
|
FIXME("Unhandled ioctl %#x.\n", stack->Parameters.DeviceIoControl.IoControlCode);
|
||||||
ret = STATUS_NOT_IMPLEMENTED;
|
ret = STATUS_NOT_IMPLEMENTED;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define IOCTL_HTTP_REMOVE_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, 0)
|
#define IOCTL_HTTP_REMOVE_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, 0)
|
||||||
#define IOCTL_HTTP_RECEIVE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, 0)
|
#define IOCTL_HTTP_RECEIVE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, 0)
|
||||||
#define IOCTL_HTTP_SEND_RESPONSE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, 0)
|
#define IOCTL_HTTP_SEND_RESPONSE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, 0)
|
||||||
|
#define IOCTL_HTTP_RECEIVE_BODY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, 0)
|
||||||
|
|
||||||
struct http_add_url_params
|
struct http_add_url_params
|
||||||
{
|
{
|
||||||
|
@ -49,4 +50,10 @@ struct http_response
|
||||||
char buffer[1];
|
char buffer[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct http_receive_body_params
|
||||||
|
{
|
||||||
|
HTTP_REQUEST_ID id;
|
||||||
|
ULONG bits;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue