// Copyright 2007-2009 Google Inc. | |
// | |
// Licensed under the Apache License, Version 2.0 (the "License"); | |
// you may not use this file except in compliance with the License. | |
// You may obtain a copy of the License at | |
// | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// | |
// Unless required by applicable law or agreed to in writing, software | |
// distributed under the License is distributed on an "AS IS" BASIS, | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// See the License for the specific language governing permissions and | |
// limitations under the License. | |
// ======================================================================== | |
// | |
// The code below is not thread safe. | |
#include "omaha/net/http_client.h" | |
#include "omaha/common/debug.h" | |
namespace omaha { | |
HttpClient::Factory* HttpClient::factory_ = NULL; | |
HttpClient::Factory& HttpClient::GetFactory() { | |
if (!factory_) { | |
factory_ = new Factory(); | |
} | |
return *factory_; | |
} | |
void HttpClient::DeleteFactory() { | |
delete factory_; | |
factory_ = NULL; | |
} | |
HttpClient* CreateHttpClient() { | |
HttpClient* http_client = | |
HttpClient::GetFactory().CreateObject(HttpClient::WINHTTP); | |
if (!http_client) { | |
http_client = HttpClient::GetFactory().CreateObject(HttpClient::WININET); | |
} | |
return http_client; | |
} | |
CString HttpClient::BuildRequestHeader(const TCHAR* name, const TCHAR* value) { | |
ASSERT1(name && *name); | |
ASSERT1(value && *value); | |
CString header; | |
header.Format(_T("%s: %s\r\n"), name, value); | |
return header; | |
} | |
HttpClient::StatusCodeClass HttpClient::GetStatusCodeClass(int status_code) { | |
ASSERT1(!status_code || | |
(HTTP_STATUS_FIRST <= status_code && status_code <= HTTP_STATUS_LAST)); | |
return static_cast<StatusCodeClass>(status_code / 100 * 100); | |
} | |
HRESULT HttpClient::QueryHeadersString(HINTERNET request_handle, | |
uint32 info_level, | |
const TCHAR* name, | |
CString* value, | |
DWORD* index) { | |
ASSERT1(value); | |
DWORD num_bytes = 0; | |
HRESULT hr = QueryHeaders(request_handle, | |
info_level, | |
name, | |
NULL, | |
&num_bytes, | |
index); | |
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { | |
return hr; | |
} | |
CString val; | |
hr = QueryHeaders(request_handle, | |
info_level, | |
name, | |
val.GetBuffer(num_bytes/sizeof(TCHAR)), | |
&num_bytes, | |
index); | |
if (FAILED(hr)) { | |
return hr; | |
} | |
ASSERT1(num_bytes); | |
val.ReleaseBufferSetLength(num_bytes/sizeof(TCHAR)); | |
*value = val; | |
return S_OK; | |
} | |
HRESULT HttpClient::QueryHeadersInt(HINTERNET request_handle, | |
uint32 info_level, | |
const TCHAR* name, | |
int* value, | |
DWORD* index) { | |
ASSERT1(value); | |
info_level |= WINHTTP_QUERY_FLAG_NUMBER; | |
DWORD value_size = sizeof(*value); | |
HRESULT hr = QueryHeaders(request_handle, | |
info_level, | |
name, | |
value, | |
&value_size, | |
index); | |
if (FAILED(hr)) { | |
return hr; | |
} | |
ASSERT1(value_size == sizeof(*value)); | |
return S_OK; | |
} | |
HRESULT HttpClient::QueryOptionString(HINTERNET handle, | |
uint32 option, | |
CString* value) { | |
ASSERT1(value); | |
DWORD num_bytes = 0; | |
HRESULT hr = QueryOption(handle, option, NULL, &num_bytes); | |
DWORD last_error = ::GetLastError(); | |
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { | |
return hr; | |
} | |
ASSERT1(num_bytes); | |
CString val; | |
hr = QueryOption(handle, option, val.GetBuffer(num_bytes), &num_bytes); | |
if (FAILED(hr)) { | |
return hr; | |
} | |
ASSERT1(num_bytes); | |
val.ReleaseBufferSetLength(num_bytes/sizeof(TCHAR)); | |
*value = val; | |
return S_OK; | |
} | |
HRESULT HttpClient::QueryOptionInt(HINTERNET handle, | |
uint32 option, | |
int* value) { | |
ASSERT1(value); | |
DWORD val = 0; | |
DWORD num_bytes = sizeof(val); | |
HRESULT hr = QueryOption(handle, option, &val, &num_bytes); | |
if (FAILED(hr)) { | |
return hr; | |
} | |
ASSERT1(num_bytes == sizeof(val)); | |
*value = val; | |
return S_OK; | |
} | |
HRESULT HttpClient::SetOptionString(HINTERNET handle, | |
uint32 option, | |
const TCHAR* value) { | |
ASSERT1(value); | |
const void* buffer = value; | |
DWORD buffer_length = _tcslen(value) * sizeof(TCHAR); | |
return SetOption(handle, option, buffer, buffer_length); | |
} | |
HRESULT HttpClient::SetOptionInt(HINTERNET handle, uint32 option, int value) { | |
DWORD val = value; | |
return SetOption(handle, option, &val, sizeof(val)); | |
} | |
} // namespace omaha | |