3 #include "libcli/libcli.h"
4 #include "lib/events/events.h"
5 #include "libcli/resolve/resolve.h"
6 #include "param/param.h"
7 #include "libcli/raw/raw_proto.h"
8 #include "libcli/http/http.h"
9 #include "credentials.h"
10 #include "util/tevent_ntstatus.h"
11 #include "lib/tls/tls.h"
12 #include "lib/cmdline/cmdline.h"
15 struct http_client_info
{
16 struct http_conn
*http_conn
;
18 const char *server_addr
;
19 struct tstream_tls_params
*tls_params
;
20 struct cli_credentials
*creds
;
21 struct loadparm_context
*lp_ctx
;
25 static bool send_http_request(TALLOC_CTX
*mem_ctx
,
26 struct tevent_context
*ev_ctx
,
27 struct http_client_info
* es
,
31 struct http_request
*http_req
= NULL
;
32 struct tevent_req
*req
= NULL
;
34 struct http_request
*http_response
= NULL
;
37 http_req
= talloc_zero(mem_ctx
, struct http_request
);
39 DBG_ERR("no memory\n");
43 uri
= talloc_strdup(mem_ctx
, es
->uri
);
45 http_req
->type
= HTTP_REQ_POST
;
47 http_req
->body
= data_blob_null
;
48 http_req
->major
= '1';
49 http_req
->minor
= '1';
51 http_add_header(mem_ctx
, &http_req
->headers
,
52 "User-Agent", "Samba/http_test");
53 http_add_header(mem_ctx
, &http_req
->headers
,
56 req
= http_send_auth_request_send(mem_ctx
,
63 if (!tevent_req_set_endtime(req
, ev_ctx
, timeval_current_ofs(10, 0))) {
64 DBG_ERR("Failed to set timeout\n");
68 if (!tevent_req_poll_ntstatus(req
, ev_ctx
, pstatus
)) {
69 DBG_ERR("Failed to connect: %s\n", nt_errstr(*pstatus
));
73 status
= http_send_auth_request_recv(req
);
74 if (!NT_STATUS_IS_OK(status
)) {
75 DBG_ERR("Auth request failed: %s\n", nt_errstr(status
));
79 req
= http_read_response_send(mem_ctx
,
84 DBG_ERR("no memory\n");
88 if (!tevent_req_set_endtime(req
, ev_ctx
, timeval_current_ofs(10, 0))) {
89 DBG_ERR("Failed to set timeout\n");
93 if (!tevent_req_poll_ntstatus(req
, ev_ctx
, pstatus
)) {
94 DBG_ERR("Failed to read_resonse: %s\n", nt_errstr(*pstatus
));
98 *pstatus
= http_read_response_recv(req
, mem_ctx
, &http_response
);
100 if (!NT_STATUS_IS_OK(*pstatus
)) {
101 DBG_ERR("Failed to receive response: %s\n", nt_errstr(*pstatus
));
104 /* following are not 'hard' errors */
105 if (http_response
->response_code
!= 200) {
106 fprintf(stdout
, "HTTP server response: %u\n",
107 http_response
->response_code
);
112 if (http_response
->body
.length
== 0) {
113 fprintf(stdout
, "unexpected 0 len response\n");
117 DBG_ERR("response: len (%d)\n%s\n",
118 (int)http_response
->body
.length
,
119 talloc_strndup(mem_ctx
,
120 (char *)http_response
->body
.data
,
121 http_response
->body
.length
));
122 fprintf(stdout
,"%s", talloc_strndup(mem_ctx
,
123 (char *)http_response
->body
.data
,
124 http_response
->body
.length
));
129 int main(int argc
, const char *argv
[])
133 struct tevent_context
*ev_ctx
;
136 struct http_client_info
*http_info
= NULL
;
137 bool use_tls
= false;
140 struct tevent_req
*req
= NULL
;
141 bool connected
= false;
143 const char **const_argv
= discard_const_p(const char *, argv
);
146 const char *ca_file
= NULL
;
148 size_t response_size
= 8192000;
149 struct cli_credentials
*cli_creds
;
151 struct poptOption long_options
[] = {
155 .longName
= "usetls",
157 .argInfo
= POPT_ARG_NONE
,
160 .descrip
= "Use tls",
161 .argDescrip
= "enable tls",
164 .longName
= "ip-address",
166 .argInfo
= POPT_ARG_STRING
,
169 .descrip
= "Use this IP to connect to",
175 .argInfo
= POPT_ARG_INT
,
178 .descrip
= "port to connect to",
179 .argDescrip
= "port",
182 .longName
= "cacart",
184 .argInfo
= POPT_ARG_STRING
,
187 .descrip
= "CA certificate to verify peer against",
188 .argDescrip
= "ca cert",
193 .argInfo
= POPT_ARG_STRING
,
196 .descrip
= "uri to send as part of http request",
201 .argInfo
= POPT_ARG_LONG
,
202 .arg
= &response_size
,
203 .descrip
= "response size",
206 POPT_COMMON_CREDENTIALS
210 mem_ctx
= talloc_init("http_test");
213 DBG_ERR("Not enough memory\n");
218 http_info
= talloc_zero(mem_ctx
, struct http_client_info
);
220 if (http_info
== NULL
) {
221 DBG_ERR("Not enough memory\n");
226 ok
= samba_cmdline_init(mem_ctx
,
227 SAMBA_CMDLINE_CONFIG_CLIENT
,
228 false /* require_smbconf */);
230 DBG_ERR("Failed to init cmdline parser!\n");
235 pc
= samba_popt_get_context(getprogname(),
241 DBG_ERR("Failed to setup popt context!\n");
248 http_info
->server_addr
= "localhost";
249 http_info
->uri
= "/_search?pretty";
251 while ((opt
= poptGetNextOpt(pc
)) != -1) {
257 ca_file
= talloc_strdup(mem_ctx
,
259 if (ca_file
== NULL
) {
260 DBG_ERR("Not enough memory\n");
267 http_info
->server_addr
= talloc_strdup(mem_ctx
,
269 if (http_info
->server_addr
== NULL
) {
270 DBG_ERR("Not enough memory\n");
277 http_info
->uri
= talloc_strdup(mem_ctx
,
279 if (http_info
->uri
== NULL
) {
280 DBG_ERR("Not enough memory\n");
289 if (use_tls
&& ca_file
== NULL
) {
290 DBG_ERR("No cacert\n");
292 poptPrintUsage(pc
, stderr
, 0);
299 http_info
->server_port
= port
;
301 ev_ctx
= s4_event_context_init(mem_ctx
);
303 DBG_ERR("Not enough memory\n");
309 cli_creds
= samba_cmdline_get_creds();
310 if (!cli_credentials_is_anonymous(cli_creds
)) {
311 http_info
->creds
= cli_credentials_init(mem_ctx
);
312 cli_credentials_set_username(
314 cli_credentials_get_username(cli_creds
),
316 cli_credentials_set_password(http_info
->creds
,
317 cli_credentials_get_password(cli_creds
),
320 DBG_DEBUG("Anonymous creds!!!\n");
321 http_info
->creds
= cli_creds
;
323 if (http_info
->creds
== NULL
) {
324 DBG_ERR("Failed to create creds\n");
328 http_info
->lp_ctx
= samba_cmdline_get_lp_ctx();
330 DBG_ERR("retries = %d/%d, Using server %s, port %d, using tls %s\n",
332 http_info
->server_addr
,
333 http_info
->server_port
,
334 use_tls
? "true" : "false");
336 while (count
< retries
) {
338 DBG_ERR("Connecting to HTTP [%s] port [%"PRIu16
"]%s\n",
339 http_info
->server_addr
, http_info
->server_port
,
340 use_tls
? " with tls" : " without tls");
342 bool system_cas
= false;
343 const char * const *ca_dirs
= NULL
;
344 const char *crl_file
= NULL
;
345 const char *tls_priority
= "NORMAL:-VERS-SSL3.0";
346 enum tls_verify_peer_state verify_peer
=
347 TLS_VERIFY_PEER_CA_ONLY
;
349 status
= tstream_tls_params_client(mem_ctx
,
356 http_info
->server_addr
,
357 &http_info
->tls_params
);
358 if (!NT_STATUS_IS_OK(status
)) {
359 DBG_ERR("Failed tstream_tls_params_client - %s\n",
366 req
= http_connect_send(mem_ctx
,
368 http_info
->server_addr
,
369 http_info
->server_port
,
371 http_info
->tls_params
);
372 if (!tevent_req_poll_ntstatus(req
, ev_ctx
, &status
)) {
377 error
= http_connect_recv(req
,
379 &http_info
->http_conn
);
382 DBG_ERR("HTTP connection failed retry %d/%d: %s\n", count
, retries
, strerror(error
));
384 DBG_ERR("HTTP connection succeeded\n");
391 DBG_ERR("Leaving early\n");
396 if (!send_http_request(mem_ctx
, ev_ctx
, http_info
, response_size
, &status
)) {
397 DBG_ERR("Failure\n");
403 TALLOC_FREE(mem_ctx
);