00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "http.h"
00022 #include "../shared/shared.h"
00023
00027 size_t HTTP_Header (void *ptr, size_t size, size_t nmemb, void *stream)
00028 {
00029 char headerBuff[1024];
00030 size_t bytes;
00031 size_t len;
00032
00033 bytes = size * nmemb;
00034
00035 if (bytes <= 16)
00036 return bytes;
00037
00038 if (bytes < sizeof(headerBuff))
00039 len = bytes + 1;
00040 else
00041 len = sizeof(headerBuff);
00042
00043 Q_strncpyz(headerBuff, ptr, len);
00044
00045 if (!Q_strncasecmp(headerBuff, "Content-Length: ", 16)) {
00046 dlhandle_t *dl;
00047
00048 dl = (dlhandle_t *)stream;
00049
00050 if (dl->file)
00051 dl->fileSize = strtoul(headerBuff + 16, NULL, 10);
00052 }
00053
00054 return bytes;
00055 }
00056
00060 size_t HTTP_Recv (void *ptr, size_t size, size_t nmemb, void *stream)
00061 {
00062 size_t bytes;
00063 dlhandle_t *dl;
00064
00065 dl = (dlhandle_t *)stream;
00066
00067 bytes = size * nmemb;
00068
00069 if (!dl->fileSize) {
00070 dl->fileSize = bytes > 131072 ? bytes : 131072;
00071 dl->tempBuffer = Mem_Alloc((int)dl->fileSize);
00072 } else if (dl->position + bytes >= dl->fileSize - 1) {
00073 char *tmp;
00074
00075 tmp = dl->tempBuffer;
00076
00077 dl->tempBuffer = Mem_Alloc((int)(dl->fileSize * 2));
00078 memcpy(dl->tempBuffer, tmp, dl->fileSize);
00079 Mem_Free(tmp);
00080 dl->fileSize *= 2;
00081 }
00082
00083 memcpy(dl->tempBuffer + dl->position, ptr, bytes);
00084 dl->position += bytes;
00085 dl->tempBuffer[dl->position] = 0;
00086
00087 return bytes;
00088 }
00089
00094 char* HTTP_GetURL (const char *url)
00095 {
00096 static qboolean downloading = qfalse;
00097 dlhandle_t dl;
00098
00099 if (downloading) {
00100 Com_Printf("Warning: There is still another download running: '%s'\n", dl.URL);
00101 return NULL;
00102 }
00103
00104 memset(&dl, 0, sizeof(dl));
00105
00106 downloading = qtrue;
00107 dl.curl = curl_easy_init();
00108
00109 Q_strncpyz(dl.URL, url, sizeof(dl.URL));
00110 curl_easy_setopt(dl.curl, CURLOPT_CONNECTTIMEOUT, http_timeout->integer);
00111 curl_easy_setopt(dl.curl, CURLOPT_ENCODING, "");
00112 curl_easy_setopt(dl.curl, CURLOPT_NOPROGRESS, 1);
00113 curl_easy_setopt(dl.curl, CURLOPT_WRITEDATA, &dl);
00114 curl_easy_setopt(dl.curl, CURLOPT_WRITEFUNCTION, HTTP_Recv);
00115 curl_easy_setopt(dl.curl, CURLOPT_PROXY, http_proxy->string);
00116 curl_easy_setopt(dl.curl, CURLOPT_FOLLOWLOCATION, 1);
00117 curl_easy_setopt(dl.curl, CURLOPT_MAXREDIRS, 5);
00118 curl_easy_setopt(dl.curl, CURLOPT_WRITEHEADER, &dl);
00119 curl_easy_setopt(dl.curl, CURLOPT_HEADERFUNCTION, HTTP_Header);
00120 curl_easy_setopt(dl.curl, CURLOPT_USERAGENT, Cvar_GetString("version"));
00121 curl_easy_setopt(dl.curl, CURLOPT_URL, dl.URL);
00122
00123
00124 curl_easy_perform(dl.curl);
00125
00126
00127 curl_easy_cleanup(dl.curl);
00128
00129 downloading = qfalse;
00130
00131 return dl.tempBuffer;
00132 }
00133
00137 void HTTP_Cleanup (void)
00138 {
00139 curl_global_cleanup();
00140 }