Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/http.sys/http.c | 56 +++++++++++++++++++++++++++++++++++++++++--- include/wine/http.h | 7 ++++++ 2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c index 41f9f15bba..91d81400e6 100644 --- a/dlls/http.sys/http.c +++ b/dlls/http.sys/http.c @@ -411,9 +411,9 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp) const struct http_receive_request_params params = *(struct http_receive_request_params *)irp->AssociatedIrp.SystemBuffer; 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); 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; USHORT unk_headers_count = 0, unk_header_idx; int name_len, value_len, len; @@ -758,8 +758,10 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp) assert(offset == irp->IoStatus.Information);
conn->available = FALSE; - memmove(conn->buffer, conn->buffer + conn->req_len, conn->len - conn->req_len); - conn->len -= conn->req_len; + processed = conn->req_len - (conn->content_len - chunk_len); + memmove(conn->buffer, conn->buffer + processed, conn->len - processed); + conn->content_len -= chunk_len; + conn->len -= processed;
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 (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->req_id = HTTP_NULL_ID; 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; }
+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) { 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: ret = http_send_response(queue, irp); break; + case IOCTL_HTTP_RECEIVE_BODY: + ret = http_receive_body(queue, irp); + break; default: FIXME("Unhandled ioctl %#x.\n", stack->Parameters.DeviceIoControl.IoControlCode); ret = STATUS_NOT_IMPLEMENTED; diff --git a/include/wine/http.h b/include/wine/http.h index eb75d8f60e..d8039dea07 100644 --- a/include/wine/http.h +++ b/include/wine/http.h @@ -27,6 +27,7 @@ #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_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 { @@ -49,4 +50,10 @@ struct http_response char buffer[1]; };
+struct http_receive_body_params +{ + HTTP_REQUEST_ID id; + ULONG bits; +}; + #endif