http.sys: Assign a unique ID to each request.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
df3e9c8e9a
commit
a6d2335836
|
@ -203,6 +203,8 @@ DECLARE_CRITICAL_SECTION(http_cs);
|
||||||
static HANDLE request_thread, request_event;
|
static HANDLE request_thread, request_event;
|
||||||
static BOOL thread_stop;
|
static BOOL thread_stop;
|
||||||
|
|
||||||
|
static HTTP_REQUEST_ID req_id_counter;
|
||||||
|
|
||||||
struct connection
|
struct connection
|
||||||
{
|
{
|
||||||
struct list entry; /* in "connections" below */
|
struct list entry; /* in "connections" below */
|
||||||
|
@ -212,8 +214,20 @@ struct connection
|
||||||
char *buffer;
|
char *buffer;
|
||||||
unsigned int len, size;
|
unsigned int len, size;
|
||||||
|
|
||||||
|
/* If there is a request fully received and waiting to be read, the
|
||||||
|
* "available" parameter will be TRUE. Either there is no queue matching
|
||||||
|
* the URL of this request yet ("queue" is NULL), there is a queue but no
|
||||||
|
* IRPs have arrived for this request yet ("queue" is non-NULL and "req_id"
|
||||||
|
* is HTTP_NULL_ID), or an IRP has arrived but did not provide a large
|
||||||
|
* enough buffer to read the whole request ("queue" is non-NULL and
|
||||||
|
* "req_id" is not HTTP_NULL_ID).
|
||||||
|
*
|
||||||
|
* If "available" is FALSE, either we are waiting for a new request
|
||||||
|
* ("req_id" is HTTP_NULL_ID), or we are waiting for the user to send a
|
||||||
|
* response ("req_id" is not HTTP_NULL_ID). */
|
||||||
BOOL available;
|
BOOL available;
|
||||||
struct request_queue *queue;
|
struct request_queue *queue;
|
||||||
|
HTTP_REQUEST_ID req_id;
|
||||||
|
|
||||||
/* Things we already parsed out of the request header in parse_request().
|
/* Things we already parsed out of the request header in parse_request().
|
||||||
* These are valid only if "available" is TRUE. */
|
* These are valid only if "available" is TRUE. */
|
||||||
|
@ -406,6 +420,9 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
|
|
||||||
TRACE("Completing IRP %p.\n", irp);
|
TRACE("Completing IRP %p.\n", irp);
|
||||||
|
|
||||||
|
if (!conn->req_id)
|
||||||
|
conn->req_id = ++req_id_counter;
|
||||||
|
|
||||||
/* First calculate the total buffer size needed for this IRP. */
|
/* First calculate the total buffer size needed for this IRP. */
|
||||||
|
|
||||||
if (conn->unk_verb_len)
|
if (conn->unk_verb_len)
|
||||||
|
@ -473,11 +490,13 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
{
|
{
|
||||||
struct http_request_32 *req = irp->AssociatedIrp.SystemBuffer;
|
struct http_request_32 *req = irp->AssociatedIrp.SystemBuffer;
|
||||||
req->ConnectionId = (ULONG_PTR)conn;
|
req->ConnectionId = (ULONG_PTR)conn;
|
||||||
|
req->RequestId = conn->req_id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct http_request_64 *req = irp->AssociatedIrp.SystemBuffer;
|
struct http_request_64 *req = irp->AssociatedIrp.SystemBuffer;
|
||||||
req->ConnectionId = (ULONG_PTR)conn;
|
req->ConnectionId = (ULONG_PTR)conn;
|
||||||
|
req->RequestId = conn->req_id;
|
||||||
}
|
}
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
@ -492,6 +511,7 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
offset = sizeof(*req);
|
offset = sizeof(*req);
|
||||||
|
|
||||||
req->ConnectionId = (ULONG_PTR)conn;
|
req->ConnectionId = (ULONG_PTR)conn;
|
||||||
|
req->RequestId = conn->req_id;
|
||||||
req->UrlContext = conn->queue->context;
|
req->UrlContext = conn->queue->context;
|
||||||
req->Version = conn->version;
|
req->Version = conn->version;
|
||||||
req->Verb = conn->verb;
|
req->Verb = conn->verb;
|
||||||
|
@ -617,6 +637,7 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
|
||||||
offset = sizeof(*req);
|
offset = sizeof(*req);
|
||||||
|
|
||||||
req->ConnectionId = (ULONG_PTR)conn;
|
req->ConnectionId = (ULONG_PTR)conn;
|
||||||
|
req->RequestId = conn->req_id;
|
||||||
req->UrlContext = conn->queue->context;
|
req->UrlContext = conn->queue->context;
|
||||||
req->Version = conn->version;
|
req->Version = conn->version;
|
||||||
req->Verb = conn->verb;
|
req->Verb = conn->verb;
|
||||||
|
@ -906,6 +927,8 @@ static void receive_data(struct connection *conn)
|
||||||
|
|
||||||
if (conn->available)
|
if (conn->available)
|
||||||
return; /* waiting for an HttpReceiveHttpRequest() call */
|
return; /* waiting for an HttpReceiveHttpRequest() call */
|
||||||
|
if (conn->req_id != HTTP_NULL_ID)
|
||||||
|
return; /* waiting for an HttpSendHttpResponse() call */
|
||||||
|
|
||||||
TRACE("Received %u bytes of data.\n", len);
|
TRACE("Received %u bytes of data.\n", len);
|
||||||
|
|
||||||
|
@ -1101,7 +1124,7 @@ static NTSTATUS http_receive_request(struct request_queue *queue, IRP *irp)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(conn, &connections, struct connection, entry)
|
LIST_FOR_EACH_ENTRY(conn, &connections, struct connection, entry)
|
||||||
{
|
{
|
||||||
if (conn->available && conn->queue == queue)
|
if (conn->available && conn->queue == queue && params->id == conn->req_id)
|
||||||
{
|
{
|
||||||
ret = complete_irp(conn, irp);
|
ret = complete_irp(conn, irp);
|
||||||
LeaveCriticalSection(&http_cs);
|
LeaveCriticalSection(&http_cs);
|
||||||
|
@ -1109,9 +1132,14 @@ static NTSTATUS http_receive_request(struct request_queue *queue, IRP *irp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params->id == HTTP_NULL_ID)
|
||||||
|
ret = STATUS_PENDING;
|
||||||
|
else
|
||||||
|
ret = STATUS_CONNECTION_INVALID;
|
||||||
|
|
||||||
LeaveCriticalSection(&http_cs);
|
LeaveCriticalSection(&http_cs);
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
||||||
|
|
Loading…
Reference in New Issue