smbd: trigger NOTIFY_ACTION_DIRLEASE_BREAK when closing a modified file
[samba4-gss.git] / source4 / client / http_test.c
blob158b2d1a8dfd2384d538910c6ca86ffc2586cefe
1 #include "includes.h"
2 #include "version.h"
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;
17 uint16_t server_port;
18 const char *server_addr;
19 struct tstream_tls_params *tls_params;
20 struct cli_credentials *creds;
21 struct loadparm_context *lp_ctx;
22 const char *uri;
25 static bool send_http_request(TALLOC_CTX *mem_ctx,
26 struct tevent_context *ev_ctx,
27 struct http_client_info* es,
28 size_t response_size,
29 NTSTATUS *pstatus)
31 struct http_request *http_req = NULL;
32 struct tevent_req *req = NULL;
33 char *uri = NULL;
34 struct http_request *http_response = NULL;
35 NTSTATUS status;
37 http_req = talloc_zero(mem_ctx, struct http_request);
38 if (!http_req) {
39 DBG_ERR("no memory\n");
40 return false;
43 uri = talloc_strdup(mem_ctx, es->uri);
45 http_req->type = HTTP_REQ_POST;
46 http_req->uri = uri;
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,
54 "Accept", "*/*");
56 req = http_send_auth_request_send(mem_ctx,
57 ev_ctx,
58 es->http_conn,
59 http_req,
60 es->creds,
61 es->lp_ctx,
62 HTTP_AUTH_BASIC);
63 if (!tevent_req_set_endtime(req, ev_ctx, timeval_current_ofs(10, 0))) {
64 DBG_ERR("Failed to set timeout\n");
65 return false;
68 if (!tevent_req_poll_ntstatus(req, ev_ctx, pstatus)) {
69 DBG_ERR("Failed to connect: %s\n", nt_errstr(*pstatus));
70 return false;
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));
76 return false;
79 req = http_read_response_send(mem_ctx,
80 ev_ctx,
81 es->http_conn,
82 response_size);
83 if (!req) {
84 DBG_ERR("no memory\n");
85 return -1;
88 if (!tevent_req_set_endtime(req, ev_ctx, timeval_current_ofs(10, 0))) {
89 DBG_ERR("Failed to set timeout\n");
90 return false;
93 if (!tevent_req_poll_ntstatus(req, ev_ctx, pstatus)) {
94 DBG_ERR("Failed to read_resonse: %s\n", nt_errstr(*pstatus));
95 return false;
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));
102 return false;
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);
108 fflush(stdout);
109 return false;
112 if (http_response->body.length == 0) {
113 fprintf(stdout, "unexpected 0 len response\n");
114 fflush(stdout);
115 return false;
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));
125 fflush(stdout);
126 return true;
129 int main(int argc, const char *argv[])
132 TALLOC_CTX *mem_ctx;
133 struct tevent_context *ev_ctx;
134 int retries = 4;
135 int count = 0;
136 struct http_client_info *http_info = NULL;
137 bool use_tls = false;
138 int res;
139 NTSTATUS status;
140 struct tevent_req *req = NULL;
141 bool connected = false;
142 poptContext pc;
143 const char **const_argv = discard_const_p(const char *, argv);
144 int opt;
145 bool ok;
146 const char *ca_file = NULL;
147 int port = 0;
148 size_t response_size = 8192000;
149 struct cli_credentials *cli_creds;
151 struct poptOption long_options[] = {
152 POPT_AUTOHELP
155 .longName = "usetls",
156 .shortName = 't',
157 .argInfo = POPT_ARG_NONE,
158 .arg = NULL,
159 .val = 't',
160 .descrip = "Use tls",
161 .argDescrip = "enable tls",
164 .longName = "ip-address",
165 .shortName = 'I',
166 .argInfo = POPT_ARG_STRING,
167 .arg = NULL,
168 .val = 'I',
169 .descrip = "Use this IP to connect to",
170 .argDescrip = "IP",
173 .longName = "port",
174 .shortName = 'p',
175 .argInfo = POPT_ARG_INT,
176 .arg = &port,
177 .val = 'p',
178 .descrip = "port to connect to",
179 .argDescrip = "port",
182 .longName = "cacart",
183 .shortName = 'c',
184 .argInfo = POPT_ARG_STRING,
185 .arg = NULL,
186 .val = 'c',
187 .descrip = "CA certificate to verify peer against",
188 .argDescrip = "ca cert",
191 .longName = "uri",
192 .shortName = 'u',
193 .argInfo = POPT_ARG_STRING,
194 .arg = NULL,
195 .val = 'u',
196 .descrip = "uri to send as part of http request",
197 .argDescrip = "uri",
200 .longName = "rsize",
201 .argInfo = POPT_ARG_LONG,
202 .arg = &response_size,
203 .descrip = "response size",
205 POPT_COMMON_SAMBA
206 POPT_COMMON_CREDENTIALS
207 POPT_TABLEEND
210 mem_ctx = talloc_init("http_test");
212 if (!mem_ctx) {
213 DBG_ERR("Not enough memory\n");
214 res = -1;
215 goto done;
218 http_info = talloc_zero(mem_ctx, struct http_client_info);
220 if (http_info == NULL) {
221 DBG_ERR("Not enough memory\n");
222 res = -1;
223 goto done;
226 ok = samba_cmdline_init(mem_ctx,
227 SAMBA_CMDLINE_CONFIG_CLIENT,
228 false /* require_smbconf */);
229 if (!ok) {
230 DBG_ERR("Failed to init cmdline parser!\n");
231 res = -1;
232 goto done;
235 pc = samba_popt_get_context(getprogname(),
236 argc,
237 const_argv,
238 long_options,
240 if (pc == NULL) {
241 DBG_ERR("Failed to setup popt context!\n");
242 res = -1;
243 goto done;
246 /* some defaults */
248 http_info->server_addr = "localhost";
249 http_info->uri = "/_search?pretty";
251 while ((opt = poptGetNextOpt(pc)) != -1) {
252 switch (opt) {
253 case 't':
254 use_tls = true;
255 break;
256 case 'c': {
257 ca_file = talloc_strdup(mem_ctx,
258 poptGetOptArg(pc));
259 if (ca_file == NULL) {
260 DBG_ERR("Not enough memory\n");
261 res = -1;
262 goto done;
264 break;
266 case 'I': {
267 http_info->server_addr = talloc_strdup(mem_ctx,
268 poptGetOptArg(pc));
269 if (http_info->server_addr == NULL) {
270 DBG_ERR("Not enough memory\n");
271 res = -1;
272 goto done;
274 break;
276 case 'u': {
277 http_info->uri = talloc_strdup(mem_ctx,
278 poptGetOptArg(pc));
279 if (http_info->uri == NULL) {
280 DBG_ERR("Not enough memory\n");
281 res = -1;
282 goto done;
284 break;
289 if (use_tls && ca_file == NULL) {
290 DBG_ERR("No cacert\n");
291 res = -1;
292 poptPrintUsage(pc, stderr, 0);
293 goto done;
296 if (!port) {
297 port = 8080;
299 http_info->server_port = port;
301 ev_ctx = s4_event_context_init(mem_ctx);
302 if (!ev_ctx) {
303 DBG_ERR("Not enough memory\n");
304 res = -1;
305 goto done;
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(
313 http_info->creds,
314 cli_credentials_get_username(cli_creds),
315 CRED_SPECIFIED);
316 cli_credentials_set_password(http_info->creds,
317 cli_credentials_get_password(cli_creds),
318 CRED_SPECIFIED);
319 } else {
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");
325 res = -1;
326 goto done;
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",
331 count, retries,
332 http_info->server_addr,
333 http_info->server_port,
334 use_tls ? "true" : "false");
336 while (count < retries) {
337 int error;
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");
341 if (use_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,
350 system_cas,
351 ca_dirs,
352 ca_file,
353 crl_file,
354 tls_priority,
355 verify_peer,
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",
360 nt_errstr(status));
361 res = -1;
362 goto done;
366 req = http_connect_send(mem_ctx,
367 ev_ctx,
368 http_info->server_addr,
369 http_info->server_port,
370 http_info->creds,
371 http_info->tls_params);
372 if (!tevent_req_poll_ntstatus(req, ev_ctx, &status)) {
373 res = -1;
374 goto done;
377 error = http_connect_recv(req,
378 mem_ctx,
379 &http_info->http_conn);
380 if (error != 0) {
381 count++;
382 DBG_ERR("HTTP connection failed retry %d/%d: %s\n", count, retries, strerror(error));
383 } else {
384 DBG_ERR("HTTP connection succeeded\n");
385 connected = true;
386 break;
390 if (!connected) {
391 DBG_ERR("Leaving early\n");
392 res = -1;
393 goto done;
396 if (!send_http_request(mem_ctx, ev_ctx, http_info, response_size, &status)) {
397 DBG_ERR("Failure\n");
398 res = -1;
399 goto done;
401 res = 0;
402 done:
403 TALLOC_FREE(mem_ctx);
404 return res;