diff options
Diffstat (limited to 'src/cl_http.c')
-rw-r--r-- | src/cl_http.c | 410 |
1 files changed, 215 insertions, 195 deletions
diff --git a/src/cl_http.c b/src/cl_http.c index 35da081..7d9749d 100644 --- a/src/cl_http.c +++ b/src/cl_http.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program 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. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -70,7 +70,8 @@ bandwidth. // libcurl callback to update progress info. Mainly just used as // a way to cancel the transfer if required. -static int progress_func (void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { +static int progress_func(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ dlhandle_t *dl = (dlhandle_t *)clientp; //dl->position = (unsigned)dlnow; @@ -87,7 +88,8 @@ static int progress_func (void *clientp, double dltotal, double dlnow, double ul } // libcurl callback for filelists. -static size_t recv_func (void *ptr, size_t size, size_t nmemb, void *stream) { +static size_t recv_func(void *ptr, size_t size, size_t nmemb, void *stream) +{ size_t new_size, bytes = size * nmemb; dlhandle_t *dl = (dlhandle_t *)stream; @@ -98,7 +100,7 @@ static size_t recv_func (void *ptr, size_t size, size_t nmemb, void *stream) { if (new_size < MIN_DLSIZE) new_size = MIN_DLSIZE; dl->size = new_size; - dl->buffer = Z_Malloc (dl->size); + dl->buffer = Z_Malloc(dl->size); } else if (dl->position + bytes >= dl->size) { char *tmp = dl->buffer; @@ -107,25 +109,26 @@ static size_t recv_func (void *ptr, size_t size, size_t nmemb, void *stream) { new_size = MAX_DLSIZE; if (dl->position + bytes >= new_size) goto oversize; - dl->buffer = Z_Malloc (new_size); - memcpy (dl->buffer, tmp, dl->size); - Z_Free (tmp); + dl->buffer = Z_Malloc(new_size); + memcpy(dl->buffer, tmp, dl->size); + Z_Free(tmp); dl->size = new_size; } - memcpy (dl->buffer + dl->position, ptr, bytes); + memcpy(dl->buffer + dl->position, ptr, bytes); dl->position += bytes; dl->buffer[dl->position] = 0; return bytes; oversize: - Com_DPrintf ("[HTTP] Oversize file while trying to download '%s'\n", dl->url); + Com_DPrintf("[HTTP] Oversize file while trying to download '%s'\n", dl->url); return 0; } // libcurl callback to update header info. -static size_t header_func (void *ptr, size_t size, size_t nmemb, void *stream) { +static size_t header_func(void *ptr, size_t size, size_t nmemb, void *stream) +{ size_t len, bytes = size * nmemb; dlhandle_t *dl = (dlhandle_t *)stream; char buffer[64]; @@ -136,36 +139,37 @@ static size_t header_func (void *ptr, size_t size, size_t nmemb, void *stream) { if (bytes <= 16) return bytes; - if (bytes > sizeof(buffer)-1) - bytes = sizeof(buffer)-1; + if (bytes > sizeof(buffer) - 1) + bytes = sizeof(buffer) - 1; - memcpy (buffer, ptr, bytes); + memcpy(buffer, ptr, bytes); buffer[bytes] = 0; - if (!Q_strncasecmp (buffer, "Content-Length: ", 16)) { + if (!Q_strncasecmp(buffer, "Content-Length: ", 16)) { //allocate buffer based on what the server claims content-length is. +1 for nul - len = strtoul (buffer + 16, NULL, 10); + len = strtoul(buffer + 16, NULL, 10); if (len >= MAX_DLSIZE) { - Com_DPrintf ("[HTTP] Oversize file while trying to download '%s'\n", dl->url); + Com_DPrintf("[HTTP] Oversize file while trying to download '%s'\n", dl->url); return 0; } dl->size = len + 1; - dl->buffer = Z_Malloc (dl->size); + dl->buffer = Z_Malloc(dl->size); } return bytes; } #ifdef _DEBUG -static int debug_func (CURL *c, curl_infotype type, char *data, size_t size, void * ptr) { +static int debug_func(CURL *c, curl_infotype type, char *data, size_t size, void * ptr) +{ char buffer[MAXPRINTMSG]; if (type == CURLINFO_TEXT) { - if (size > sizeof(buffer)-1) - size = sizeof(buffer)-1; - memcpy (buffer, data, size); + if (size > sizeof(buffer) - 1) + size = sizeof(buffer) - 1; + memcpy(buffer, data, size); buffer[size] = 0; - Com_LPrintf (PRINT_DEVELOPER, "[HTTP] %s\n", buffer); + Com_LPrintf(PRINT_DEVELOPER, "[HTTP] %s\n", buffer); } return 0; @@ -175,16 +179,17 @@ static int debug_func (CURL *c, curl_infotype type, char *data, size_t size, voi // Properly escapes a path with HTTP %encoding. libcurl's function // seems to treat '/' and such as illegal chars and encodes almost // the entire url... -static void escape_path (const char *path, char *escaped) { +static void escape_path(const char *path, char *escaped) +{ static const char allowed[] = ";/?:@&=+$,[]-_.!~*'()"; int c; char *p; p = escaped; - while(*path) { + while (*path) { c = *path++; - if (!Q_isalnum (c) && !strchr(allowed, c)) { - sprintf (p, "%%%02x", c); + if (!Q_isalnum(c) && !strchr(allowed, c)) { + sprintf(p, "%%%02x", c); p += 3; } else { *p++ = c; @@ -194,51 +199,52 @@ static void escape_path (const char *path, char *escaped) { } // Actually starts a download by adding it to the curl multi handle. -static void start_download (dlqueue_t *entry, dlhandle_t *dl) { +static void start_download(dlqueue_t *entry, dlhandle_t *dl) +{ size_t len; char temp[MAX_QPATH]; - char escaped[MAX_QPATH*4]; + char escaped[MAX_QPATH * 4]; CURLMcode ret; qerror_t err; - + //yet another hack to accomodate filelists, how i wish i could push :( //NULL file handle indicates filelist. if (entry->type == DL_LIST) { dl->file = NULL; dl->path[0] = 0; - escape_path (entry->path, escaped); + escape_path(entry->path, escaped); } else { - len = Q_snprintf (dl->path, sizeof(dl->path), "%s/%s.tmp", fs_gamedir, entry->path); + len = Q_snprintf(dl->path, sizeof(dl->path), "%s/%s.tmp", fs_gamedir, entry->path); if (len >= sizeof(dl->path)) { - Com_EPrintf ("[HTTP] Refusing oversize temporary file path.\n"); + Com_EPrintf("[HTTP] Refusing oversize temporary file path.\n"); goto fail; } // FIXME: should use baseq2 instead of empty gamedir? - len = Q_snprintf (temp, sizeof(temp), "%s/%s", fs_game->string, entry->path); + len = Q_snprintf(temp, sizeof(temp), "%s/%s", fs_game->string, entry->path); if (len >= sizeof(temp)) { - Com_EPrintf ("[HTTP] Refusing oversize server file path.\n"); + Com_EPrintf("[HTTP] Refusing oversize server file path.\n"); goto fail; } - escape_path (temp, escaped); + escape_path(temp, escaped); - err = FS_CreatePath (dl->path); + err = FS_CreatePath(dl->path); if (err < 0) { - Com_EPrintf ("[HTTP] Couldn't create path to '%s': %s\n", dl->path, Q_ErrorString (err)); + Com_EPrintf("[HTTP] Couldn't create path to '%s': %s\n", dl->path, Q_ErrorString(err)); goto fail; } //don't bother with http resume... too annoying if server doesn't support it. - dl->file = fopen (dl->path, "wb"); + dl->file = fopen(dl->path, "wb"); if (!dl->file) { - Com_EPrintf ("[HTTP] Couldn't open '%s' for writing: %s\n", dl->path, strerror (errno)); + Com_EPrintf("[HTTP] Couldn't open '%s' for writing: %s\n", dl->path, strerror(errno)); goto fail; } } - len = Q_snprintf (dl->url, sizeof(dl->url), "%s%s", download_server, escaped); + len = Q_snprintf(dl->url, sizeof(dl->url), "%s%s", download_server, escaped); if (len >= sizeof(dl->url)) { - Com_EPrintf ("[HTTP] Refusing oversize download URL.\n"); + Com_EPrintf("[HTTP] Refusing oversize download URL.\n"); goto fail; } @@ -247,50 +253,50 @@ static void start_download (dlqueue_t *entry, dlhandle_t *dl) { dl->position = 0; dl->queue = entry; if (!dl->curl) - dl->curl = curl_easy_init (); + dl->curl = curl_easy_init(); - curl_easy_setopt (dl->curl, CURLOPT_ENCODING, ""); + curl_easy_setopt(dl->curl, CURLOPT_ENCODING, ""); #ifdef _DEBUG if (cl_http_debug->integer) { - curl_easy_setopt (dl->curl, CURLOPT_DEBUGFUNCTION, debug_func); - curl_easy_setopt (dl->curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt(dl->curl, CURLOPT_DEBUGFUNCTION, debug_func); + curl_easy_setopt(dl->curl, CURLOPT_VERBOSE, 1); } #endif - curl_easy_setopt (dl->curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(dl->curl, CURLOPT_NOPROGRESS, 0); if (dl->file) { - curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl->file); - curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt (dl->curl, CURLOPT_WRITEHEADER, NULL); - curl_easy_setopt (dl->curl, CURLOPT_HEADERFUNCTION, NULL); + curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file); + curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL); + curl_easy_setopt(dl->curl, CURLOPT_WRITEHEADER, NULL); + curl_easy_setopt(dl->curl, CURLOPT_HEADERFUNCTION, NULL); } else { - curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl); - curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, recv_func); - curl_easy_setopt (dl->curl, CURLOPT_WRITEHEADER, dl); - curl_easy_setopt (dl->curl, CURLOPT_HEADERFUNCTION, header_func); - } - curl_easy_setopt (dl->curl, CURLOPT_FAILONERROR, 1); - curl_easy_setopt (dl->curl, CURLOPT_PROXY, cl_http_proxy->string); - curl_easy_setopt (dl->curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt (dl->curl, CURLOPT_MAXREDIRS, 5); - curl_easy_setopt (dl->curl, CURLOPT_PROGRESSFUNCTION, progress_func); - curl_easy_setopt (dl->curl, CURLOPT_PROGRESSDATA, dl); - curl_easy_setopt (dl->curl, CURLOPT_USERAGENT, com_version->string); - curl_easy_setopt (dl->curl, CURLOPT_REFERER, download_referer); - curl_easy_setopt (dl->curl, CURLOPT_URL, dl->url); - - ret = curl_multi_add_handle (curl_multi, dl->curl); + curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl); + curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, recv_func); + curl_easy_setopt(dl->curl, CURLOPT_WRITEHEADER, dl); + curl_easy_setopt(dl->curl, CURLOPT_HEADERFUNCTION, header_func); + } + curl_easy_setopt(dl->curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string); + curl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5); + curl_easy_setopt(dl->curl, CURLOPT_PROGRESSFUNCTION, progress_func); + curl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl); + curl_easy_setopt(dl->curl, CURLOPT_USERAGENT, com_version->string); + curl_easy_setopt(dl->curl, CURLOPT_REFERER, download_referer); + curl_easy_setopt(dl->curl, CURLOPT_URL, dl->url); + + ret = curl_multi_add_handle(curl_multi, dl->curl); if (ret != CURLM_OK) { - Com_EPrintf ("[HTTP] Failed to add download handle: %s\n", - curl_multi_strerror (ret)); + Com_EPrintf("[HTTP] Failed to add download handle: %s\n", + curl_multi_strerror(ret)); fail: - CL_FinishDownload( entry ); + CL_FinishDownload(entry); // see if we have more to dl - CL_RequestNextDownload (); + CL_RequestNextDownload(); return; } - Com_DPrintf ("[HTTP] Fetching %s...\n", dl->url); + Com_DPrintf("[HTTP] Fetching %s...\n", dl->url); entry->state = DL_RUNNING; curl_handles++; } @@ -302,7 +308,8 @@ HTTP_CleanupDownloads Disconnected from server, or fatal HTTP error occured. Clean up. =============== */ -void HTTP_CleanupDownloads (void) { +void HTTP_CleanupDownloads(void) +{ dlhandle_t *dl; int i; @@ -314,20 +321,20 @@ void HTTP_CleanupDownloads (void) { dl = &download_handles[i]; if (dl->file) { - fclose (dl->file); - remove (dl->path); + fclose(dl->file); + remove(dl->path); dl->file = NULL; } if (dl->buffer) { - Z_Free (dl->buffer); + Z_Free(dl->buffer); dl->buffer = NULL; } if (dl->curl) { if (curl_multi) - curl_multi_remove_handle (curl_multi, dl->curl); - curl_easy_cleanup (dl->curl); + curl_multi_remove_handle(curl_multi, dl->curl); + curl_easy_cleanup(dl->curl); dl->curl = NULL; } @@ -335,7 +342,7 @@ void HTTP_CleanupDownloads (void) { } if (curl_multi) { - curl_multi_cleanup (curl_multi); + curl_multi_cleanup(curl_multi); curl_multi = NULL; } } @@ -348,28 +355,30 @@ HTTP_Init Init libcurl and multi handle. =============== */ -void HTTP_Init (void) { - cl_http_downloads = Cvar_Get ("cl_http_downloads", "1", 0); - cl_http_filelists = Cvar_Get ("cl_http_filelists", "1", 0); - cl_http_max_connections = Cvar_Get ("cl_http_max_connections", "2", 0); +void HTTP_Init(void) +{ + cl_http_downloads = Cvar_Get("cl_http_downloads", "1", 0); + cl_http_filelists = Cvar_Get("cl_http_filelists", "1", 0); + cl_http_max_connections = Cvar_Get("cl_http_max_connections", "2", 0); //cl_http_max_connections->changed = _cl_http_max_connections_changed; - cl_http_proxy = Cvar_Get ("cl_http_proxy", "", 0); + cl_http_proxy = Cvar_Get("cl_http_proxy", "", 0); #ifdef _DEBUG - cl_http_debug = Cvar_Get ("cl_http_debug", "0", 0); + cl_http_debug = Cvar_Get("cl_http_debug", "0", 0); #endif - curl_global_init (CURL_GLOBAL_NOTHING); + curl_global_init(CURL_GLOBAL_NOTHING); curl_initialized = qtrue; - Com_DPrintf ("%s initialized.\n", curl_version()); + Com_DPrintf("%s initialized.\n", curl_version()); } -void HTTP_Shutdown (void) { +void HTTP_Shutdown(void) +{ if (!curl_initialized) return; HTTP_CleanupDownloads(); - curl_global_cleanup (); + curl_global_cleanup(); curl_initialized = qfalse; } @@ -381,9 +390,10 @@ HTTP_SetServer A new server is specified, so we nuke all our state. =============== */ -void HTTP_SetServer (const char *url) { +void HTTP_SetServer(const char *url) +{ if (curl_multi) { - Com_EPrintf ("[HTTP] Set server without cleanup?\n"); + Com_EPrintf("[HTTP] Set server without cleanup?\n"); return; } @@ -394,18 +404,18 @@ void HTTP_SetServer (const char *url) { if (allow_download->integer == -1) return; - if (strncmp (url, "http://", 7)) { - Com_Printf ("[HTTP] Ignoring download server URL with non-HTTP schema.\n"); + if (strncmp(url, "http://", 7)) { + Com_Printf("[HTTP] Ignoring download server URL with non-HTTP schema.\n"); return; } - curl_multi = curl_multi_init (); + curl_multi = curl_multi_init(); - Q_strlcpy (download_server, url, sizeof(download_server)); - Q_snprintf (download_referer, sizeof(download_referer), - "quake2://%s", NET_AdrToString (&cls.serverAddress)); + Q_strlcpy(download_server, url, sizeof(download_server)); + Q_snprintf(download_referer, sizeof(download_referer), + "quake2://%s", NET_AdrToString(&cls.serverAddress)); - Com_Printf ("[HTTP] Download server at %s\n", download_server); + Com_Printf("[HTTP] Download server at %s\n", download_server); } /* @@ -416,7 +426,8 @@ Called from the precache check to queue a download. Return value of Q_ERR_NOSYS will cause standard UDP downloading to be used instead. =============== */ -qerror_t HTTP_QueueDownload (const char *path, dltype_t type) { +qerror_t HTTP_QueueDownload(const char *path, dltype_t type) +{ size_t len; qboolean need_list; char temp[MAX_QPATH]; @@ -427,9 +438,9 @@ qerror_t HTTP_QueueDownload (const char *path, dltype_t type) { return Q_ERR_NOSYS; // first download queued, so we want the mod filelist - need_list = LIST_EMPTY (&cls.download.queue); + need_list = LIST_EMPTY(&cls.download.queue); - ret = CL_QueueDownload (path, type); + ret = CL_QueueDownload(path, type); if (ret) { return ret; } @@ -439,9 +450,9 @@ qerror_t HTTP_QueueDownload (const char *path, dltype_t type) { if (need_list) { //grab the filelist - len = Q_snprintf (temp, sizeof(temp), "%s.filelist", fs_game->string); + len = Q_snprintf(temp, sizeof(temp), "%s.filelist", fs_game->string); if (len < sizeof(temp)) - CL_QueueDownload (temp, DL_LIST); + CL_QueueDownload(temp, DL_LIST); //this is a nasty hack to let the server know what we're doing so admins don't //get confused by a ton of people stuck in CNCT state. it's assumed the server @@ -451,12 +462,12 @@ qerror_t HTTP_QueueDownload (const char *path, dltype_t type) { } //special case for map file lists, i really wanted a server-push mechanism for this, but oh well - len = strlen (path); - if (len > 4 && !Q_stricmp (path + len - 4, ".bsp")) { - len = Q_snprintf (temp, sizeof(temp), "%s/%s", fs_game->string, path); + len = strlen(path); + if (len > 4 && !Q_stricmp(path + len - 4, ".bsp")) { + len = Q_snprintf(temp, sizeof(temp), "%s/%s", fs_game->string, path); if (len + 5 < sizeof(temp)) { - memcpy (temp + len - 4, ".filelist", 10); - CL_QueueDownload (temp, DL_LIST); + memcpy(temp + len - 4, ".filelist", 10); + CL_QueueDownload(temp, DL_LIST); } } @@ -464,7 +475,8 @@ qerror_t HTTP_QueueDownload (const char *path, dltype_t type) { } // Validate a path supplied by a filelist. -static void check_and_queue_download (char *path) { +static void check_and_queue_download(char *path) +{ size_t len; char *ext; dltype_t type; @@ -474,7 +486,7 @@ static void check_and_queue_download (char *path) { if (len >= MAX_QPATH) return; - ext = strrchr (path, '.'); + ext = strrchr(path, '.'); if (!ext) return; @@ -482,22 +494,22 @@ static void check_and_queue_download (char *path) { if (!ext[0]) return; - Q_strlwr (ext); + Q_strlwr(ext); - if (!strcmp (ext, "pak") || !strcmp (ext, "pkz")) { - Com_Printf ("[HTTP] Filelist is requesting a .%s file '%s'\n", ext, path); + if (!strcmp(ext, "pak") || !strcmp(ext, "pkz")) { + Com_Printf("[HTTP] Filelist is requesting a .%s file '%s'\n", ext, path); type = DL_PAK; } else { type = DL_OTHER; if (!CL_CheckDownloadExtension(ext)) { - Com_WPrintf ("[HTTP] Illegal file type '%s' in filelist.\n", path); + Com_WPrintf("[HTTP] Illegal file type '%s' in filelist.\n", path); return; } } - if (path[0] == '@'){ + if (path[0] == '@') { if (type == DL_PAK) { - Com_WPrintf ("[HTTP] '@' prefix used on a pak file '%s' in filelist.\n", path); + Com_WPrintf("[HTTP] '@' prefix used on a pak file '%s' in filelist.\n", path); return; } flags = FS_PATH_GAME; @@ -505,72 +517,74 @@ static void check_and_queue_download (char *path) { len--; } else if (type == DL_PAK) { //by definition paks are game-local - flags = FS_PATH_GAME|FS_TYPE_REAL; + flags = FS_PATH_GAME | FS_TYPE_REAL; } else { flags = 0; } - len = FS_NormalizePath (path, path); + len = FS_NormalizePath(path, path); if (len == 0 || - !Q_ispath (path[0]) || - !Q_ispath (path[len-1]) || - !FS_ValidatePath (path) || - strstr (path, "..") || - (type == DL_OTHER && !strchr (path, '/')) || - (type == DL_PAK && strchr(path, '/'))) - { - Com_WPrintf ("[HTTP] Illegal path '%s' in filelist.\n", path); + !Q_ispath(path[0]) || + !Q_ispath(path[len - 1]) || + !FS_ValidatePath(path) || + strstr(path, "..") || + (type == DL_OTHER && !strchr(path, '/')) || + (type == DL_PAK && strchr(path, '/'))) { + Com_WPrintf("[HTTP] Illegal path '%s' in filelist.\n", path); return; } - if (!FS_FileExistsEx (path, flags)) { - CL_QueueDownload (path, type); + if (!FS_FileExistsEx(path, flags)) { + CL_QueueDownload(path, type); } } // A filelist is in memory, scan and validate it and queue up the files. -static void parse_file_list (dlhandle_t *dl) { +static void parse_file_list(dlhandle_t *dl) +{ char *list; char *p; if (cl_http_filelists->integer) { list = dl->buffer; while (1) { - p = strchr (list, '\n'); + p = strchr(list, '\n'); if (p) { if (p > list && *(p - 1) == '\r') *(p - 1) = 0; *p = 0; if (*list) - check_and_queue_download (list); + check_and_queue_download(list); list = p + 1; } else { if (*list) - check_and_queue_download (list); + check_and_queue_download(list); break; } } } - Z_Free (dl->buffer); + Z_Free(dl->buffer); dl->buffer = NULL; } // A pak file just downloaded, let's see if we can remove some stuff from // the queue which is in the .pak. -static void rescan_queue (void) { +static void rescan_queue(void) +{ dlqueue_t *q; - FOR_EACH_DLQ (q) { - if (q->state == DL_PENDING && q->type < DL_LIST && FS_FileExists (q->path)) - CL_FinishDownload (q); + FOR_EACH_DLQ(q) { + if (q->state == DL_PENDING && q->type < DL_LIST && FS_FileExists(q->path)) + CL_FinishDownload(q); } } // Fatal HTTP error occured, remove any special entries from // queue and fall back to UDP downloading. -static void abort_downloads (void) { +static void abort_downloads(void) +{ dlqueue_t *q; HTTP_CleanupDownloads(); @@ -578,19 +592,20 @@ static void abort_downloads (void) { cls.download.current = NULL; cls.download.percent = 0; - FOR_EACH_DLQ (q) { + FOR_EACH_DLQ(q) { if (q->state != DL_DONE && q->type >= DL_LIST) - CL_FinishDownload (q); + CL_FinishDownload(q); else if (q->state == DL_RUNNING) q->state = DL_PENDING; } - CL_RequestNextDownload (); - CL_StartNextDownload (); + CL_RequestNextDownload(); + CL_StartNextDownload(); } // curl doesn't provide reverse-lookup of the void * ptr, so search for it -static dlhandle_t *find_handle (CURL *curl) { +static dlhandle_t *find_handle(CURL *curl) +{ size_t i; dlhandle_t *dl; @@ -601,10 +616,11 @@ static dlhandle_t *find_handle (CURL *curl) { } } - Com_Error (ERR_FATAL, "CURL handle not found for CURLMSG_DONE"); + Com_Error(ERR_FATAL, "CURL handle not found for CURLMSG_DONE"); } -static const char *http_strerror (int response) { +static const char *http_strerror(int response) +{ static char buffer[32]; //common codes @@ -624,21 +640,21 @@ static const char *http_strerror (int response) { } if (response < 100 || response >= 600) { - Q_snprintf (buffer, sizeof (buffer), "%d <bad code>", response); + Q_snprintf(buffer, sizeof(buffer), "%d <bad code>", response); return buffer; } //generic classes if (response < 200) { - Q_snprintf (buffer, sizeof (buffer), "%d Informational", response); + Q_snprintf(buffer, sizeof(buffer), "%d Informational", response); } else if (response < 300) { - Q_snprintf (buffer, sizeof (buffer), "%d Success", response); + Q_snprintf(buffer, sizeof(buffer), "%d Success", response); } else if (response < 400) { - Q_snprintf (buffer, sizeof (buffer), "%d Redirection", response); + Q_snprintf(buffer, sizeof(buffer), "%d Redirection", response); } else if (response < 500) { - Q_snprintf (buffer, sizeof (buffer), "%d Client Error", response); + Q_snprintf(buffer, sizeof(buffer), "%d Client Error", response); } else { - Q_snprintf (buffer, sizeof (buffer), "%d Server Error", response); + Q_snprintf(buffer, sizeof(buffer), "%d Server Error", response); } return buffer; @@ -646,7 +662,8 @@ static const char *http_strerror (int response) { // A download finished, find out what it was, whether there were any errors and // if so, how severe. If none, rename file and other such stuff. -static qboolean finish_download (void) { +static qboolean finish_download(void) +{ int msgs_in_queue; CURLMsg *msg; CURLcode result; @@ -661,7 +678,7 @@ static qboolean finish_download (void) { print_type_t level; do { - msg = curl_multi_info_read (curl_multi, &msgs_in_queue); + msg = curl_multi_info_read(curl_multi, &msgs_in_queue); if (!msg) break; @@ -669,14 +686,14 @@ static qboolean finish_download (void) { continue; curl = msg->easy_handle; - dl = find_handle (curl); + dl = find_handle(curl); cls.download.current = NULL; cls.download.percent = 0; //filelist processing is done on read if (dl->file) { - fclose (dl->file); + fclose(dl->file); dl->file = NULL; } @@ -685,16 +702,16 @@ static qboolean finish_download (void) { result = msg->data.result; switch (result) { - //for some reason curl returns CURLE_OK for a 404... + //for some reason curl returns CURLE_OK for a 404... case CURLE_HTTP_RETURNED_ERROR: case CURLE_OK: - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); if (result == CURLE_OK && response == 200) { //success break; } - err = http_strerror (response); + err = http_strerror(response); //404 is non-fatal if (response == 404) { @@ -713,73 +730,73 @@ static qboolean finish_download (void) { case CURLE_COULDNT_CONNECT: case CURLE_COULDNT_RESOLVE_PROXY: //connection problems are fatal - err = curl_easy_strerror (result); + err = curl_easy_strerror(result); level = PRINT_ERROR; fatal_error = qtrue; goto fail2; default: - err = curl_easy_strerror (result); + err = curl_easy_strerror(result); level = PRINT_WARNING; fail1: //we mark download as done even if it errored //to prevent multiple attempts. - CL_FinishDownload (dl->queue); + CL_FinishDownload(dl->queue); fail2: - Com_LPrintf (level, - "[HTTP] %s [%s] [%d remaining file%s]\n", - dl->queue->path, err, cls.download.pending, - cls.download.pending == 1 ? "" : "s"); + Com_LPrintf(level, + "[HTTP] %s [%s] [%d remaining file%s]\n", + dl->queue->path, err, cls.download.pending, + cls.download.pending == 1 ? "" : "s"); if (dl->path[0]) { - remove (dl->path); + remove(dl->path); dl->path[0] = 0; } if (dl->buffer) { - Z_Free (dl->buffer); + Z_Free(dl->buffer); dl->buffer = NULL; } - curl_multi_remove_handle (curl_multi, curl); + curl_multi_remove_handle(curl_multi, curl); continue; } //mark as done - CL_FinishDownload (dl->queue); + CL_FinishDownload(dl->queue); //show some stats - curl_easy_getinfo (curl, CURLINFO_TOTAL_TIME, &sec); - curl_easy_getinfo (curl, CURLINFO_SIZE_DOWNLOAD, &bytes); + curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &sec); + curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &bytes); if (sec < 0.001) sec = 0.001; - Com_FormatSizeLong (size, sizeof (size), bytes); - Com_FormatSizeLong (speed, sizeof (speed), bytes / sec); + Com_FormatSizeLong(size, sizeof(size), bytes); + Com_FormatSizeLong(speed, sizeof(speed), bytes / sec); //FIXME: //technically i shouldn't need to do this as curl will auto reuse the //existing handle when you change the url. however, the curl_handles goes //all weird when reusing a download slot in this way. if you can figure //out why, please let me know. - curl_multi_remove_handle (curl_multi, curl); + curl_multi_remove_handle(curl_multi, curl); - Com_Printf ("[HTTP] %s [%s, %s/sec] [%d remaining file%s]\n", - dl->queue->path, size, speed, cls.download.pending, - cls.download.pending == 1 ? "" : "s"); + Com_Printf("[HTTP] %s [%s, %s/sec] [%d remaining file%s]\n", + dl->queue->path, size, speed, cls.download.pending, + cls.download.pending == 1 ? "" : "s"); if (dl->path[0]) { //rename the temp file - Q_snprintf (temp, sizeof(temp), "%s/%s", fs_gamedir, dl->queue->path); + Q_snprintf(temp, sizeof(temp), "%s/%s", fs_gamedir, dl->queue->path); - if (rename (dl->path, temp)) - Com_EPrintf ("[HTTP] Failed to rename '%s' to '%s': %s\n", - dl->path, dl->queue->path, strerror (errno)); + if (rename(dl->path, temp)) + Com_EPrintf("[HTTP] Failed to rename '%s' to '%s': %s\n", + dl->path, dl->queue->path, strerror(errno)); dl->path[0] = 0; //a pak file is very special... if (dl->queue->type == DL_PAK) { - CL_RestartFilesystem (qfalse); - rescan_queue (); + CL_RestartFilesystem(qfalse); + rescan_queue(); } } else if (!fatal_error) { - parse_file_list (dl); + parse_file_list(dl); } } while (msgs_in_queue > 0); @@ -790,12 +807,13 @@ fail2: } // see if we have more to dl - CL_RequestNextDownload (); + CL_RequestNextDownload(); return qtrue; } // Find a free download handle to start another queue entry on. -static dlhandle_t *get_free_handle (void) { +static dlhandle_t *get_free_handle(void) +{ dlhandle_t *dl; int i; @@ -809,7 +827,8 @@ static dlhandle_t *get_free_handle (void) { } // Start another HTTP download if possible. -static void start_next_download (void) { +static void start_next_download(void) +{ dlqueue_t *q; if (!cls.download.pending || curl_handles >= cl_http_max_connections->integer) { @@ -817,14 +836,14 @@ static void start_next_download (void) { } //not enough downloads running, queue some more! - FOR_EACH_DLQ (q) { + FOR_EACH_DLQ(q) { if (q->state == DL_RUNNING) { if (q->type == DL_PAK) break; // hack for pak file single downloading } else if (q->state == DL_PENDING) { dlhandle_t *dl = get_free_handle(); if (dl) - start_download (q, dl); + start_download(q, dl); break; } } @@ -839,32 +858,33 @@ connecting to minimise latency. Also starts new downloads if we're not doing the maximum already. =============== */ -void HTTP_RunDownloads (void) { +void HTTP_RunDownloads(void) +{ int new_count; CURLMcode ret; if (!curl_multi) return; - start_next_download (); + start_next_download(); do { - ret = curl_multi_perform (curl_multi, &new_count); + ret = curl_multi_perform(curl_multi, &new_count); if (new_count < curl_handles) { //hmm, something either finished or errored out. - if (!finish_download ()) + if (!finish_download()) return; //aborted curl_handles = new_count; } } while (ret == CURLM_CALL_MULTI_PERFORM); if (ret != CURLM_OK) { - Com_EPrintf ("[HTTP] Error running downloads: %s.\n", - curl_multi_strerror(ret)); + Com_EPrintf("[HTTP] Error running downloads: %s.\n", + curl_multi_strerror(ret)); abort_downloads(); return; } - start_next_download (); + start_next_download(); } |