Electroneum
http_client_via_api_helper.h
Go to the documentation of this file.
1 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the Andrey N. Sabelnikov nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 
28 
29 
30 #pragma once
31 #include <wininet.h>
32 #include <atlutil.h>
33 #pragma comment(lib, "Wininet.lib")
34 
35 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
36 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "net.http"
37 
38 namespace epee
39 {
40 namespace net_utils
41 {
42  inline
43  bool http_ssl_invoke(const std::string& url, const std::string usr, const std::string psw, std::string& http_response_body, bool use_post = false)
44  {
45  bool final_res = false;
46 
47  ATL::CUrl url_obj;
48  BOOL crack_rss = url_obj.CrackUrl(string_encoding::convert_to_t<std::basic_string<TCHAR> >(url).c_str());
49 
50  HINTERNET hinet = ::InternetOpenA(SHARED_JOBSCOMMON_HTTP_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
51  if(!hinet)
52  {
53  int err = ::GetLastError();
54  LOG_PRINT("Failed to call InternetOpenA, \nError: " << err << " " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
55  return false;
56  }
57 
58  DWORD dwFlags = 0;
59  DWORD dwBuffLen = sizeof(dwFlags);
60 
61  if(usr.size())
62  {
63  dwFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|
64  INTERNET_FLAG_PRAGMA_NOCACHE | SECURITY_FLAG_IGNORE_UNKNOWN_CA|INTERNET_FLAG_SECURE;
65  }else
66  {
67  dwFlags |= INTERNET_FLAG_PRAGMA_NOCACHE;
68  }
69 
70 
71  int port = url_obj.GetPortNumber();
72  BOOL res = FALSE;
73 
74  HINTERNET hsession = ::InternetConnectA(hinet, string_encoding::convert_to_ansii(url_obj.GetHostName()).c_str(), port/*INTERNET_DEFAULT_HTTPS_PORT*/, usr.c_str(), psw.c_str(), INTERNET_SERVICE_HTTP, dwFlags, NULL);
75  if(hsession)
76  {
77  const std::string uri = string_encoding::convert_to_ansii(url_obj.GetUrlPath()) + string_encoding::convert_to_ansii(url_obj.GetExtraInfo());
78 
79  HINTERNET hrequest = ::HttpOpenRequestA(hsession, use_post?"POST":NULL, uri.c_str(), NULL, NULL,NULL, dwFlags, NULL);
80  if(hrequest)
81  {
82  while(true)
83  {
84  res = ::HttpSendRequestA(hrequest, NULL, 0, NULL, 0);
85  if(!res)
86  {
87  //ERROR_INTERNET_INVALID_CA 45
88  //ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
89  int err = ::GetLastError();
90  LOG_PRINT("Failed to call HttpSendRequestA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
91  break;
92  }
93 
94  DWORD code = 0;
95  DWORD buf_len = sizeof(code);
96  DWORD index = 0;
97  res = ::HttpQueryInfo(hrequest, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &code, &buf_len, &index);
98  if(!res)
99  {
100  //ERROR_INTERNET_INVALID_CA 45
101  //ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
102  int err = ::GetLastError();
103  LOG_PRINT("Failed to call HttpQueryInfo, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
104  break;
105  }
106  if(code < 200 || code > 299)
107  {
108  LOG_PRINT("Wrong server response, HttpQueryInfo returned statuse code" << code , LOG_LEVEL_0);
109  break;
110  }
111 
112 
113  char buff[100000] = {0};
114  DWORD readed = 0;
115  while(true)
116  {
117  res = ::InternetReadFile(hrequest, buff, sizeof(buff), &readed);
118  if(!res)
119  {
120  int err = ::GetLastError();
121  LOG_PRINT("Failed to call InternetReadFile, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
122  break;
123  }
124  if(readed)
125  {
126  http_response_body.append(buff, readed);
127  }
128  else
129  break;
130  }
131 
132  if(!res)
133  break;
134 
135 
136  //we success
137  final_res = true;
138 
139  res = ::InternetCloseHandle(hrequest);
140  if(!res)
141  {
142  int err = ::GetLastError();
143  LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
144  }
145 
146  break;
147  }
148  }
149  else
150  {
151  //ERROR_INTERNET_INVALID_CA
152  int err = ::GetLastError();
153  LOG_PRINT("Failed to call InternetOpenUrlA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
154  return false;
155  }
156 
157  res = ::InternetCloseHandle(hsession);
158  if(!res)
159  {
160  int err = ::GetLastError();
161  LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
162  }
163  }else
164  {
165  int err = ::GetLastError();
166  LOG_PRINT("Failed to call InternetConnectA(" << string_encoding::convert_to_ansii(url_obj.GetHostName()) << ", port " << port << " \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
167  }
168 
169 
170 
171  res = ::InternetCloseHandle(hinet);
172  if(!res)
173  {
174  int err = ::GetLastError();
175  LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
176  }
177  return final_res;
178  }
179 }
180 }
const char * res
Definition: hmac_keccak.cpp:41
::std::string string
Definition: gtest-port.h:1097
std::string convert_to_ansii(const std::wstring &str_from)
Definition: string_coding.h:37
boost::endian::big_uint16_t port
Definition: socks.cpp:60
target_string convert_to_t(const std::wstring &str_from)
bool http_ssl_invoke(const std::string &url, const std::string usr, const std::string psw, std::string &http_response_body, bool use_post=false)