Implement WinINet based HTTP downloads
This commit is contained in:
parent
94c9be05c9
commit
9814f5f42f
14
Makefile
14
Makefile
|
|
@ -749,7 +749,9 @@ ifdef MINGW
|
|||
FREETYPE_CFLAGS = -Ifreetype2
|
||||
endif
|
||||
|
||||
USE_HTTP=0
|
||||
ifeq ($(USE_HTTP),1)
|
||||
CLIENT_LIBS += -lwininet
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86)
|
||||
# build 32bit
|
||||
|
|
@ -1914,8 +1916,6 @@ Q3OBJ = \
|
|||
$(B)/client/qal.o \
|
||||
$(B)/client/snd_openal.o \
|
||||
\
|
||||
$(B)/client/cl_http_curl.o \
|
||||
\
|
||||
$(B)/client/sv_bot.o \
|
||||
$(B)/client/sv_ccmds.o \
|
||||
$(B)/client/sv_client.o \
|
||||
|
|
@ -1971,6 +1971,14 @@ Q3OBJ = \
|
|||
$(B)/client/sys_autoupdater.o \
|
||||
$(B)/client/sys_main.o
|
||||
|
||||
ifdef MINGW
|
||||
Q3OBJ += \
|
||||
$(B)/client/cl_http_windows.o
|
||||
else
|
||||
Q3OBJ += \
|
||||
$(B)/client/cl_http_curl.o
|
||||
endif
|
||||
|
||||
ifdef MINGW
|
||||
Q3OBJ += \
|
||||
$(B)/client/con_passive.o
|
||||
|
|
|
|||
162
code/client/cl_http_windows.c
Normal file
162
code/client/cl_http_windows.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2025 Tim Angus (tim@ngus.net)
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifdef USE_HTTP
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
|
||||
static HINTERNET hInternet = NULL;
|
||||
static HINTERNET hUrl = NULL;
|
||||
|
||||
static void DropIf(qboolean condition, const char *fmt, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
if (!condition)
|
||||
return;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
Q_vsnprintf(buffer, sizeof(buffer), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
Com_Error(ERR_DROP, "Download Error: %s URL: %s", buffer, clc.downloadURL);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_HTTP_Init
|
||||
=================
|
||||
*/
|
||||
qboolean CL_HTTP_Init()
|
||||
{
|
||||
OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO)};
|
||||
const char *windowsVersion = GetVersionEx(&osvi) ? va("Windows %lu.%lu (build %lu)",
|
||||
osvi.dwMajorVersion,
|
||||
osvi.dwMinorVersion,
|
||||
osvi.dwBuildNumber)
|
||||
: "Windows";
|
||||
|
||||
hInternet = InternetOpenA(
|
||||
va("%s %s", Q3_VERSION, windowsVersion),
|
||||
INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
|
||||
return hInternet != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_HTTP_Available
|
||||
=================
|
||||
*/
|
||||
qboolean CL_HTTP_Available()
|
||||
{
|
||||
return hInternet != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_HTTP_Shutdown
|
||||
=================
|
||||
*/
|
||||
void CL_HTTP_Shutdown(void)
|
||||
{
|
||||
if (hInternet)
|
||||
{
|
||||
InternetCloseHandle(hInternet);
|
||||
hInternet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_HTTP_BeginDownload
|
||||
=================
|
||||
*/
|
||||
void CL_HTTP_BeginDownload(const char *remoteURL)
|
||||
{
|
||||
DWORD httpCode = 0;
|
||||
DWORD contentLength = 0;
|
||||
DWORD len = sizeof(httpCode);
|
||||
DWORD zero = 0;
|
||||
BOOL success;
|
||||
|
||||
hUrl = InternetOpenUrlA(hInternet, remoteURL,
|
||||
va("Referer: ioQ3://%s\r\n", NET_AdrToString(clc.serverAddress)), -1,
|
||||
INTERNET_FLAG_HYPERLINK |
|
||||
INTERNET_FLAG_NO_CACHE_WRITE |
|
||||
INTERNET_FLAG_NO_COOKIES |
|
||||
INTERNET_FLAG_NO_UI |
|
||||
INTERNET_FLAG_RESYNCHRONIZE |
|
||||
INTERNET_FLAG_RELOAD,
|
||||
0);
|
||||
|
||||
DropIf(hUrl == NULL, "InternetOpenUrlA failed %lu", GetLastError());
|
||||
|
||||
success = HttpQueryInfo(hUrl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &httpCode, &len, &zero);
|
||||
DropIf(!success, "Get HTTP_QUERY_STATUS_CODE failed %lu", GetLastError());
|
||||
|
||||
DropIf(httpCode >= 400, "HTTP code %lu", httpCode);
|
||||
DropIf(httpCode != 200, "Unhandled HTTP code %lu", httpCode);
|
||||
|
||||
success = HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &len, &zero);
|
||||
DropIf(!success, "Get HTTP_QUERY_CONTENT_LENGTH failed %lu", GetLastError());
|
||||
|
||||
clc.downloadSize = (int)contentLength;
|
||||
Cvar_SetValue("cl_downloadSize", clc.downloadSize);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_HTTP_PerformDownload
|
||||
=================
|
||||
*/
|
||||
qboolean CL_HTTP_PerformDownload(void)
|
||||
{
|
||||
static BYTE readBuffer[256 * 1024];
|
||||
DWORD bytesRead = 0;
|
||||
BOOL success;
|
||||
|
||||
DropIf(hUrl == NULL, "hUrl is NULL");
|
||||
|
||||
success = InternetReadFile(hUrl, readBuffer, sizeof(readBuffer), &bytesRead);
|
||||
DropIf(!success, "InternetReadFile failed %lu", GetLastError());
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
clc.downloadCount += bytesRead;
|
||||
Cvar_SetValue("cl_downloadCount", clc.downloadCount);
|
||||
|
||||
int bytesWritten = FS_Write(readBuffer, bytesRead, clc.download);
|
||||
DropIf(bytesWritten != bytesRead, "bytesWritten != bytesRead");
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
InternetCloseHandle(hUrl);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
#endif /* USE_HTTP */
|
||||
Loading…
Reference in New Issue
Block a user