void shoes_download(shoes_http_request *req) { HANDLE file = INVALID_HANDLE_VALUE; INTERNET_PORT _port = req->port; LPWSTR _method = NULL, _body = NULL; LPWSTR _scheme = SHOE_ALLOC_N(WCHAR, MAX_PATH); LPWSTR _host = SHOE_ALLOC_N(WCHAR, MAX_PATH); LPWSTR _path = SHOE_ALLOC_N(WCHAR, MAX_PATH); DWORD _size; MultiByteToWideChar(CP_UTF8, 0, req->scheme, -1, _scheme, MAX_PATH); MultiByteToWideChar(CP_UTF8, 0, req->host, -1, _host, MAX_PATH); MultiByteToWideChar(CP_UTF8, 0, req->path, -1, _path, MAX_PATH); if (req->method != NULL) { _method = SHOE_ALLOC_N(WCHAR, MAX_PATH); MultiByteToWideChar(CP_UTF8, 0, req->method, -1, _method, MAX_PATH); } if (req->mem == NULL && req->filepath != NULL) file = CreateFile(req->filepath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); shoes_winhttp(_scheme, _host, _port, _path, _method, req->headers, (LPVOID)req->body, req->bodylen, &req->mem, req->memlen, file, &_size, req->flags, req->handler, req->data); req->size = _size; SHOE_FREE(_scheme); SHOE_FREE(_host); SHOE_FREE(_path); if (_method != NULL) SHOE_FREE(_method); }
SHOES_DOWNLOAD_HEADERS shoes_http_headers(VALUE hsh) { long i; LPWSTR hdrs = NULL; VALUE keys = rb_funcall(hsh, s_keys, 0); if (RARRAY_LEN(keys) > 0) { VALUE headers = rb_str_new2(""); //for (i = 0; i < RARRAY(keys)->as.heap.len; i++ ) for (i = 0; i < RARRAY_LEN(keys); i++ ) { VALUE key = rb_ary_entry(keys, i); rb_str_append(headers, key); rb_str_cat2(headers, ": "); rb_str_append(headers, rb_hash_aref(hsh, key)); rb_str_cat2(headers, "\n"); } hdrs = SHOE_ALLOC_N(WCHAR, RSTRING_LEN(headers) + 1); SHOE_MEMZERO(hdrs, WCHAR, RSTRING_LEN(headers) + 1); MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(headers), -1, hdrs, RSTRING_LEN(headers) + 1); } return hdrs; }
DWORD WINAPI shoes_download_thread(IN DWORD mid, IN WPARAM w, LPARAM &l, IN LPVOID data) { DWORD len = 0; WCHAR path[BUFSIZE]; TCHAR *buf = SHOE_ALLOC_N(TCHAR, BUFSIZE); TCHAR *empty = NULL; HANDLE file; TCHAR *nl; TCHAR setup_path[BUFSIZE]; GetTempPath(BUFSIZE, setup_path); strncat(setup_path, setup_exe, strlen(setup_exe)); shoes_winhttp(L"hacketyhack.net", 80, L"/pkg/win32/shoes", &buf, BUFSIZE, INVALID_HANDLE_VALUE, &len, NULL, NULL); if (len == 0) return 0; nl = strstr(buf, "\n"); if (nl) nl[0] = '\0'; len = 0; MultiByteToWideChar(CP_ACP, 0, buf, -1, path, BUFSIZE); file = CreateFile(setup_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); shoes_winhttp(L"hacketyhack.net", 80, path, &empty, 0, file, &len, HTTP_HANDLER(StubDownloadingShoes), NULL); CloseHandle(file); shoes_silent_install(setup_path); return 0; }
void shoes_download(shoes_download_request *req) { HANDLE file = INVALID_HANDLE_VALUE; INTERNET_PORT _port = req->port; LPWSTR _host = SHOE_ALLOC_N(WCHAR, MAX_PATH); LPWSTR _path = SHOE_ALLOC_N(WCHAR, MAX_PATH); DWORD _size; MultiByteToWideChar(CP_UTF8, 0, req->host, -1, _host, MAX_PATH); MultiByteToWideChar(CP_UTF8, 0, req->path, -1, _path, MAX_PATH); if (req->mem == NULL && req->filepath != NULL) file = CreateFile(req->filepath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); shoes_winhttp(_host, _port, _path, &req->mem, req->memlen, file, &_size, req->handler, req->data); req->size = _size; SHOE_FREE(_host); SHOE_FREE(_path); }
void shoes_winhttp(LPCWSTR host, INTERNET_PORT port, LPCWSTR path, TCHAR **mem, ULONG memlen, HANDLE file, LPDWORD size, shoes_download_handler handler, void *data) { DWORD len = 0, rlen = 0, status = 0, complete = 0, flen = 0, total = 0, written = 0; LPTSTR buf = SHOE_ALLOC_N(TCHAR, SHOES_BUFSIZE); LPTSTR fbuf = SHOE_ALLOC_N(TCHAR, SHOES_CHUNKSIZE); LPWSTR uagent = SHOE_ALLOC_N(WCHAR, SHOES_BUFSIZE); HINTERNET sess = NULL, conn = NULL, req = NULL; SHOES_TIME last = 0; if (buf == NULL || fbuf == NULL || uagent == NULL) goto done; _snwprintf(uagent, SHOES_BUFSIZE, L"Shoes/0.r%d (%S) %S/%d", SHOES_REVISION, SHOES_PLATFORM, SHOES_RELEASE_NAME, SHOES_BUILD_DATE); sess = WinHttpOpen(uagent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (sess == NULL) goto done; conn = WinHttpConnect(sess, host, port, 0); if (conn == NULL) goto done; req = WinHttpOpenRequest(conn, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (req == NULL) goto done; if (!WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0)) goto done; if (!WinHttpReceiveResponse(req, NULL)) goto done; len = sizeof(DWORD); if (!WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &len, NULL)) goto done; else { shoes_download_event event; event.stage = SHOES_HTTP_STATUS; event.status = status; if (handler != NULL) handler(&event, data); } shoes_winhttp_headers(req, handler, data); *size = 0; len = sizeof(buf); if (WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, buf, &len, NULL)) { *size = _wtoi((wchar_t *)buf); if (*mem != NULL && *size > memlen) { SHOE_REALLOC_N(*mem, char, (memlen = *size)); if (*mem == NULL) goto done; }
void shoes_winhttp_headers(HINTERNET req, shoes_download_handler handler, void *data) { DWORD size; WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, WINHTTP_NO_HEADER_INDEX); if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { int whdrlen = 0, hdrlen = 0; LPCWSTR whdr; LPSTR hdr = SHOE_ALLOC_N(CHAR, MAX_PATH); LPCWSTR hdrs = SHOE_ALLOC_N(WCHAR, size/sizeof(WCHAR)); BOOL res = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, WINHTTP_HEADER_NAME_BY_INDEX, (LPVOID)hdrs, &size, WINHTTP_NO_HEADER_INDEX); if (res) { for (whdr = hdrs; whdr - hdrs < size / sizeof(WCHAR); whdr += whdrlen) { WideCharToMultiByte(CP_UTF8, 0, whdr, -1, hdr, MAX_PATH, NULL, NULL); hdrlen = strlen(hdr); HTTP_HEADER(hdr, hdrlen, handler, data); whdrlen = wcslen(whdr) + 1; } } SHOE_FREE(hdrs); SHOE_FREE(hdr); } }