HRESULT PROPFINDRequest::perform() { wstring depthProperty; wostringstream ss; BOOL bResults = FALSE; int bodyLength = 0; if (! this->hRequest) return E_INVALIDARG; ss<<L"Depth: "<<depth; depthProperty = ss.str(); //set Depth bodyLength = lstrlen(DEFAULT_PROPFIND)*sizeof(WCHAR); WinHttpAddRequestHeaders(this->hRequest, depthProperty.c_str(), (DWORD)-1, WINHTTP_ADDREQ_FLAG_REPLACE|WINHTTP_ADDREQ_FLAG_ADD); bResults = WinHttpSendRequest(this->hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, DEFAULT_PROPFIND, bodyLength, bodyLength, 0); if (! bResults) return E_FAIL; bResults = WinHttpReceiveResponse(this->hRequest, NULL); this->updateStatus(); return S_OK; }
static int apply_basic_credential(HINTERNET request, git_cred *cred) { git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred; git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT; wchar_t *wide = NULL; int error = -1, wide_len = 0; git_buf_printf(&raw, "%s:%s", c->username, c->password); if (git_buf_oom(&raw) || git_buf_puts(&buf, "Authorization: Basic ") < 0 || git_buf_put_base64(&buf, git_buf_cstr(&raw), raw.size) < 0) goto on_error; wide_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, git_buf_cstr(&buf), -1, NULL, 0); if (!wide_len) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to measure string for wide conversion")); goto on_error; } wide = git__malloc(wide_len * sizeof(wchar_t)); if (!wide) goto on_error; if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, git_buf_cstr(&buf), -1, wide, wide_len)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to convert string to wide form")); goto on_error; } if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to add a header to the request")); goto on_error; } error = 0; on_error: /* We were dealing with plaintext passwords, so clean up after ourselves a bit. */ if (wide) memset(wide, 0x0, wide_len * sizeof(wchar_t)); if (buf.size) memset(buf.ptr, 0x0, buf.size); if (raw.size) memset(raw.ptr, 0x0, raw.size); git__free(wide); git_buf_free(&buf); git_buf_free(&raw); return error; }
//#else void CSinaSvr::PostWeibo(LPCTSTR lpContent) { BOOL bResults= FALSE; HINTERNET hSession = NULL,hConnect = NULL, hRequest = NULL; TCHAR szServer[1024] = _T("weibo.com"); TCHAR szParam[1024] = _T("aj/mblog/add"); TCHAR szHeader[1024] = {0}; TCHAR szCookie[1024] = {0}; _stprintf(szHeader,_T("Accept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://weibo.com/%s\r\nx-requested-with: XMLHttpRequest\r\n"),m_szCurUID); _stprintf(szCookie,_T("Cookie: %s\r\n"),m_strCookie.GetBuffer()); WCHAR szwPost[1024]={0}; _stprintf(szwPost,_T("_t=0&pic_id=&text=%s"),lpContent); char szPost[1024]= {0}; WideCharToMultiByte(CP_UTF8, 0, szwPost, -1, szPost, MAX_PATH, NULL, NULL); PBYTE pBuf = new BYTE[1024*1024]; hSession = WinHttpOpen(0, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if(hSession) WinHttpSetTimeouts( hSession, 600000, 600000, 600000, 600000); if( hSession ) hConnect = WinHttpConnect( hSession,szServer,80, 0 ); if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"POST", szParam, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); int nLen = strlen(szPost); WinHttpAddRequestHeaders( hRequest, szCookie, -1, WINHTTP_ADDREQ_FLAG_ADD); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, szHeader,-1, szPost, nLen,nLen,0); DWORD dwLen; GetHttpResponse(pBuf,dwLen,hRequest); if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); delete []pBuf; PostWeibo1(lpContent); }
bool CWinHttp::AddRequestHeader( _In_ LPCWSTR pwszHeaders, _In_ DWORD dwHeadersLength, _In_ DWORD dwModifiers ) { bool bRet=false; int n; if(!WinHttpAddRequestHeaders(hRequest,pwszHeaders,dwHeadersLength,dwModifiers)) { n=GetLastError(); goto exit0; } bRet=true; exit0: return bRet; }
static int apply_basic_credential(HINTERNET request, git_cred *cred) { git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred; git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT; wchar_t *wide = NULL; int error = -1, wide_len; git_buf_printf(&raw, "%s:%s", c->username, c->password); if (git_buf_oom(&raw) || git_buf_puts(&buf, "Authorization: Basic ") < 0 || git_buf_encode_base64(&buf, git_buf_cstr(&raw), raw.size) < 0) goto on_error; if ((wide_len = git__utf8_to_16_alloc(&wide, git_buf_cstr(&buf))) < 0) { giterr_set(GITERR_OS, "Failed to convert string to wide form"); goto on_error; } if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } error = 0; on_error: /* We were dealing with plaintext passwords, so clean up after ourselves a bit. */ if (wide) memset(wide, 0x0, wide_len * sizeof(wchar_t)); if (buf.size) memset(buf.ptr, 0x0, buf.size); if (raw.size) memset(raw.ptr, 0x0, raw.size); git__free(wide); git_buf_free(&buf); git_buf_free(&raw); return error; }
HRESULT GETRequest::perform() { wstring rangeProperty; wostringstream ss; BOOL bResults = FALSE; if (! this->hRequest) return E_INVALIDARG; if (this->offset > 0 && this->length > 0) { ss<<L"Range: bytes="<<(int)this->offset<<L"-"<<(int)(this->offset+this->length); rangeProperty = ss.str(); WinHttpAddRequestHeaders(this->hRequest, rangeProperty.c_str(), (DWORD)-1, WINHTTP_ADDREQ_FLAG_REPLACE|WINHTTP_ADDREQ_FLAG_ADD); } bResults = WinHttpSendRequest(this->hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); if (! bResults) return E_FAIL; bResults = WinHttpReceiveResponse(this->hRequest, NULL); this->updateStatus(); return S_OK; }
void WindowsHttpDownloader::InternalConnect(char* append_headers) { WCHAR host_name[1024] = {}; if (wcslen(_url.lpszHostName) > 1024) { SetEvent(_events[EventErr]); return; } wcscpy(host_name, _url.lpszHostName); if (wcsstr(host_name, L"/") != NULL) *wcsstr(host_name, L"/") = 0; if (wcsstr(host_name, L":") != NULL) *wcsstr(host_name, L":") = 0; _http.connect = WinHttpConnect(_http.session, host_name, _url.nPort, 0); if (_http.connect == NULL) { SetEvent(_events[EventErr]); return; } SetEvent(_events[EventConnect]); if (_abort_download) return; _http.request = WinHttpOpenRequest(_http.connect, L"GET", _url.dwUrlPathLength > 0 ? _url.lpszUrlPath : NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (_http.connect == NULL) { SetEvent(_events[EventErr]); return; } if (_abort_download) return; DWORD temp = WINHTTP_DISABLE_AUTHENTICATION; WinHttpSetOption(_http.request, WINHTTP_OPTION_DISABLE_FEATURE, &temp, sizeof(temp)); int hcount = _user_heads.size(); for (int i = 0; i < hcount; i++) { WCHAR header[MAX_PATH], hvalue[1024]; header[0] = hvalue[0] = 0; auto h = _user_heads.front(); _user_heads.pop(); AnsiToUnicode(h.name, header); AnsiToUnicode(h.value, hvalue, _countof(hvalue)); h.Free(); auto str = (LPWSTR)malloc(4096); RtlZeroMemory(str, 4096); wcscpy(str, header); wcscat(str, L": "); wcscat(str, hvalue); WinHttpAddRequestHeaders(_http.request, str, -1, WINHTTP_ADDREQ_FLAG_ADD); free(str); } LPWSTR add_headers = NULL; if (append_headers) { int add_head_len = MultiByteToWideChar(CP_ACP, 0, append_headers, -1, NULL, 0); if (add_head_len > 1) { add_headers = (LPWSTR)calloc(2, add_head_len); if (add_headers) MultiByteToWideChar(CP_ACP, 0, append_headers, -1, add_headers, add_head_len + 1); } } if (!WinHttpSendRequest(_http.request, add_headers, -1, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) { if (add_headers) free(add_headers); _http.Close(); SetEvent(_events[EventErr]); return; } if (add_headers) free(add_headers); SetEvent(_events[EventSendRequest]); if (_abort_download) return; if (!WinHttpReceiveResponse(_http.request, NULL)) { _http.Close(); SetEvent(_events[EventErr]); return; } //status code... temp = MAX_PATH; WCHAR scode[MAX_PATH] = {}; WinHttpQueryHeaders(_http.request, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &scode, &temp, WINHTTP_NO_HEADER_INDEX); _http.status_code = wcstol(scode, NULL, 10); //headers... WinHttpQueryHeaders(_http.request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, (LPDWORD)&_recv_headers_zero_size, WINHTTP_NO_HEADER_INDEX); _recv_headers = (wchar_t*)calloc(_recv_headers_zero_size, 2); if (_recv_headers) WinHttpQueryHeaders(_http.request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, _recv_headers, (LPDWORD)&_recv_headers_zero_size, WINHTTP_NO_HEADER_INDEX); WinHttpQueryHeaders(_http.request, WINHTTP_QUERY_RAW_HEADERS, WINHTTP_HEADER_NAME_BY_INDEX, NULL, (LPDWORD)&_recv_headers_zero_size, WINHTTP_NO_HEADER_INDEX); _recv_headers_zero = (unsigned char*)calloc(_recv_headers_zero_size, 2); if (_recv_headers_zero) WinHttpQueryHeaders(_http.request, WINHTTP_QUERY_RAW_HEADERS, WINHTTP_HEADER_NAME_BY_INDEX, _recv_headers_zero, (LPDWORD)&_recv_headers_zero_size, WINHTTP_NO_HEADER_INDEX); SetEvent(_events[EventReceiveResponse]); if (_abort_download) return; if (_http.status_code >= 400) SetEvent(_events[EventStatusCode400]); else InternalDownload(); }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "Failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP"); goto on_error; } /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; if (proxy_url) { WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; /* Convert URL to wide characters */ int proxy_wide_len = git__utf8_to_16_alloc(&proxy_wide, proxy_url); if (proxy_wide_len < 0) { giterr_set(GITERR_OS, "Failed to convert string to wide form"); goto on_error; } /* Strip any trailing forward slash on the proxy URL; * WinHTTP doesn't like it if one is present */ if (proxy_wide_len > 1 && L'/' == proxy_wide[proxy_wide_len - 2]) proxy_wide[proxy_wide_len - 2] = L'\0'; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "Failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "Failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && t->auth_mechanism == GIT_WINHTTP_AUTH_BASIC && apply_basic_credential(s->request, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && t->auth_mechanism == GIT_WINHTTP_AUTH_NEGOTIATE && apply_default_credentials(s->request) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_basic_credential(s->request, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }
static int winhttp_stream_write_chunked( git_smart_subtransport_stream *stream, const char *buffer, size_t len) { winhttp_stream *s = (winhttp_stream *)stream; int error; if (!s->request && winhttp_stream_connect(s) < 0) return -1; if (!s->sent_request) { /* Send Transfer-Encoding: chunked header */ if (!WinHttpAddRequestHeaders(s->request, transfer_encoding, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); return -1; } if ((error = send_request(s, 0, 1)) < 0) return error; s->sent_request = 1; } if (len > CACHED_POST_BODY_BUF_SIZE) { /* Flush, if necessary */ if (s->chunk_buffer_len > 0) { if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; } /* Write chunk directly */ if (write_chunk(s->request, buffer, len) < 0) return -1; } else { /* Append as much to the buffer as we can */ int count = (int)min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, len); if (!s->chunk_buffer) s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE); memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count); s->chunk_buffer_len += count; buffer += count; len -= count; /* Is the buffer full? If so, then flush */ if (CACHED_POST_BODY_BUF_SIZE == s->chunk_buffer_len) { if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; /* Is there any remaining data from the source? */ if (len > 0) { memcpy(s->chunk_buffer, buffer, len); s->chunk_buffer_len = (unsigned int)len; } } } return 0; }
void main() { DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer = NULL; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; BOOL bResults = FALSE; hSession=WinHttpOpen(L"User-Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0); if(hSession) { hConnect=WinHttpConnect(hSession,L"kinggigi.sinaapp.com",INTERNET_DEFAULT_HTTP_PORT,0); } if(hConnect) { hRequest=WinHttpOpenRequest(hConnect, L"POST",L"hello.php",L"HTTP/1.1", WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0); } LPCWSTR header=L"Content-type: application/x-www-form-urlencoded"; SIZE_T len = lstrlenW(header); WinHttpAddRequestHeaders(hRequest,header,DWORD(len), WINHTTP_ADDREQ_FLAG_ADD); if(hRequest) { std::string data="val1=10&val2=9"; const void *ss=(const char *)data.c_str(); bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, const_cast<void *>(ss), data.length(), data.length(), 0); ////bResults=WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); } if(bResults) { bResults=WinHttpReceiveResponse(hRequest,NULL); } if(bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n",GetLastError()); break; } if (!dwSize) break; pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } delete [] pszOutBuffer; if (!dwDownloaded) break; } while (dwSize > 0); } if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); system("pause"); }
PSTR VirusTotalSendHttpRequest( _In_ PPH_BYTES JsonArray ) { HANDLE fileHandle = INVALID_HANDLE_VALUE; HINTERNET httpSessionHandle = NULL; HINTERNET connectHandle = NULL; HINTERNET requestHandle = NULL; PSTR subRequestBuffer = NULL; PPH_STRING phVersion = NULL; PPH_STRING userAgent = NULL; PPH_STRING urlString = NULL; phVersion = PhGetPhVersion(); userAgent = PhConcatStrings2(L"ProcessHacker_", phVersion->Buffer); if (!(httpSessionHandle = WinHttpOpen( userAgent->Buffer, WindowsVersion >= WINDOWS_8_1 ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ))) { goto CleanupExit; } if (WindowsVersion >= WINDOWS_8_1) { WinHttpSetOption( httpSessionHandle, WINHTTP_OPTION_DECOMPRESSION, &(ULONG){ WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE }, sizeof(ULONG) ); } if (!(connectHandle = WinHttpConnect( httpSessionHandle, L"www.virustotal.com", INTERNET_DEFAULT_HTTPS_PORT, 0 ))) { goto CleanupExit; } PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlString = PhFormatString( L"%s%s%s%s%S", L"/partners", L"/sysinternals", L"/file-reports", L"?apikey=", resourceString->Buffer ); PhClearReference(&resourceString); if (!(requestHandle = WinHttpOpenRequest( connectHandle, L"POST", PhGetString(urlString), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE ))) { PhClearReference(&urlString); goto CleanupExit; } PhClearReference(&urlString); if (!WinHttpAddRequestHeaders(requestHandle, L"Content-Type: application/json", -1L, 0)) { goto CleanupExit; } if (!WinHttpSendRequest( requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, JsonArray->Buffer, (ULONG)JsonArray->Length, (ULONG)JsonArray->Length, 0 )) { goto CleanupExit; } if (WinHttpReceiveResponse(requestHandle, NULL)) { BYTE buffer[PAGE_SIZE]; ULONG allocatedLength; ULONG dataLength; ULONG returnLength; allocatedLength = sizeof(buffer); subRequestBuffer = PhAllocate(allocatedLength); dataLength = 0; while (WinHttpReadData(requestHandle, buffer, PAGE_SIZE, &returnLength)) { if (returnLength == 0) break; if (allocatedLength < dataLength + returnLength) { allocatedLength *= 2; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } memcpy(subRequestBuffer + dataLength, buffer, returnLength); dataLength += returnLength; } if (allocatedLength < dataLength + 1) { allocatedLength++; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } // Ensure that the buffer is null-terminated. subRequestBuffer[dataLength] = 0; } CleanupExit: if (requestHandle) WinHttpCloseHandle(requestHandle); if (connectHandle) WinHttpCloseHandle(connectHandle); if (httpSessionHandle) WinHttpCloseHandle(httpSessionHandle); if (JsonArray) PhDereferenceObject(JsonArray); return subRequestBuffer; }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; size_t i; const git_proxy_options *proxy_opts; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP"); goto on_error; } proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { proxy_url = git__strdup(proxy_opts->url); GITERR_CHECK_ALLOC(proxy_url); } if (proxy_url) { git_buf processed_url = GIT_BUF_INIT; WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) { t->proxy_connection_data.use_ssl = false; } else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) { t->proxy_connection_data.use_ssl = true; } else { giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url); return -1; } gitno_connection_data_free_ptrs(&t->proxy_connection_data); if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL, &t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0) goto on_error; if (t->proxy_connection_data.user && t->proxy_connection_data.pass) { if (t->proxy_cred) { t->proxy_cred->free(t->proxy_cred); } if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0) goto on_error; } if (t->proxy_connection_data.use_ssl) git_buf_PUTS(&processed_url, SCHEME_HTTPS); else git_buf_PUTS(&processed_url, SCHEME_HTTP); git_buf_puts(&processed_url, t->proxy_connection_data.host); if (t->proxy_connection_data.port) git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port); if (git_buf_oom(&processed_url)) { giterr_set_oom(); error = -1; goto on_error; } /* Convert URL to wide characters */ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr); git_buf_free(&processed_url); if (error < 0) goto on_error; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); if (t->proxy_cred) { if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) { if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred)) < 0) goto on_error; } } } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } for (i = 0; i < t->owner->custom_headers.count; i++) { if (t->owner->custom_headers.strings[i]) { git_buf_clear(&buf); git_buf_puts(&buf, t->owner->custom_headers.strings[i]); if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert custom header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && apply_default_credentials(s->request, t->auth_mechanisms) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }
//-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- HttpRequest* HttpRequestSystem::MakeRequest(HttpRequest::Type in_type, const std::string& in_url, const std::string& in_body, const CSCore::ParamDictionary& in_headers, const HttpRequest::Delegate& in_delegate, u32 in_timeoutSecs) { CS_ASSERT(CSCore::Application::Get()->GetTaskScheduler()->IsMainThread() == true, "Http requests can currently only be made on the main thread"); CS_ASSERT(in_delegate != nullptr, "Cannot make an http request with a null delegate"); CS_ASSERT(in_url.empty() == false, "Cannot make an http request to a blank url"); URL_COMPONENTS urlComps; //Initialize the URL_COMPONENTS structure. ZeroMemory(&urlComps, sizeof(URL_COMPONENTS)); urlComps.dwStructSize = sizeof(URL_COMPONENTS); //Set required component lengths to non-zero so that they are cracked. urlComps.dwSchemeLength = (DWORD)-1; urlComps.dwHostNameLength = (DWORD)-1; urlComps.dwUrlPathLength = (DWORD)-1; urlComps.dwExtraInfoLength = (DWORD)-1; //Change the URL to wide string std::wstring url(WindowsStringUtils::UTF8ToUTF16(in_url)); //Crack the URL. if (!WinHttpCrackUrl(url.c_str(), (DWORD)url.length(), 0, &urlComps)) { CS_LOG_FATAL("Cannot crack URL: " + in_url); return nullptr; } //Weirdly the cracked URL struct only gives you the ability to crack your own URL std::wstring hostName = urlComps.lpszHostName; hostName = hostName.substr(0, urlComps.dwHostNameLength); HINTERNET connectionHandle = ::WinHttpConnect(m_sessionHandle, hostName.c_str(), INTERNET_DEFAULT_PORT, 0); if (!connectionHandle) { CS_LOG_ERROR("Failed to connect to server: " + in_url); return nullptr; } //Set up the request based on whether it is POST or GET and whether it is SSL LPCWSTR type = (in_type == CSNetworking::HttpRequest::Type::k_get ? L"GET" : L"POST"); HINTERNET requestHandle = 0; std::wstring urlPath = urlComps.lpszUrlPath; urlPath = urlPath.substr(0, urlComps.dwUrlPathLength); if (urlComps.nScheme == INTERNET_SCHEME_HTTPS) { requestHandle = ::WinHttpOpenRequest(connectionHandle, type, urlPath.c_str(), L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (requestHandle == nullptr || ApplySSLSettings(requestHandle) == false) { CS_LOG_ERROR("Failed to open request: " + in_url); WinHttpCloseHandle(connectionHandle); return nullptr; } } else { requestHandle = ::WinHttpOpenRequest(connectionHandle, type, urlPath.c_str(), L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (requestHandle == nullptr) { CS_LOG_ERROR("Failed to open request: " + in_url); WinHttpCloseHandle(connectionHandle); return nullptr; } } if (in_headers.empty() == false) { std::wstring headerBlob = ConvertHeaders(in_headers); if (WinHttpAddRequestHeaders(requestHandle, headerBlob.c_str(), DWORD(headerBlob.length()), WINHTTP_ADDREQ_FLAG_ADD) == false) { CS_LOG_ERROR("Failed to add http headers: " + in_url); WinHttpCloseHandle(requestHandle); WinHttpCloseHandle(connectionHandle); return nullptr; } } HttpRequest* httpRequest = new HttpRequest(in_type, in_url, in_body, in_headers, in_timeoutSecs, requestHandle, connectionHandle, GetMaxBufferSize(), in_delegate); m_requests.push_back(httpRequest); return httpRequest; }
PVIRUSTOTAL_FILE_REPORT_RESULT VirusTotalSendHttpFileReportRequest( _In_ PPH_STRING FileHash ) { NTSTATUS status = STATUS_SUCCESS; HANDLE fileHandle = INVALID_HANDLE_VALUE; HINTERNET httpSessionHandle = NULL; HINTERNET connectHandle = NULL; HINTERNET requestHandle = NULL; PSTR subRequestBuffer = NULL; PPH_STRING phVersion = NULL; PPH_STRING userAgent = NULL; PPH_STRING urlString = NULL; phVersion = PhGetPhVersion(); userAgent = PhConcatStrings2(L"ProcessHacker_", phVersion->Buffer); if (!(httpSessionHandle = WinHttpOpen( userAgent->Buffer, WindowsVersion >= WINDOWS_8_1 ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ))) { goto CleanupExit; } if (WindowsVersion >= WINDOWS_8_1) { WinHttpSetOption( httpSessionHandle, WINHTTP_OPTION_DECOMPRESSION, &(ULONG){ WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE }, sizeof(ULONG) ); } if (!(connectHandle = WinHttpConnect( httpSessionHandle, L"www.virustotal.com", INTERNET_DEFAULT_HTTPS_PORT, 0 ))) { goto CleanupExit; } PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlString = PhFormatString( L"%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/file", L"/report", L"?apikey=", resourceString->Buffer, L"&resource=", PhGetString(FileHash) ); PhClearReference(&resourceString); if (!(requestHandle = WinHttpOpenRequest( connectHandle, L"POST", PhGetString(urlString), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE ))) { goto CleanupExit; } if (!WinHttpAddRequestHeaders(requestHandle, L"Content-Type: application/json", -1L, 0)) goto CleanupExit; if (!WinHttpSendRequest( requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0 )) { goto CleanupExit; } if (WinHttpReceiveResponse(requestHandle, NULL)) { BYTE buffer[PAGE_SIZE]; ULONG allocatedLength; ULONG dataLength; ULONG returnLength; allocatedLength = sizeof(buffer); subRequestBuffer = PhAllocate(allocatedLength); dataLength = 0; while (WinHttpReadData(requestHandle, buffer, PAGE_SIZE, &returnLength)) { if (returnLength == 0) break; if (allocatedLength < dataLength + returnLength) { allocatedLength *= 2; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } memcpy(subRequestBuffer + dataLength, buffer, returnLength); dataLength += returnLength; } if (allocatedLength < dataLength + 1) { allocatedLength++; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } subRequestBuffer[dataLength] = 0; } CleanupExit: PhClearReference(&urlString); if (requestHandle) WinHttpCloseHandle(requestHandle); if (connectHandle) WinHttpCloseHandle(connectHandle); if (httpSessionHandle) WinHttpCloseHandle(httpSessionHandle); PVOID jsonRootObject; //PVOID jsonScanObject; PVIRUSTOTAL_FILE_REPORT_RESULT result; if (!(jsonRootObject = CreateJsonParser(subRequestBuffer))) goto CleanupExit; if (!GetJsonValueAsUlong(jsonRootObject, "response_code")) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); result->Total = PhFormatUInt64(GetJsonValueAsUlong(jsonRootObject, "total"), FALSE); result->Positives = PhFormatUInt64(GetJsonValueAsUlong(jsonRootObject, "positives"), FALSE); result->Resource = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "resource")); result->ScanId = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "scan_id")); result->Md5 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "md5")); result->Sha1 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "sha1")); result->Sha256 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "sha256")); result->ScanDate = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "scan_date")); result->Permalink = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "permalink")); result->StatusMessage = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "verbose_msg")); //if (jsonScanObject = JsonGetObject(jsonRootObject, "scans")) //{ // PPH_LIST jsonArrayList; // // if (jsonArrayList = JsonGetObjectArrayList(jsonScanObject)) // { // result->ScanResults = PhCreateList(jsonArrayList->Count); // // for (ULONG i = 0; i < jsonArrayList->Count; i++) // { // PJSON_ARRAY_LIST_OBJECT object = jsonArrayList->Items[i]; // //BOOLEAN detected = GetJsonValueAsBool(object->Entry, "detected") == TRUE; // //PSTR version = GetJsonValueAsString(object->Entry, "version"); // //PSTR result = GetJsonValueAsString(object->Entry, "result"); // //PSTR update = GetJsonValueAsString(object->Entry, "update"); // // PhFree(object); // } // // PhDereferenceObject(jsonArrayList); // } //} return result; }
static int winhttp_stream_write_chunked( git_smart_subtransport_stream *stream, const char *buffer, size_t len) { winhttp_stream *s = (winhttp_stream *)stream; winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); if (!s->request && winhttp_stream_connect(s) < 0) return -1; if (!s->sent_request) { /* Send Transfer-Encoding: chunked header */ if (!WinHttpAddRequestHeaders(s->request, transfer_encoding, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to add a header to the request")); return -1; } if (!WinHttpSendRequest(s->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to send request")); return -1; } s->sent_request = 1; } if (len > CACHED_POST_BODY_BUF_SIZE) { /* Flush, if necessary */ if (s->chunk_buffer_len > 0) { if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; } /* Write chunk directly */ if (write_chunk(s->request, buffer, len) < 0) return -1; } else { /* Append as much to the buffer as we can */ int count = min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, (int)len); if (!s->chunk_buffer) s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE); memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count); s->chunk_buffer_len += count; buffer += count; len -= count; /* Is the buffer full? If so, then flush */ if (CACHED_POST_BODY_BUF_SIZE == s->chunk_buffer_len) { if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; /* Is there any remaining data from the source? */ if (len > 0) { memcpy(s->chunk_buffer, buffer, len); s->chunk_buffer_len = (unsigned int)len; } } } return 0; }
//リクエストを送る //内部メモリバッファにDLする場合はファイル容量に要注意 //戻り値:エラーコード DWORD CWinHTTPUtil::SendRequest( LPCWSTR url, //[IN] アクセスするURL NW_VERB_MODE verbMode, //[IN] VERBの種類 LPCWSTR addHttpHeader, //[IN] Httpヘッダに追加するものあるなら指定 LPCWSTR saveFilePath, //[IN] DLファイル名、NULL時は内部メモリバッファにDL UPLOAD_DATA_LIST* upList //[IN] サーバーに送信するデータ(PUT or POST) ) { if( url == NULL ){ return ERR_INVALID_ARG; } if( this->session == NULL ){ return ERR_NW_NO_SESSION; } //リクエストクローズ if( this->request != NULL ){ WinHttpSetStatusCallback( this->request, NULL, NULL, NULL ); WinHttpCloseHandle(this->request); this->request = NULL; } ClearUpList(); for( size_t i=0; i<this->dlBuffList.size(); i++ ){ SAFE_DELETE(this->dlBuffList[i]); } this->dlBuffList.clear(); //URLの分解 URL_COMPONENTS stURL; ZeroMemory(&stURL, sizeof(URL_COMPONENTS)); stURL.dwStructSize = sizeof(URL_COMPONENTS); stURL.dwSchemeLength = -1; stURL.dwHostNameLength = -1; stURL.dwUrlPathLength = -1; stURL.dwExtraInfoLength = -1; if( WinHttpCrackUrl( url, (DWORD)wcslen(url), 0, &stURL) == NULL ){ return ERR_FALSE; } if( stURL.dwHostNameLength <= 0 ){ return ERR_FALSE; } wstring host = L""; host.insert(0,stURL.lpszHostName, stURL.dwHostNameLength ); host += L"\0"; if( CompareNoCase(host, stURL.lpszHostName) != 0 || this->lastPort != stURL.nPort){ //前回と違うコネクションなのでやりなおし if( this->connect != NULL ){ WinHttpCloseHandle(this->connect); this->connect = NULL; } } //コネクションオープン if( this->connect == NULL ){ this->connect = WinHttpConnect( this->session, host.c_str(), stURL.nPort, 0 ); if( this->connect == NULL ){ return ERR_NW_OPEN_CONNECT; } } //Verbの設定 wstring verb = L"GET"; if( verbMode == NW_VERB_GET ){ verb = L"GET"; }else if( verbMode == NW_VERB_POST ){ verb = L"POST"; }else if( verbMode == NW_VERB_PUT ){ verb = L"PUT"; } wstring sendUrl = L""; sendUrl.insert(0, stURL.lpszUrlPath, stURL.dwUrlPathLength+stURL.dwExtraInfoLength); sendUrl += L"\0"; //リクエストオープン if( stURL.nPort == INTERNET_DEFAULT_HTTPS_PORT ){ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); }else{ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 ); } if( this->request == NULL ){ return ERR_NW_OPEN_REQUEST; } if( this->useProxy == TRUE ){ //ProxyのIDとパスワードがあったらセット if( this->proxyID.size() > 0 || this->proxyPWD.size() > 0 ){ if( WinHttpSetCredentials( this->request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, this->proxyID.c_str(), this->proxyPWD.c_str(), NULL ) == FALSE ){ return ERR_NW_PROXY_LOGIN; } } } //HTTPヘッダを設定 if( addHttpHeader != NULL ){ WinHttpAddRequestHeaders( this->request, addHttpHeader, -1, WINHTTP_ADDREQ_FLAG_ADD ); } //コールバック設定 WinHttpSetStatusCallback(this->request, StatusCallback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, NULL ); //アップロードデータのコピー this->totalUpSize = 0; if( upList != NULL ){ for( DWORD i=0; i<upList->listCount; i++ ){ UPLOAD_DATA* item = new UPLOAD_DATA; item->filePathFlag = upList->list[i].filePathFlag; item->buffSize = upList->list[i].buffSize; if( item->buffSize > 0 ){ item->buff = new BYTE[item->buffSize]; memcpy(item->buff, upList->list[i].buff, item->buffSize); } upDataList.push_back(item); if( item->filePathFlag == TRUE ){ HANDLE file = CreateFileW( (WCHAR*)item->buff, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( file == INVALID_HANDLE_VALUE ){ //ファイルにアクセスできないのでエラー return ERR_NW_OPEN_FILE; } DWORD HSize=0; DWORD LSize=0; LSize = GetFileSize(file, &HSize); CloseHandle(file); if( HSize > 0 ){ //DWORD以上は未サポート return ERR_SIZE; } this->totalUpSize += LSize; }else{ this->totalUpSize += item->buffSize; } } } this->lastHost = host; this->lastPort = stURL.nPort; if( saveFilePath != NULL ){ this->saveFilePath = saveFilePath; }else{ this->saveFilePath = L""; } ResetEvent(this->upStopEvent); ResetEvent(this->responseCompEvent); this->errEndCode = NO_ERR; if( WinHttpSendRequest( this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, totalUpSize, (DWORD_PTR)this) == FALSE ){ return ERR_NW_SEND_REQUEST; } if( this->asyncMode == FALSE ){ //同期なので完了するまで待つ WaitForSingleObject(this->responseCompEvent, INFINITE); return this->errEndCode; } return NO_ERR; }
int APICaller::GetData(LPCWSTR path, char **dataOut) { char *readBuffer = NULL; DWORD cumulativeRead = 0; BOOL dataCompressed = FALSE; // Attempt to get a connection if (!GetConnection()) { return 0; } HINTERNET request = WinHttpOpenRequest(connection, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (request != NULL) { WinHttpAddRequestHeaders(request, L"Accept-Encoding: gzip, deflate", (DWORD)-1, WINHTTP_ADDREQ_FLAG_ADD); if (WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) { if (WinHttpReceiveResponse(request, NULL)) { DWORD toRead = 0; DWORD bytesRead = 0; do { if (!WinHttpQueryDataAvailable(request, &toRead)) { break; } if (toRead == 0) { break; } readBuffer = (char*)((readBuffer == NULL) ? malloc(toRead) : realloc(readBuffer, cumulativeRead + toRead + 1)); if (WinHttpReadData(request, readBuffer+cumulativeRead, toRead, &bytesRead)) { cumulativeRead += bytesRead; } } while (toRead > 0); readBuffer[cumulativeRead] = '\0'; //get compression status WCHAR *headerInfo = GetHeader(request, WINHTTP_QUERY_CONTENT_ENCODING); dataCompressed = wcswcs(headerInfo, L"gzip") != NULL; delete[] headerInfo; } } WinHttpCloseHandle(request); } //Decompress data if necessary if (readBuffer != NULL && cumulativeRead > 0) { if (dataCompressed) { char *inflateBuffer = new char[cumulativeRead*50]; cumulativeRead = decompress(readBuffer, cumulativeRead, inflateBuffer, cumulativeRead*50); inflateBuffer[cumulativeRead] = NULL; *dataOut = inflateBuffer; } else { char *buffer = new char[cumulativeRead+1]; memcpy(buffer, readBuffer, cumulativeRead+1); *dataOut = buffer; } free(readBuffer); } return cumulativeRead; }
bool HttpQuery(const HttpRequest& request, HttpResponse& response) { // initialize response.statusCode = -1; HINTERNET internet = NULL; HINTERNET connectedInternet = NULL; HINTERNET requestInternet = NULL; BOOL httpResult = FALSE; DWORD error = 0; std::deque<LPCWSTR> acceptTypes; std::deque<BufferPair> availableBuffers; // access http internet = WinHttpOpen(L"Raven", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); error = GetLastError(); if (!internet) goto CLEANUP; // connect connectedInternet = WinHttpConnect(internet, request.server.c_str(), (int)request.port, 0); error = GetLastError(); if (!connectedInternet) goto CLEANUP; // open request for (int i = 0; i<(int)request.acceptTypes.size(); i++) { acceptTypes.push_front(request.acceptTypes[i].c_str()); } acceptTypes.push_front(0); requestInternet = WinHttpOpenRequest(connectedInternet, request.method.c_str(), request.query.c_str(), NULL, WINHTTP_NO_REFERER, &acceptTypes[0], (request.secure ? WINHTTP_FLAG_SECURE : 0)); error = GetLastError(); if (!requestInternet) goto CLEANUP; // authentication, cookie and request if (request.username != L"" && request.password != L"") { WinHttpSetCredentials(requestInternet, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, request.username.c_str(), request.password.c_str(), NULL); } if (request.contentType != L"") { httpResult = WinHttpAddRequestHeaders(requestInternet, (L"Content-type:" + request.contentType).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD); } if (request.cookie != L"") { WinHttpAddRequestHeaders(requestInternet, (L"Cookie:" + request.cookie).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD); } // extra headers for (auto it = request.extraHeaders.begin(); it != request.extraHeaders.end(); it++) { std::wstring key = it->first; std::wstring value = it->second; WinHttpAddRequestHeaders(requestInternet, (key + L":" + value).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD); } if (request.body.size()>0) { httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)&request.body[0], (int)request.body.size(), (int)request.body.size(), NULL); } else { httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL); } error = GetLastError(); if (httpResult == FALSE) goto CLEANUP; // receive response httpResult = WinHttpReceiveResponse(requestInternet, NULL); error = GetLastError(); if (httpResult != TRUE) goto CLEANUP; DWORD headerLength = sizeof(DWORD); // read response status code DWORD statusCode = 0; httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &headerLength, WINHTTP_NO_HEADER_INDEX); error = GetLastError(); if (httpResult == FALSE) goto CLEANUP; response.statusCode = statusCode; // read respons cookie httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &headerLength, WINHTTP_NO_HEADER_INDEX); error = GetLastError(); if (error == ERROR_INSUFFICIENT_BUFFER) { wchar_t* rawHeader = new wchar_t[headerLength / sizeof(wchar_t)]; ZeroMemory(rawHeader, headerLength); httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, rawHeader, &headerLength, WINHTTP_NO_HEADER_INDEX); const wchar_t* cookieStart = wcsstr(rawHeader, L"Cookie:"); if (cookieStart) { const wchar_t* cookieEnd = wcsstr(cookieStart, L";"); if (cookieEnd) { response.cookie = std::wstring(cookieStart + 7, cookieEnd - cookieStart - 7); } } delete[] rawHeader; } // read response body while (true) { DWORD bytesAvailable = 0; BOOL queryDataAvailableResult = WinHttpQueryDataAvailable(requestInternet, &bytesAvailable); error = GetLastError(); if (queryDataAvailableResult == TRUE && bytesAvailable != 0) { char* utf8 = new char[bytesAvailable]; DWORD bytesRead = 0; BOOL readDataResult = WinHttpReadData(requestInternet, utf8, bytesAvailable, &bytesRead); error = GetLastError(); if (readDataResult == TRUE) { availableBuffers.push_front(BufferPair(utf8, bytesRead)); } else { delete[] utf8; } } else { break; } } // concatincate response body int totalSize = 0; for each (BufferPair p in availableBuffers) { totalSize += p.length; } response.body.resize(totalSize); if (totalSize>0) { char* utf8 = new char[totalSize]; { char* temp = utf8; for each (BufferPair p in availableBuffers) { memcpy(temp, p.buffer, p.length); temp += p.length; } }