mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[WININET] Sync with Wine Staging 2.9. CORE-13362
05c23c9 wininet: Use isspaceW() instead of isspace() for WCHARs. f9d1b16 wininet: Return failure when handling http redirect without hostname. 4ca5f42 wininet: Allow to set INTERNET_OPTION_HTTP_DECODING on sessions and connections. 7d8cf31 wininet: Don't use returned read size if read failed in gzip_read. 2952c63 wininet: Get rid of no longer needed get_avail_data from data stream implementations. 295291b wininet: Always use non-blocking reads in HTTP_ReceiveRequestData. fd0ac40 wininet: Get rid of no longer needed blocking_mode_t. 18f9d03 wininet: Get rid of no longer needed BLOCKING_WAITALL. 7eaadab wininet: Merge InternetReadFile and InternetReadFileEx implementations. a546e8a wininet: Reimplemented InternetQueryDataAvailable on top of async_read. 0880874 wininet: Rewrite InternetReadFileEx for http protocol to make use of non-blocking reads. 98bcd00 wininet: Rewrite asynchronous read to try to fill whole buffer and not buffer additional data unless requested. c140a70 wininet: Propagate WSAEWOULDBLOCK from read_http_stream. f42a2cc wininet: Pass blocking mode to HTTPREQ_Read. 67b5677 wininet: Propagate WSAEWOULDBLOCK result from content decoding reads. 36f6387 wininet: Forward InternetGetConnectedState to Ex function. 7b42dc4 wininet: Improved netconn_drain_content. 6caecb6 wininet: Handle query parameters for HTTPS urls in InternetOpenUrlW. e9be490 wininet: Fix some more spec file entries. svn path=/trunk/; revision=74866
This commit is contained in:
parent
25cdf28c16
commit
6e2403e911
7 changed files with 247 additions and 360 deletions
|
@ -1161,7 +1161,8 @@ static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffe
|
|||
return INET_QueryOption(hdr, option, buffer, size, unicode);
|
||||
}
|
||||
|
||||
static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
|
||||
static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read,
|
||||
DWORD flags, DWORD_PTR context)
|
||||
{
|
||||
ftp_file_t *file = (ftp_file_t*)hdr;
|
||||
int res;
|
||||
|
@ -1185,12 +1186,6 @@ static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DW
|
|||
return error;
|
||||
}
|
||||
|
||||
static DWORD FTPFILE_ReadFileEx(object_header_t *hdr, void *buf, DWORD size, DWORD *ret_size,
|
||||
DWORD flags, DWORD_PTR context)
|
||||
{
|
||||
return FTPFILE_ReadFile(hdr, buf, size, ret_size);
|
||||
}
|
||||
|
||||
static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written)
|
||||
{
|
||||
ftp_file_t *lpwh = (ftp_file_t*) hdr;
|
||||
|
@ -1277,7 +1272,6 @@ static const object_vtbl_t FTPFILEVtbl = {
|
|||
FTPFILE_QueryOption,
|
||||
INET_SetOption,
|
||||
FTPFILE_ReadFile,
|
||||
FTPFILE_ReadFileEx,
|
||||
FTPFILE_WriteFile,
|
||||
FTPFILE_QueryDataAvailable,
|
||||
NULL,
|
||||
|
@ -2381,7 +2375,6 @@ static const object_vtbl_t FTPSESSIONVtbl = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -3520,7 +3513,6 @@ static const object_vtbl_t FTPFINDNEXTVtbl = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FTPFINDNEXT_FindNextFileW
|
||||
};
|
||||
|
||||
|
|
|
@ -364,16 +364,9 @@ static WCHAR *get_host_header( http_request_t *req )
|
|||
return ret;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
BLOCKING_ALLOW,
|
||||
BLOCKING_DISALLOW,
|
||||
BLOCKING_WAITALL
|
||||
} blocking_mode_t;
|
||||
|
||||
struct data_stream_vtbl_t {
|
||||
DWORD (*get_avail_data)(data_stream_t*,http_request_t*);
|
||||
BOOL (*end_of_data)(data_stream_t*,http_request_t*);
|
||||
DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,blocking_mode_t);
|
||||
DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,BOOL);
|
||||
BOOL (*drain_content)(data_stream_t*,http_request_t*);
|
||||
void (*destroy)(data_stream_t*);
|
||||
};
|
||||
|
@ -430,12 +423,6 @@ typedef struct {
|
|||
BOOL end_of_data;
|
||||
} gzip_stream_t;
|
||||
|
||||
static DWORD gzip_get_avail_data(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
/* Allow reading only from read buffer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL gzip_end_of_data(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
|
||||
|
@ -444,7 +431,7 @@ static BOOL gzip_end_of_data(data_stream_t *stream, http_request_t *req)
|
|||
}
|
||||
|
||||
static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
|
||||
DWORD *read, blocking_mode_t blocking_mode)
|
||||
DWORD *read, BOOL allow_blocking)
|
||||
{
|
||||
gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
|
||||
z_stream *zstream = &gzip_stream->zstream;
|
||||
|
@ -452,7 +439,7 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW
|
|||
int zres;
|
||||
DWORD res = ERROR_SUCCESS;
|
||||
|
||||
TRACE("(%d %d)\n", size, blocking_mode);
|
||||
TRACE("(%d %x)\n", size, allow_blocking);
|
||||
|
||||
while(size && !gzip_stream->end_of_data) {
|
||||
if(!gzip_stream->buf_size) {
|
||||
|
@ -462,16 +449,14 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW
|
|||
gzip_stream->buf_pos = 0;
|
||||
}
|
||||
res = gzip_stream->parent_stream->vtbl->read(gzip_stream->parent_stream, req, gzip_stream->buf+gzip_stream->buf_size,
|
||||
sizeof(gzip_stream->buf)-gzip_stream->buf_size, ¤t_read, blocking_mode);
|
||||
gzip_stream->buf_size += current_read;
|
||||
sizeof(gzip_stream->buf)-gzip_stream->buf_size, ¤t_read, allow_blocking);
|
||||
if(res != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
gzip_stream->buf_size += current_read;
|
||||
if(!current_read) {
|
||||
if(blocking_mode != BLOCKING_DISALLOW) {
|
||||
WARN("unexpected end of data\n");
|
||||
gzip_stream->end_of_data = TRUE;
|
||||
}
|
||||
WARN("unexpected end of data\n");
|
||||
gzip_stream->end_of_data = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -497,11 +482,13 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW
|
|||
break;
|
||||
}
|
||||
|
||||
if(ret_read && blocking_mode == BLOCKING_ALLOW)
|
||||
blocking_mode = BLOCKING_DISALLOW;
|
||||
if(ret_read)
|
||||
allow_blocking = FALSE;
|
||||
}
|
||||
|
||||
TRACE("read %u bytes\n", ret_read);
|
||||
if(ret_read)
|
||||
res = ERROR_SUCCESS;
|
||||
*read = ret_read;
|
||||
return res;
|
||||
}
|
||||
|
@ -524,7 +511,6 @@ static void gzip_destroy(data_stream_t *stream)
|
|||
}
|
||||
|
||||
static const data_stream_vtbl_t gzip_stream_vtbl = {
|
||||
gzip_get_avail_data,
|
||||
gzip_end_of_data,
|
||||
gzip_read,
|
||||
gzip_drain_content,
|
||||
|
@ -2348,11 +2334,6 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer,
|
|||
if (!(req->session->appInfo->proxyPassword = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY;
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
case INTERNET_OPTION_HTTP_DECODING:
|
||||
if(size != sizeof(BOOL))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
req->decoding = *(BOOL*)buffer;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return INET_SetOption(hdr, option, buffer, size);
|
||||
|
@ -2565,11 +2546,13 @@ static BOOL end_of_read_data( http_request_t *req )
|
|||
return !req->read_size && req->data_stream->vtbl->end_of_data(req->data_stream, req);
|
||||
}
|
||||
|
||||
static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD *read, blocking_mode_t blocking_mode)
|
||||
static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
|
||||
{
|
||||
DWORD res;
|
||||
|
||||
res = req->data_stream->vtbl->read(req->data_stream, req, buf, size, read, blocking_mode);
|
||||
res = req->data_stream->vtbl->read(req->data_stream, req, buf, size, read, allow_blocking);
|
||||
if(res != ERROR_SUCCESS)
|
||||
*read = 0;
|
||||
assert(*read <= size);
|
||||
|
||||
if(req->hCacheFile) {
|
||||
|
@ -2582,7 +2565,7 @@ static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD
|
|||
FIXME("WriteFile failed: %u\n", GetLastError());
|
||||
}
|
||||
|
||||
if(req->data_stream->vtbl->end_of_data(req->data_stream, req))
|
||||
if((res == ERROR_SUCCESS && !*read) || req->data_stream->vtbl->end_of_data(req->data_stream, req))
|
||||
commit_cache_entry(req);
|
||||
}
|
||||
|
||||
|
@ -2590,7 +2573,7 @@ static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD
|
|||
}
|
||||
|
||||
/* fetch some more data into the read buffer (the read section must be held) */
|
||||
static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mode, DWORD *read_bytes)
|
||||
static DWORD refill_read_buffer(http_request_t *req, BOOL allow_blocking, DWORD *read_bytes)
|
||||
{
|
||||
DWORD res, read=0;
|
||||
|
||||
|
@ -2604,7 +2587,10 @@ static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mo
|
|||
}
|
||||
|
||||
res = read_http_stream(req, req->read_buf+req->read_size, sizeof(req->read_buf) - req->read_size,
|
||||
&read, blocking_mode);
|
||||
&read, allow_blocking);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return res;
|
||||
|
||||
req->read_size += read;
|
||||
|
||||
TRACE("read %u bytes, read_size %u\n", read, req->read_size);
|
||||
|
@ -2613,33 +2599,6 @@ static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mo
|
|||
return res;
|
||||
}
|
||||
|
||||
/* return the size of data available to be read immediately (the read section must be held) */
|
||||
static DWORD get_avail_data( http_request_t *req )
|
||||
{
|
||||
DWORD avail = req->read_size;
|
||||
|
||||
/*
|
||||
* Different Windows versions have different limits of returned data, but all
|
||||
* of them return no more than centrain amount. We use READ_BUFFER_SIZE as a limit.
|
||||
*/
|
||||
if(avail < READ_BUFFER_SIZE)
|
||||
avail += req->data_stream->vtbl->get_avail_data(req->data_stream, req);
|
||||
|
||||
return min(avail, READ_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
static DWORD netconn_get_avail_data(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
|
||||
DWORD avail = 0;
|
||||
|
||||
if(is_valid_netconn(req->netconn))
|
||||
NETCON_query_data_available(req->netconn, &avail);
|
||||
return netconn_stream->content_length == ~0u
|
||||
? avail
|
||||
: min(avail, netconn_stream->content_length-netconn_stream->content_read);
|
||||
}
|
||||
|
||||
static BOOL netconn_end_of_data(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
|
||||
|
@ -2647,31 +2606,24 @@ static BOOL netconn_end_of_data(data_stream_t *stream, http_request_t *req)
|
|||
}
|
||||
|
||||
static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
|
||||
DWORD *read, blocking_mode_t blocking_mode)
|
||||
DWORD *read, BOOL allow_blocking)
|
||||
{
|
||||
netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
|
||||
DWORD res = ERROR_SUCCESS;
|
||||
int len = 0, ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
size = min(size, netconn_stream->content_length-netconn_stream->content_read);
|
||||
|
||||
if(size && is_valid_netconn(req->netconn)) {
|
||||
while((res = NETCON_recv(req->netconn, buf+ret, size-ret, blocking_mode != BLOCKING_DISALLOW, &len)) == ERROR_SUCCESS) {
|
||||
if(!len) {
|
||||
res = NETCON_recv(req->netconn, buf, size, allow_blocking, &ret);
|
||||
if(res == ERROR_SUCCESS) {
|
||||
if(!ret)
|
||||
netconn_stream->content_length = netconn_stream->content_read;
|
||||
break;
|
||||
}
|
||||
ret += len;
|
||||
netconn_stream->content_read += len;
|
||||
if(blocking_mode != BLOCKING_WAITALL || size == ret)
|
||||
break;
|
||||
netconn_stream->content_read += ret;
|
||||
}
|
||||
|
||||
if(ret || (blocking_mode == BLOCKING_DISALLOW && res == WSAEWOULDBLOCK))
|
||||
res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
TRACE("read %u bytes\n", ret);
|
||||
TRACE("res %u read %u bytes\n", res, ret);
|
||||
*read = ret;
|
||||
return res;
|
||||
}
|
||||
|
@ -2680,17 +2632,20 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req)
|
|||
{
|
||||
netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
|
||||
BYTE buf[1024];
|
||||
int len;
|
||||
int len, res;
|
||||
size_t size;
|
||||
|
||||
if(netconn_end_of_data(stream, req))
|
||||
return TRUE;
|
||||
if(netconn_stream->content_length == ~0u)
|
||||
return FALSE;
|
||||
|
||||
do {
|
||||
if(NETCON_recv(req->netconn, buf, sizeof(buf), FALSE, &len) != ERROR_SUCCESS)
|
||||
while(netconn_stream->content_read < netconn_stream->content_length) {
|
||||
size = min(sizeof(buf), netconn_stream->content_length-netconn_stream->content_read);
|
||||
res = NETCON_recv(req->netconn, buf, size, FALSE, &len);
|
||||
if(res || !len)
|
||||
return FALSE;
|
||||
|
||||
netconn_stream->content_read += len;
|
||||
}while(netconn_stream->content_read < netconn_stream->content_length);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -2700,7 +2655,6 @@ static void netconn_destroy(data_stream_t *stream)
|
|||
}
|
||||
|
||||
static const data_stream_vtbl_t netconn_stream_vtbl = {
|
||||
netconn_get_avail_data,
|
||||
netconn_end_of_data,
|
||||
netconn_read,
|
||||
netconn_drain_content,
|
||||
|
@ -2722,7 +2676,7 @@ static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req)
|
|||
}
|
||||
|
||||
static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
|
||||
DWORD *read, blocking_mode_t blocking_mode)
|
||||
DWORD *read, BOOL allow_blocking)
|
||||
{
|
||||
chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
|
||||
DWORD ret_read = 0, res = ERROR_SUCCESS;
|
||||
|
@ -2741,10 +2695,12 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
|
|||
case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
|
||||
case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
|
||||
chunked_stream->buf_pos = 0;
|
||||
res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), blocking_mode != BLOCKING_DISALLOW, &read_bytes);
|
||||
res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), allow_blocking, &read_bytes);
|
||||
if(res == ERROR_SUCCESS && read_bytes) {
|
||||
chunked_stream->buf_size += read_bytes;
|
||||
}else if(res == WSAEWOULDBLOCK) {
|
||||
if(ret_read)
|
||||
res = ERROR_SUCCESS;
|
||||
continue_read = FALSE;
|
||||
continue;
|
||||
}else {
|
||||
|
@ -2803,7 +2759,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
|
|||
chunked_stream->buf_size -= read_bytes;
|
||||
}else {
|
||||
res = NETCON_recv(req->netconn, (char*)buf+ret_read, read_bytes,
|
||||
blocking_mode != BLOCKING_DISALLOW, (int*)&read_bytes);
|
||||
allow_blocking, (int*)&read_bytes);
|
||||
if(res != ERROR_SUCCESS) {
|
||||
continue_read = FALSE;
|
||||
break;
|
||||
|
@ -2820,8 +2776,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
|
|||
ret_read += read_bytes;
|
||||
if(!chunked_stream->chunk_size)
|
||||
chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA;
|
||||
if(blocking_mode == BLOCKING_ALLOW)
|
||||
blocking_mode = BLOCKING_DISALLOW;
|
||||
allow_blocking = FALSE;
|
||||
break;
|
||||
|
||||
case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
|
||||
|
@ -2848,7 +2803,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
|
|||
|
||||
if(ret_read)
|
||||
res = ERROR_SUCCESS;
|
||||
if(res != ERROR_SUCCESS && res != WSAEWOULDBLOCK)
|
||||
if(res != ERROR_SUCCESS)
|
||||
return res;
|
||||
|
||||
TRACE("read %d bytes\n", ret_read);
|
||||
|
@ -2856,26 +2811,6 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static DWORD chunked_get_avail_data(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
|
||||
DWORD avail = 0;
|
||||
|
||||
if(chunked_stream->state != CHUNKED_STREAM_STATE_READING_CHUNK) {
|
||||
DWORD res, read;
|
||||
|
||||
/* try to process to the next chunk */
|
||||
res = chunked_read(stream, req, NULL, 0, &read, BLOCKING_DISALLOW);
|
||||
if(res != ERROR_SUCCESS || chunked_stream->state != CHUNKED_STREAM_STATE_READING_CHUNK)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(is_valid_netconn(req->netconn) && chunked_stream->buf_size < chunked_stream->chunk_size)
|
||||
NETCON_query_data_available(req->netconn, &avail);
|
||||
|
||||
return min(avail + chunked_stream->buf_size, chunked_stream->chunk_size);
|
||||
}
|
||||
|
||||
static BOOL chunked_drain_content(data_stream_t *stream, http_request_t *req)
|
||||
{
|
||||
chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
|
||||
|
@ -2889,7 +2824,6 @@ static void chunked_destroy(data_stream_t *stream)
|
|||
}
|
||||
|
||||
static const data_stream_vtbl_t chunked_stream_vtbl = {
|
||||
chunked_get_avail_data,
|
||||
chunked_end_of_data,
|
||||
chunked_read,
|
||||
chunked_drain_content,
|
||||
|
@ -2941,7 +2875,7 @@ static DWORD set_content_length(http_request_t *request)
|
|||
request->contentLength = ~0u;
|
||||
}
|
||||
|
||||
if(request->decoding) {
|
||||
if(request->hdr.decoding) {
|
||||
int encoding_idx;
|
||||
|
||||
static const WCHAR deflateW[] = {'d','e','f','l','a','t','e',0};
|
||||
|
@ -2980,49 +2914,39 @@ static void send_request_complete(http_request_t *req, DWORD_PTR result, DWORD e
|
|||
sizeof(INTERNET_ASYNC_RESULT));
|
||||
}
|
||||
|
||||
static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif, DWORD *ret_size)
|
||||
static void HTTP_ReceiveRequestData(http_request_t *req)
|
||||
{
|
||||
DWORD res, read = 0, avail = 0;
|
||||
blocking_mode_t mode;
|
||||
DWORD res, read = 0;
|
||||
|
||||
TRACE("%p\n", req);
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
|
||||
mode = first_notif && req->read_size ? BLOCKING_DISALLOW : BLOCKING_ALLOW;
|
||||
res = refill_read_buffer(req, mode, &read);
|
||||
res = refill_read_buffer(req, FALSE, &read);
|
||||
if(res == ERROR_SUCCESS)
|
||||
avail = get_avail_data(req);
|
||||
read += req->read_size;
|
||||
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
||||
if(res != ERROR_SUCCESS || (mode != BLOCKING_DISALLOW && !read)) {
|
||||
if(res != WSAEWOULDBLOCK && (res != ERROR_SUCCESS || !read)) {
|
||||
WARN("res %u read %u, closing connection\n", res, read);
|
||||
http_release_netconn(req, FALSE);
|
||||
}
|
||||
|
||||
if(res != ERROR_SUCCESS) {
|
||||
if(res != ERROR_SUCCESS && res != WSAEWOULDBLOCK) {
|
||||
send_request_complete(req, 0, res);
|
||||
return;
|
||||
}
|
||||
|
||||
if(ret_size)
|
||||
*ret_size = avail;
|
||||
if(first_notif)
|
||||
avail = 0;
|
||||
|
||||
send_request_complete(req, req->session->hdr.dwInternalFlags & INET_OPENURL ? (DWORD_PTR)req->hdr.hInternet : 1, avail);
|
||||
send_request_complete(req, req->session->hdr.dwInternalFlags & INET_OPENURL ? (DWORD_PTR)req->hdr.hInternet : 1, 0);
|
||||
}
|
||||
|
||||
/* read data from the http connection (the read section must be held) */
|
||||
static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read)
|
||||
static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL allow_blocking)
|
||||
{
|
||||
DWORD current_read = 0, ret_read = 0;
|
||||
blocking_mode_t blocking_mode;
|
||||
DWORD res = ERROR_SUCCESS;
|
||||
|
||||
blocking_mode = req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC ? BLOCKING_ALLOW : BLOCKING_WAITALL;
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
|
||||
if(req->read_size) {
|
||||
|
@ -3030,13 +2954,15 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *
|
|||
memcpy(buffer, req->read_buf+req->read_pos, ret_read);
|
||||
req->read_size -= ret_read;
|
||||
req->read_pos += ret_read;
|
||||
if(blocking_mode == BLOCKING_ALLOW)
|
||||
blocking_mode = BLOCKING_DISALLOW;
|
||||
allow_blocking = FALSE;
|
||||
}
|
||||
|
||||
if(ret_read < size) {
|
||||
res = read_http_stream(req, (BYTE*)buffer+ret_read, size-ret_read, ¤t_read, blocking_mode);
|
||||
ret_read += current_read;
|
||||
res = read_http_stream(req, (BYTE*)buffer+ret_read, size-ret_read, ¤t_read, allow_blocking);
|
||||
if(res == ERROR_SUCCESS)
|
||||
ret_read += current_read;
|
||||
else if(res == WSAEWOULDBLOCK && ret_read)
|
||||
res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
@ -3044,7 +2970,7 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *
|
|||
*read = ret_read;
|
||||
TRACE( "retrieved %u bytes (%u)\n", ret_read, req->contentLength );
|
||||
|
||||
if(size && !ret_read)
|
||||
if(res != WSAEWOULDBLOCK && (!ret_read || res != ERROR_SUCCESS))
|
||||
http_release_netconn(req, res == ERROR_SUCCESS);
|
||||
|
||||
return res;
|
||||
|
@ -3069,7 +2995,7 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
|
|||
DWORD bytes_read, res;
|
||||
BYTE buf[4096];
|
||||
|
||||
res = HTTPREQ_Read(req, buf, sizeof(buf), &bytes_read);
|
||||
res = HTTPREQ_Read(req, buf, sizeof(buf), &bytes_read, TRUE);
|
||||
if(res != ERROR_SUCCESS) {
|
||||
ret = FALSE;
|
||||
break;
|
||||
|
@ -3088,114 +3014,136 @@ typedef struct {
|
|||
task_header_t hdr;
|
||||
void *buf;
|
||||
DWORD size;
|
||||
DWORD read_pos;
|
||||
DWORD *ret_read;
|
||||
} read_file_ex_task_t;
|
||||
} read_file_task_t;
|
||||
|
||||
static void AsyncReadFileExProc(task_header_t *hdr)
|
||||
static void async_read_file_proc(task_header_t *hdr)
|
||||
{
|
||||
read_file_ex_task_t *task = (read_file_ex_task_t*)hdr;
|
||||
read_file_task_t *task = (read_file_task_t*)hdr;
|
||||
http_request_t *req = (http_request_t*)task->hdr.hdr;
|
||||
DWORD res = ERROR_SUCCESS, read = 0, buffered = 0;
|
||||
DWORD res = ERROR_SUCCESS, read = task->read_pos, complete_arg = 0;
|
||||
|
||||
TRACE("%p\n", req);
|
||||
TRACE("req %p buf %p size %u read_pos %u ret_read %p\n", req, task->buf, task->size, task->read_pos, task->ret_read);
|
||||
|
||||
if(task->buf) {
|
||||
DWORD read_bytes;
|
||||
while (read < task->size) {
|
||||
res = HTTPREQ_Read(req, (char*)task->buf + read, task->size - read, &read_bytes, TRUE);
|
||||
if (res != ERROR_SUCCESS || !read_bytes)
|
||||
break;
|
||||
read += read_bytes;
|
||||
}
|
||||
}else {
|
||||
EnterCriticalSection(&req->read_section);
|
||||
res = refill_read_buffer(req, TRUE, &read);
|
||||
LeaveCriticalSection(&req->read_section);
|
||||
|
||||
if(task->ret_read)
|
||||
res = HTTPREQ_Read(req, task->buf, task->size, &read);
|
||||
if(res == ERROR_SUCCESS)
|
||||
res = refill_read_buffer(req, task->ret_read ? BLOCKING_DISALLOW : BLOCKING_ALLOW, &buffered);
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
if(task->ret_read)
|
||||
*task->ret_read = read;
|
||||
read += buffered;
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
|
||||
&read, sizeof(read));
|
||||
complete_arg = read; /* QueryDataAvailable reports read bytes in request complete notification */
|
||||
if(res != ERROR_SUCCESS || !read)
|
||||
http_release_netconn(req, drain_content(req, FALSE));
|
||||
}
|
||||
|
||||
send_request_complete(req, res == ERROR_SUCCESS, res);
|
||||
TRACE("res %u read %u\n", res, read);
|
||||
|
||||
if(task->ret_read)
|
||||
*task->ret_read = read;
|
||||
|
||||
/* FIXME: We should report bytes transferred before decoding content. */
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED, &read, sizeof(read));
|
||||
|
||||
if(res != ERROR_SUCCESS)
|
||||
complete_arg = res;
|
||||
send_request_complete(req, res == ERROR_SUCCESS, complete_arg);
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_ReadFileEx(object_header_t *hdr, void *buf, DWORD size, DWORD *ret_read,
|
||||
static DWORD async_read(http_request_t *req, void *buf, DWORD size, DWORD read_pos, DWORD *ret_read)
|
||||
{
|
||||
read_file_task_t *task;
|
||||
|
||||
task = alloc_async_task(&req->hdr, async_read_file_proc, sizeof(*task));
|
||||
if(!task)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
task->buf = buf;
|
||||
task->size = size;
|
||||
task->read_pos = read_pos;
|
||||
task->ret_read = ret_read;
|
||||
|
||||
INTERNET_AsyncCall(&task->hdr);
|
||||
return ERROR_IO_PENDING;
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buf, DWORD size, DWORD *ret_read,
|
||||
DWORD flags, DWORD_PTR context)
|
||||
{
|
||||
|
||||
http_request_t *req = (http_request_t*)hdr;
|
||||
DWORD res, read, cread, error = ERROR_SUCCESS;
|
||||
DWORD res = ERROR_SUCCESS, read = 0, cread, error = ERROR_SUCCESS;
|
||||
BOOL allow_blocking, notify_received = FALSE;
|
||||
|
||||
TRACE("(%p %p %u %x)\n", req, buf, size, flags);
|
||||
|
||||
if (flags & ~(IRF_ASYNC|IRF_NO_WAIT))
|
||||
FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
|
||||
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
||||
allow_blocking = !(req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC);
|
||||
|
||||
if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
|
||||
{
|
||||
read_file_ex_task_t *task;
|
||||
if(allow_blocking || TryEnterCriticalSection(&req->read_section)) {
|
||||
if(allow_blocking)
|
||||
EnterCriticalSection(&req->read_section);
|
||||
if(hdr->dwError == ERROR_SUCCESS)
|
||||
hdr->dwError = INTERNET_HANDLE_IN_USE;
|
||||
else if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||
|
||||
if (TryEnterCriticalSection( &req->read_section ))
|
||||
{
|
||||
if (get_avail_data(req) || end_of_read_data(req))
|
||||
{
|
||||
res = HTTPREQ_Read(req, buf, size, &read);
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
goto done;
|
||||
}
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
if(req->read_size) {
|
||||
read = min(size, req->read_size);
|
||||
memcpy(buf, req->read_buf + req->read_pos, read);
|
||||
req->read_size -= read;
|
||||
req->read_pos += read;
|
||||
}
|
||||
|
||||
task = alloc_async_task(&req->hdr, AsyncReadFileExProc, sizeof(*task));
|
||||
task->buf = buf;
|
||||
task->size = size;
|
||||
task->ret_read = (flags & IRF_NO_WAIT) ? NULL : ret_read;
|
||||
if(read < size && (!read || !(flags & IRF_NO_WAIT)) && !end_of_read_data(req)) {
|
||||
LeaveCriticalSection(&req->read_section);
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
||||
EnterCriticalSection( &req->read_section );
|
||||
notify_received = TRUE;
|
||||
|
||||
INTERNET_AsyncCall(&task->hdr);
|
||||
while(read < size) {
|
||||
res = HTTPREQ_Read(req, (char*)buf+read, size-read, &cread, allow_blocking);
|
||||
read += cread;
|
||||
if (res != ERROR_SUCCESS || !cread)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_IO_PENDING;
|
||||
}
|
||||
|
||||
read = 0;
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
if(hdr->dwError == ERROR_SUCCESS)
|
||||
hdr->dwError = INTERNET_HANDLE_IN_USE;
|
||||
else if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||
|
||||
while(1) {
|
||||
res = HTTPREQ_Read(req, (char*)buf+read, size-read, &cread);
|
||||
if(res != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
read += cread;
|
||||
if(read == size || end_of_read_data(req))
|
||||
break;
|
||||
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_SUCCESS;
|
||||
else
|
||||
error = hdr->dwError;
|
||||
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
|
||||
&cread, sizeof(cread));
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext,
|
||||
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
}else {
|
||||
res = WSAEWOULDBLOCK;
|
||||
}
|
||||
|
||||
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_SUCCESS;
|
||||
else
|
||||
error = hdr->dwError;
|
||||
if(res == WSAEWOULDBLOCK) {
|
||||
if(!(flags & IRF_NO_WAIT))
|
||||
return async_read(req, buf, size, read, ret_read);
|
||||
if(!read)
|
||||
return async_read(req, NULL, 0, 0, NULL);
|
||||
res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
||||
done:
|
||||
*ret_read = read;
|
||||
if (res == ERROR_SUCCESS) {
|
||||
if (res != ERROR_SUCCESS)
|
||||
return res;
|
||||
|
||||
if(notify_received)
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
|
||||
&read, sizeof(read));
|
||||
}
|
||||
|
||||
return res==ERROR_SUCCESS ? error : res;
|
||||
return error;
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written)
|
||||
|
@ -3214,99 +3162,60 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
|
|||
return res;
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
|
||||
{
|
||||
http_request_t *req = (http_request_t*)hdr;
|
||||
DWORD res;
|
||||
|
||||
if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
|
||||
{
|
||||
read_file_ex_task_t *task;
|
||||
|
||||
if (TryEnterCriticalSection( &req->read_section ))
|
||||
{
|
||||
if (get_avail_data(req) || end_of_read_data(req))
|
||||
{
|
||||
res = HTTPREQ_Read(req, buffer, size, read);
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
return res;
|
||||
}
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
}
|
||||
|
||||
task = alloc_async_task(&req->hdr, AsyncReadFileExProc, sizeof(*task));
|
||||
task->buf = buffer;
|
||||
task->size = size;
|
||||
task->ret_read = read;
|
||||
|
||||
*read = 0;
|
||||
INTERNET_AsyncCall(&task->hdr);
|
||||
|
||||
return ERROR_IO_PENDING;
|
||||
}
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||
|
||||
res = HTTPREQ_Read(req, buffer, size, read);
|
||||
if(res == ERROR_SUCCESS)
|
||||
res = hdr->dwError;
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
task_header_t hdr;
|
||||
DWORD *ret_size;
|
||||
} http_data_available_task_t;
|
||||
|
||||
static void AsyncQueryDataAvailableProc(task_header_t *hdr)
|
||||
{
|
||||
http_data_available_task_t *task = (http_data_available_task_t*)hdr;
|
||||
|
||||
HTTP_ReceiveRequestData((http_request_t*)task->hdr.hdr, FALSE, task->ret_size);
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
|
||||
{
|
||||
http_request_t *req = (http_request_t*)hdr;
|
||||
DWORD res = ERROR_SUCCESS, avail = 0, error = ERROR_SUCCESS;
|
||||
BOOL allow_blocking, notify_received = FALSE;
|
||||
|
||||
TRACE("(%p %p %x %lx)\n", req, available, flags, ctx);
|
||||
|
||||
if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
|
||||
{
|
||||
http_data_available_task_t *task;
|
||||
if (flags & ~(IRF_ASYNC|IRF_NO_WAIT))
|
||||
FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
|
||||
|
||||
/* never wait, if we can't enter the section we queue an async request right away */
|
||||
if (TryEnterCriticalSection( &req->read_section ))
|
||||
{
|
||||
refill_read_buffer(req, BLOCKING_DISALLOW, NULL);
|
||||
if ((*available = get_avail_data( req ))) goto done;
|
||||
if (end_of_read_data( req )) goto done;
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
*available = 0;
|
||||
allow_blocking = !(req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC);
|
||||
|
||||
if(allow_blocking || TryEnterCriticalSection(&req->read_section)) {
|
||||
if(allow_blocking)
|
||||
EnterCriticalSection(&req->read_section);
|
||||
if(hdr->dwError == ERROR_SUCCESS)
|
||||
hdr->dwError = INTERNET_HANDLE_IN_USE;
|
||||
else if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||
|
||||
avail = req->read_size;
|
||||
|
||||
if(!avail && !end_of_read_data(req)) {
|
||||
LeaveCriticalSection(&req->read_section);
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
||||
EnterCriticalSection( &req->read_section );
|
||||
notify_received = TRUE;
|
||||
|
||||
res = refill_read_buffer(req, allow_blocking, &avail);
|
||||
}
|
||||
|
||||
task = alloc_async_task(&req->hdr, AsyncQueryDataAvailableProc, sizeof(*task));
|
||||
task->ret_size = available;
|
||||
INTERNET_AsyncCall(&task->hdr);
|
||||
return ERROR_IO_PENDING;
|
||||
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||
hdr->dwError = ERROR_SUCCESS;
|
||||
else
|
||||
error = hdr->dwError;
|
||||
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
}else {
|
||||
res = WSAEWOULDBLOCK;
|
||||
}
|
||||
|
||||
EnterCriticalSection( &req->read_section );
|
||||
if(res == WSAEWOULDBLOCK)
|
||||
return async_read(req, NULL, 0, 0, available);
|
||||
|
||||
if (!(*available = get_avail_data( req )) && !end_of_read_data( req ))
|
||||
{
|
||||
refill_read_buffer( req, BLOCKING_ALLOW, NULL );
|
||||
*available = get_avail_data( req );
|
||||
}
|
||||
if (res != ERROR_SUCCESS)
|
||||
return res;
|
||||
|
||||
done:
|
||||
LeaveCriticalSection( &req->read_section );
|
||||
|
||||
TRACE( "returning %u\n", *available );
|
||||
return ERROR_SUCCESS;
|
||||
*available = avail;
|
||||
if(notify_received)
|
||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
|
||||
&avail, sizeof(avail));
|
||||
return error;
|
||||
}
|
||||
|
||||
static DWORD HTTPREQ_LockRequestFile(object_header_t *hdr, req_file_t **ret)
|
||||
|
@ -3330,7 +3239,6 @@ static const object_vtbl_t HTTPREQVtbl = {
|
|||
HTTPREQ_QueryOption,
|
||||
HTTPREQ_SetOption,
|
||||
HTTPREQ_ReadFile,
|
||||
HTTPREQ_ReadFileEx,
|
||||
HTTPREQ_WriteFile,
|
||||
HTTPREQ_QueryDataAvailable,
|
||||
NULL,
|
||||
|
@ -3365,6 +3273,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
|
|||
request->hdr.htype = WH_HHTTPREQ;
|
||||
request->hdr.dwFlags = dwFlags;
|
||||
request->hdr.dwContext = dwContext;
|
||||
request->hdr.decoding = session->hdr.decoding;
|
||||
request->contentLength = ~0u;
|
||||
|
||||
request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl;
|
||||
|
@ -4137,6 +4046,9 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
|||
if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
|
||||
return INTERNET_GetLastError();
|
||||
|
||||
if (!urlComponents.dwHostNameLength)
|
||||
return ERROR_INTERNET_INVALID_URL;
|
||||
|
||||
if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
|
||||
if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
|
||||
TRACE("redirect from secure page to non-secure page\n");
|
||||
|
@ -4380,7 +4292,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
|
|||
while (isspaceW(*ptr))
|
||||
ptr++;
|
||||
|
||||
for (monthPtr = month; !isspace(*ptr) &&
|
||||
for (monthPtr = month; !isspaceW(*ptr) &&
|
||||
monthPtr - month < sizeof(month) / sizeof(month[0]) - 1;
|
||||
monthPtr++, ptr++)
|
||||
*monthPtr = *ptr;
|
||||
|
@ -4477,7 +4389,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
|
|||
while (isspaceW(*ptr))
|
||||
ptr++;
|
||||
|
||||
for (monthPtr = month; !isspace(*ptr) &&
|
||||
for (monthPtr = month; !isspaceW(*ptr) &&
|
||||
monthPtr - month < sizeof(month) / sizeof(month[0]) - 1;
|
||||
monthPtr++, ptr++)
|
||||
*monthPtr = *ptr;
|
||||
|
@ -5221,7 +5133,7 @@ lend:
|
|||
{
|
||||
if (res == ERROR_SUCCESS) {
|
||||
if(bEndRequest && request->contentLength && request->bytesWritten == request->bytesToWrite)
|
||||
HTTP_ReceiveRequestData(request, TRUE, NULL);
|
||||
HTTP_ReceiveRequestData(request);
|
||||
else
|
||||
send_request_complete(request,
|
||||
request->session->hdr.dwInternalFlags & INET_OPENURL ? (DWORD_PTR)request->hdr.hInternet : 1, 0);
|
||||
|
@ -5328,7 +5240,7 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
|
|||
create_cache_entry(request);
|
||||
|
||||
if (res == ERROR_SUCCESS && request->contentLength)
|
||||
HTTP_ReceiveRequestData(request, TRUE, NULL);
|
||||
HTTP_ReceiveRequestData(request);
|
||||
else
|
||||
send_request_complete(request, res == ERROR_SUCCESS, res);
|
||||
|
||||
|
@ -5818,7 +5730,6 @@ static const object_vtbl_t HTTPSESSIONVtbl = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -5859,6 +5770,7 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
|
|||
session->hdr.dwFlags = dwFlags;
|
||||
session->hdr.dwContext = dwContext;
|
||||
session->hdr.dwInternalFlags |= dwInternalFlags;
|
||||
session->hdr.decoding = hIC->hdr.decoding;
|
||||
|
||||
WININET_AddRef( &hIC->hdr );
|
||||
session->appInfo = hIC;
|
||||
|
|
|
@ -943,7 +943,6 @@ static const object_vtbl_t APPINFOVtbl = {
|
|||
APPINFO_SetOption,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1146,11 +1145,7 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
|
|||
{
|
||||
TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved);
|
||||
|
||||
if (lpdwStatus) {
|
||||
WARN("always returning LAN connection.\n");
|
||||
*lpdwStatus = INTERNET_CONNECTION_LAN;
|
||||
}
|
||||
return TRUE;
|
||||
return InternetGetConnectedStateExW(lpdwStatus, NULL, 0, dwReserved);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2149,8 +2144,11 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(hdr->vtbl->ReadFile)
|
||||
res = hdr->vtbl->ReadFile(hdr, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);
|
||||
if(hdr->vtbl->ReadFile) {
|
||||
res = hdr->vtbl->ReadFile(hdr, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead, 0, 0);
|
||||
if(res == ERROR_IO_PENDING)
|
||||
*pdwNumOfBytesRead = 0;
|
||||
}
|
||||
|
||||
WININET_Release(hdr);
|
||||
|
||||
|
@ -2208,8 +2206,8 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(hdr->vtbl->ReadFileEx)
|
||||
res = hdr->vtbl->ReadFileEx(hdr, lpBuffersOut->lpvBuffer, lpBuffersOut->dwBufferLength,
|
||||
if(hdr->vtbl->ReadFile)
|
||||
res = hdr->vtbl->ReadFile(hdr, lpBuffersOut->lpvBuffer, lpBuffersOut->dwBufferLength,
|
||||
&lpBuffersOut->dwBufferLength, dwFlags, dwContext);
|
||||
|
||||
WININET_Release(hdr);
|
||||
|
@ -2246,8 +2244,8 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(hdr->vtbl->ReadFileEx)
|
||||
res = hdr->vtbl->ReadFileEx(hdr, lpBuffer->lpvBuffer, lpBuffer->dwBufferLength, &lpBuffer->dwBufferLength,
|
||||
if(hdr->vtbl->ReadFile)
|
||||
res = hdr->vtbl->ReadFile(hdr, lpBuffer->lpvBuffer, lpBuffer->dwBufferLength, &lpBuffer->dwBufferLength,
|
||||
dwFlags, dwContext);
|
||||
|
||||
WININET_Release(hdr);
|
||||
|
@ -2839,10 +2837,21 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
|
|||
FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n");
|
||||
break;
|
||||
case INTERNET_OPTION_HTTP_DECODING:
|
||||
FIXME("INTERNET_OPTION_HTTP_DECODING; STUB\n");
|
||||
SetLastError(ERROR_INTERNET_INVALID_OPTION);
|
||||
ret = FALSE;
|
||||
{
|
||||
if (!lpwhh)
|
||||
{
|
||||
SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
|
||||
return FALSE;
|
||||
}
|
||||
if (!lpBuffer || dwBufferLength != sizeof(BOOL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
lpwhh->decoding = *(BOOL *)lpBuffer;
|
||||
break;
|
||||
}
|
||||
case INTERNET_OPTION_COOKIES_3RD_PARTY:
|
||||
FIXME("INTERNET_OPTION_COOKIES_3RD_PARTY; STUB\n");
|
||||
SetLastError(ERROR_INTERNET_INVALID_OPTION);
|
||||
|
@ -3458,7 +3467,9 @@ static HINTERNET INTERNET_InternetOpenUrlW(appinfo_t *hIC, LPCWSTR lpszUrl,
|
|||
if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
|
||||
return NULL;
|
||||
|
||||
if(urlComponents.nScheme == INTERNET_SCHEME_HTTP && urlComponents.dwExtraInfoLength) {
|
||||
if ((urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) &&
|
||||
urlComponents.dwExtraInfoLength)
|
||||
{
|
||||
assert(urlComponents.lpszUrlPath + urlComponents.dwUrlPathLength == urlComponents.lpszExtraInfo);
|
||||
urlComponents.dwUrlPathLength += urlComponents.dwExtraInfoLength;
|
||||
}
|
||||
|
|
|
@ -336,8 +336,7 @@ typedef struct {
|
|||
void (*CloseConnection)(object_header_t*);
|
||||
DWORD (*QueryOption)(object_header_t*,DWORD,void*,DWORD*,BOOL);
|
||||
DWORD (*SetOption)(object_header_t*,DWORD,void*,DWORD);
|
||||
DWORD (*ReadFile)(object_header_t*,void*,DWORD,DWORD*);
|
||||
DWORD (*ReadFileEx)(object_header_t*,void*,DWORD,DWORD*,DWORD,DWORD_PTR);
|
||||
DWORD (*ReadFile)(object_header_t*,void*,DWORD,DWORD*,DWORD,DWORD_PTR);
|
||||
DWORD (*WriteFile)(object_header_t*,const void*,DWORD,DWORD*);
|
||||
DWORD (*QueryDataAvailable)(object_header_t*,DWORD*,DWORD,DWORD_PTR);
|
||||
DWORD (*FindNextFileW)(object_header_t*,void*);
|
||||
|
@ -358,6 +357,7 @@ struct _object_header_t
|
|||
ULONG ErrorMask;
|
||||
DWORD dwInternalFlags;
|
||||
LONG refs;
|
||||
BOOL decoding;
|
||||
INTERNET_STATUS_CALLBACK lpfnStatusCB;
|
||||
struct list entry;
|
||||
struct list children;
|
||||
|
@ -454,7 +454,6 @@ typedef struct
|
|||
DWORD read_size; /* valid data size in read_buf */
|
||||
BYTE read_buf[READ_BUFFER_SIZE]; /* buffer for already read but not returned data */
|
||||
|
||||
BOOL decoding;
|
||||
data_stream_t *data_stream;
|
||||
netconn_stream_t netconn_stream;
|
||||
} http_request_t;
|
||||
|
@ -512,7 +511,6 @@ DWORD NETCON_secure_connect(netconn_t*,server_t*) DECLSPEC_HIDDEN;
|
|||
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
|
||||
int *sent /* out */) DECLSPEC_HIDDEN;
|
||||
DWORD NETCON_recv(netconn_t*,void*,size_t,BOOL,int*) DECLSPEC_HIDDEN;
|
||||
BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSPEC_HIDDEN;
|
||||
BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
|
||||
LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
|
||||
int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -862,32 +862,6 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, BOOL blocking, i
|
|||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NETCON_query_data_available
|
||||
* Returns the number of bytes of peeked data plus the number of bytes of
|
||||
* queued, but unread data.
|
||||
*/
|
||||
BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available)
|
||||
{
|
||||
*available = 0;
|
||||
|
||||
if(!connection->secure)
|
||||
{
|
||||
ULONG unread;
|
||||
int retval = ioctlsocket(connection->socket, FIONREAD, &unread);
|
||||
if (!retval)
|
||||
{
|
||||
TRACE("%d bytes of queued, but unread data\n", unread);
|
||||
*available += unread;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*available = connection->peek_len;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL NETCON_is_alive(netconn_t *netconn)
|
||||
{
|
||||
int len;
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
@ stub ForceNexusLookupExW
|
||||
@ stdcall FreeUrlCacheSpaceA(str long long)
|
||||
@ stdcall FreeUrlCacheSpaceW(wstr long long)
|
||||
@ stdcall FtpCommandA(long long long str ptr ptr)
|
||||
@ stdcall FtpCommandW(long long long wstr ptr ptr)
|
||||
@ stdcall FtpCommandA(long long long str long ptr)
|
||||
@ stdcall FtpCommandW(long long long wstr long ptr)
|
||||
@ stdcall FtpCreateDirectoryA(ptr str)
|
||||
@ stdcall FtpCreateDirectoryW(ptr wstr)
|
||||
@ stdcall FtpDeleteFileA(ptr str)
|
||||
|
@ -119,8 +119,8 @@
|
|||
@ stdcall InternetAutodialHangup(long)
|
||||
@ stdcall InternetCanonicalizeUrlA(str ptr ptr long)
|
||||
@ stdcall InternetCanonicalizeUrlW(wstr ptr ptr long)
|
||||
@ stdcall InternetCheckConnectionA(ptr long long)
|
||||
@ stdcall InternetCheckConnectionW(ptr long long)
|
||||
@ stdcall InternetCheckConnectionA(str long long)
|
||||
@ stdcall InternetCheckConnectionW(wstr long long)
|
||||
@ stdcall InternetClearAllPerSiteCookieDecisions()
|
||||
@ stdcall InternetCloseHandle(long)
|
||||
@ stdcall InternetCombineUrlA(str str str ptr long)
|
||||
|
@ -150,10 +150,10 @@
|
|||
@ stdcall InternetGetConnectedStateEx(ptr ptr long long) InternetGetConnectedStateExA
|
||||
@ stdcall InternetGetConnectedStateExA(ptr ptr long long)
|
||||
@ stdcall InternetGetConnectedStateExW(ptr ptr long long)
|
||||
@ stdcall InternetGetCookieA(str str ptr long)
|
||||
@ stdcall InternetGetCookieA(str str ptr ptr)
|
||||
@ stdcall InternetGetCookieExA(str str ptr ptr long ptr)
|
||||
@ stdcall InternetGetCookieExW(wstr wstr ptr ptr long ptr)
|
||||
@ stdcall InternetGetCookieW(wstr wstr ptr long)
|
||||
@ stdcall InternetGetCookieW(wstr wstr ptr ptr)
|
||||
@ stdcall InternetGetLastResponseInfoA(ptr ptr ptr)
|
||||
@ stdcall InternetGetLastResponseInfoW(ptr ptr ptr)
|
||||
@ stdcall InternetGetPerSiteCookieDecisionA(str ptr)
|
||||
|
@ -183,8 +183,8 @@
|
|||
@ stub InternetSecurityProtocolToStringW
|
||||
@ stub InternetServerPushParse
|
||||
@ stdcall InternetSetCookieA(str str str)
|
||||
@ stdcall InternetSetCookieExA(str str str long ptr)
|
||||
@ stdcall InternetSetCookieExW(wstr wstr wstr long ptr)
|
||||
@ stdcall InternetSetCookieExA(str str str long long)
|
||||
@ stdcall InternetSetCookieExW(wstr wstr wstr long long)
|
||||
@ stdcall InternetSetCookieW(wstr wstr wstr)
|
||||
@ stub InternetSetDialState
|
||||
@ stub InternetSetDialStateA
|
||||
|
|
|
@ -201,7 +201,7 @@ reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.9.11
|
|||
reactos/dll/win32/winemp3.acm # Synced to WineStaging-2.2
|
||||
reactos/dll/win32/wing32 # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/winhttp # Synced to WineStaging-2.9
|
||||
reactos/dll/win32/wininet # Synced to WineStaging-2.2
|
||||
reactos/dll/win32/wininet # Synced to WineStaging-2.9
|
||||
reactos/dll/win32/winmm # Forked at Wine-20050628
|
||||
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
|
||||
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
||||
|
|
Loading…
Reference in a new issue