1 #include "ace/Get_Opt.h"
3 #include "ace/OS_NS_errno.h"
4 #include "ace/INet/HTTP_URL.h"
5 #include "ace/INet/HTTP_ClientRequestHandler.h"
6 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
7 # include "ace/INet/SSL_CallbackManager.h"
8 # include "ace/INet/HTTPS_Context.h"
10 #include "ace/INet/INet_Log.h"
14 ACE_CString proxy_hostname
;
15 u_short proxy_port
= ACE::HTTP::URL::HTTP_PROXY_PORT
;
18 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
19 int ssl_mode
= ACE_SSL_Context::SSLv23
;
20 bool verify_peer
= true;
21 bool ignore_verify
= false;
22 ACE_CString certificate
;
23 ACE_CString private_key
;
24 ACE_CString ca_location
;
30 std::cout
<< "usage: http_simple_wget [options] <url>\n";
31 std::cout
<< "Executes an HTTP GET request and sends the result to STDOUT or file\n";
32 std::cout
<< "\t-H <hostname> \t\tproxy host to connect to\n";
33 std::cout
<< "\t-p <port> \t\tproxy port to connect to\n";
34 std::cout
<< "\t-o <filename> \t\tfile to write output to\n";
35 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
36 std::cout
<< "\t-n \t\tno peer certificate verification\n";
37 std::cout
<< "\t-i \t\tignore peer certificate verification failures\n";
38 std::cout
<< "\t-c <filename> \t\tcertificate file (PEM format)\n";
39 std::cout
<< "\t-k <filename> \t\tprivate key file (PEM format); requires -c\n";
40 std::cout
<< "\t-C <path> \t\ttrusted CA file or directory\n";
45 parse_args (int argc
, ACE_TCHAR
*argv
[])
47 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
48 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("H:p:o:hv:nic:k:C:"), 0, 0, ACE_Get_Opt::RETURN_IN_ORDER
);
50 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("H:p:o:h"), 0, 0, ACE_Get_Opt::RETURN_IN_ORDER
);
55 while ((c
= get_opt ()) != EOF
)
60 url
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
63 proxy_hostname
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
67 proxy_port
= (u_short
)ACE_OS::atoi (ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ()));
71 outfile
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
74 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
84 certificate
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
88 private_key
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
92 ca_location
= ACE_TEXT_ALWAYS_CHAR (get_opt
.opt_arg ());
105 class My_HTTP_RequestHandler
106 : public ACE::HTTP::ClientRequestHandler
109 My_HTTP_RequestHandler () : in_length_ (0), read_length_ (0) {}
110 virtual ~My_HTTP_RequestHandler () {}
113 virtual void handle_request_error (const ACE::HTTP::URL
& url
)
115 std::cout
<< "ERROR" << std::endl
;
116 std::cerr
<< "Failed to handle request for " << url
.to_string ().c_str () << std::endl
;
119 virtual void handle_connection_error (const ACE::HTTP::URL
& url
)
121 std::cout
<< "ERROR" << std::endl
;
122 std::cerr
<< "Failed to set up connection for " << url
.to_string ().c_str () << std::endl
;
125 virtual void after_read (const char_type
* /*buffer*/, int length_read
)
127 if (this->read_length_
== 0)
129 this->in_length_
= this->response ().get_content_length ();
131 this->read_length_
+= length_read
;
132 std::cout
<< "\r [" << this->read_length_
<< '/';
133 if (this->in_length_
!= ACE::HTTP::Response::UNKNOWN_CONTENT_LENGTH
)
135 std::cout
<< this->in_length_
<< "] " << ((this->read_length_
* 100) / this->in_length_
) << "%";
142 virtual void on_eof ()
144 ACE::HTTP::ClientRequestHandler::on_eof ();
145 std::cout
<< std::endl
;
146 this->read_length_
= 0;
155 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
157 std::unique_ptr
<std::ofstream
> fout
;
158 std::ostream
* sout
= &std::cout
;
160 if (!parse_args (argc
, argv
))
165 #if defined (ACE_HAS_SSL) && ACE_HAS_SSL == 1
166 ACE::HTTPS::Context::set_default_ssl_mode (ssl_mode
);
167 ACE::HTTPS::Context::set_default_verify_mode (verify_peer
);
168 ACE::HTTPS::Context::instance ().use_default_ca ();
169 if (!private_key
.empty ())
171 if (certificate
.empty ())
173 std::cerr
<< "ERROR: private key file [" << private_key
<< "] requires certificate file to be specified." << std::endl
;
176 if (!ACE::HTTPS::Context::instance ().set_key_files (private_key
.c_str (), certificate
.c_str ()))
178 std::cerr
<< "ERROR: failed to set private key [" << private_key
<< "]." << std::endl
;
182 if (!ca_location
.empty ())
184 INET_DEBUG (6, (LM_INFO
, DLINFO
ACE_TEXT ("loading trusted CA [%C]\n"), ca_location
.c_str ()));
185 if (!ACE::HTTPS::Context::instance ().load_trusted_ca (ca_location
.c_str ()))
187 std::cerr
<< "ERROR: failed to load trusted CA from [" << ca_location
<< "]." << std::endl
;
190 INET_DEBUG (6, (LM_INFO
, DLINFO
ACE_TEXT ("loaded [%d] trusted CA\n"), ACE::HTTPS::Context::instance ().has_trusted_ca ()));
193 ACE::INet::SSL_CallbackManager::instance ()->set_certificate_callback (new ACE::INet::SSL_CertificateAcceptor
);
196 std::cout
<< "Starting..." << std::endl
;
200 if (!outfile
.empty ())
202 fout
.reset (new std::ofstream (outfile
.c_str (), std::ios_base::binary
|std::ios_base::out
));
206 std::cerr
<< "Failed to open output file : " << outfile
.c_str () << std::endl
;
213 std::cout
<< "Parsing url [" << url
.c_str () << "]" << std::endl
;
215 std::unique_ptr
<ACE::INet::URL_Base
> url_safe (ACE::INet::URL_Base::create_from_string (url
));
217 if (url_safe
.get () == 0 || url
!= url_safe
->to_string ())
219 std::cerr
<< "Failed parsing url [" << url
<< "]" << std::endl
;
220 std::cerr
<< "\tresult = " << (url_safe
.get () == 0 ? "(null)" : url_safe
->to_string ().c_str ()) << std::endl
;
224 ACE::HTTP::URL
& http_url
= *dynamic_cast<ACE::HTTP::URL
*> (url_safe
.get ());
226 if (!proxy_hostname
.empty ())
228 std::cout
<< "Setting proxy: " << proxy_hostname
.c_str () << ':' << proxy_port
<< std::endl
;
229 http_url
.set_proxy (proxy_hostname
, proxy_port
);
232 std::cout
<< "Opening url...";
233 My_HTTP_RequestHandler my_rh
;
234 ACE::INet::URLStream urlin
= http_url
.open (my_rh
);
237 std::cout
<< "Received response "
238 << (int)my_rh
.response ().get_status ().get_status ()
240 << my_rh
.response ().get_status ().get_reason ().c_str ()
242 if (my_rh
.response ().get_status ().is_ok ())
244 std::cout
<< "Length: ";
245 if (my_rh
.response ().get_content_length () != ACE::HTTP::Response::UNKNOWN_CONTENT_LENGTH
)
246 std::cout
<< my_rh
.response ().get_content_length () << " [";
248 std::cout
<< "(unknown) [";
249 if (my_rh
.response ().get_content_type () != ACE::HTTP::Response::UNKNOWN_CONTENT_TYPE
)
250 std::cout
<< my_rh
.response ().get_content_type ().c_str ();
252 std::cout
<< "(unknown)";
253 std::cout
<< "]" << std::endl
;
256 std::cout
<< "Saving to: ";
257 if (!outfile
.empty ())
258 std::cout
<< '\'' << outfile
.c_str () << '\'' << std::endl
;
260 std::cout
<< "(stdout)" << std::endl
;
262 (*sout
) << urlin
->rdbuf ();
268 std::cerr
<< "ERROR: No URL specified!" << std::endl
;
273 std::cout
<< "Done" << std::endl
;