From: EunBong Song Date: Thu, 25 May 2017 10:40:58 +0000 (+0900) Subject: examples/http: support option parameters X-Git-Tag: 1.1_Public_Release~457^2~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=086f9c5700287375b7d19f7e7e11ea6264372516;p=rtos%2Ftinyara.git examples/http: support option parameters Now that webclient supports option parameters input. * Webclient usage. . webclient GET http://127.0.0.1/ async=1 . webclient PUT https://127.0.0.1/ async=1 entity=senddata * Options . async=1 : Enable asynchronous mode (default is synchronous) . chunked=1 : Enable chunked encoding (default is disabled) . entity=DATA : Input entity data (default is NULL) . test_entity=SIZE : Input test entity dummy data (default is 0) Change-Id: I074a74507c72813621617731cd9215071cb7b461 Signed-off-by: Junyeon LEE --- diff --git a/apps/examples/webclient/README.txt b/apps/examples/webclient/README.txt index fdc1154..76c70b7 100644 --- a/apps/examples/webclient/README.txt +++ b/apps/examples/webclient/README.txt @@ -2,14 +2,18 @@ examples/webclient ^^^^^^^^^^^^^^^^^^ This is an example of webclient. - It is executed by "webclient ( )" command. - and parameters should be given, and parameters are optional. + It is executed by "webclient [options]" command. + and parameters should be given, [options] parameters are optional. is one if "GET", "POST", "PUT", "DELETE". should start with "http://" or "https://". - is a string value and its default value is NULL. + + [options] parameter support several different options. + async=1 : Enable asynchronous mode (default is synchronous) + chunked=1 : Enable chunked encoding (default is disabled) + entity=DATA : Input entity data (default is NULL) + test_entity=SIZE : Input test entity dummy data (default is 0) + The way of sending an entity is content-length by default. - If is "c", it sends an entity with chunked encoding. Configs (see the details on Kconfig): * CONFIG_EXAMPLES_WEBCLIENT - diff --git a/apps/examples/webclient/webclient_main.c b/apps/examples/webclient/webclient_main.c index eb765c2..d4773bd 100644 --- a/apps/examples/webclient/webclient_main.c +++ b/apps/examples/webclient/webclient_main.c @@ -126,6 +126,15 @@ const char c_cli_key_rsa[] = "DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" "VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" "Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" "wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" "c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" "33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" "ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" "BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" "KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" "UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" "7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" "gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" "-----END RSA PRIVATE KEY-----\r\n"; +struct http_client_ssl_config_t g_config = { + (char *)c_ca_crt_rsa, (char *)c_cli_crt_rsa, (char *)c_cli_key_rsa, + sizeof(c_ca_crt_rsa), sizeof(c_cli_crt_rsa), sizeof(c_cli_key_rsa), 2 +}; + +static int g_https; +static int g_async; +static int g_testentity; + static const char headerfield_connect[] = "Connect"; static const char headerfield_close[] = "close"; static const char headerfield_useragent[] = "User-Agent"; @@ -140,22 +149,27 @@ static const char headerfield_tinyara[] = "TinyARA"; static void callback(struct http_client_response_t *response) { - printf("in response callback\n"); + printf("----------async response----------\n"); printf("status %d %s\n", response->status, response->phrase); printf("%s\n", response->entity); + printf("---------------------------------\n"); } static void dump_webclient_usage(void) { printf("\n webclient usage:\n"); - printf(" $ webclient [method] [uri] [entity] [encoding]\n"); + printf(" $ webclient [options...] \n"); printf("\n"); - printf(" [method] : %%s (GET, PUT, POST, DELETE)\n"); - printf(" [uri] : %%s (Host address : should be started with http:// or https://)\n"); - printf(" [entity] : %%s (Entity : default is NULL)\n"); - printf(" [encoding] : %%s (Enable the chenked encodning with 'c' option)\n"); + printf(" : %%s (GET, PUT, POST, DELETE)\n"); + printf(" : %%s (Host address : should be started with http:// or https://)\n"); + printf("\n [options...] \n"); + printf(" async=1 Enable asynchronous mode (default is synchronous)\n"); + printf(" chunked=1 Enable chunked encoding (default is disabled)\n"); + printf(" entity=DATA Set entity data (default is NULL)\n"); + printf(" test_entity=SIZE Test entity size (default is 0)\n"); printf("\n example:\n"); printf(" $ webclient GET https://127.0.0.1/\n"); + printf(" $ webclient GET https://127.0.0.1/ async=1 entity=data\n"); } /**************************************************************************** @@ -166,64 +180,102 @@ static void dump_webclient_usage(void) * Name: wget_main ****************************************************************************/ -pthread_addr_t webclient_cb(void *arg) +int webclient_init_request(void *arg, struct http_client_request_t *request) { - int argc; + int argc, i; char **argv; + char *p, *q; struct webclient_input *input; - struct http_client_request_t request; - struct http_keyvalue_list_t headers; - struct http_client_response_t response; -#ifdef CONFIG_NET_SECURITY_TLS - struct http_client_ssl_config_t ssl_config; -#endif input = arg; argc = input->argc; argv = input->argv; - /* Many embedded network interfaces must have a software assigned MAC */ - - /* Then start the server */ - - /* argument1 is method. default is GET */ + g_async = 0; + g_testentity = 0; + memset(request, 0, sizeof(struct http_client_request_t)); if (argc < 3) { - dump_webclient_usage(); - return NULL; + return -1; } if (!strcmp(argv[1], "GET")) { - request.method = WGET_MODE_GET; + request->method = WGET_MODE_GET; } else if (!strcmp(argv[1], "POST")) { - request.method = WGET_MODE_POST; + request->method = WGET_MODE_POST; } else if (!strcmp(argv[1], "PUT")) { - request.method = WGET_MODE_PUT; + request->method = WGET_MODE_PUT; } else if (!strcmp(argv[1], "DELETE")) { - request.method = WGET_MODE_DELETE; + request->method = WGET_MODE_DELETE; } else { dump_webclient_usage(); - return NULL; + return -1; } /* argument2 is url. */ - request.url = argv[2]; + request->url = argv[2]; +#ifdef CONFIG_NET_SECURITY_TLS + if (!strncmp(request->url, "https", 5)) { + g_https = 1; + } else +#endif + if (!strncmp(request->url, "http", 4)) { + g_https = 0; + } else { + return -1; + } - /* argument3 is entity. default is NULL */ - request.entity = NULL; - if (argc >= 4) { - request.entity = argv[3]; + for (i = 3; i < argc; i++) { + p = argv[i]; + if ((q = strchr(p, '=')) == NULL) { + return -1; + } + *q++ = '\0'; + + if (strcmp(p, "async") == 0) { + g_async = atoi(q); + } else if (strcmp(p, "chunked") == 0) { + request->encoding = atoi(q); + } else if (strcmp(p, "entity") == 0) { + request->entity = q; + } else if (strcmp(p, "test_entity") == 0) { + int t = atoi(q); + if (t > 0 && t <= WEBCLIENT_CONF_MAX_ENTITY_SIZE) { + request->entity = malloc(t); + if (request->entity == NULL) { + return -1; + } + g_testentity = 1; + memset(request->entity, '1', t); + } else { + printf("entity is too big\n"); + return -1; + } + } else { + return -1; + } } - /* argument4 is encoding selection. default is content-length */ - request.encoding = CONTENT_LENGTH; - if (argc >= 5) { - if (!strcmp(argv[4], "c")) { - request.encoding = CHUNKED_ENCODING; + request->buflen = WEBCLIENT_BUF_SIZE; + return 0; +} + +pthread_addr_t webclient_cb(void *arg) +{ + struct http_client_request_t request; + struct http_keyvalue_list_t headers; + struct http_client_response_t response; + struct http_client_ssl_config_t *ssl_config = NULL; + + if (webclient_init_request(arg, &request)) { + dump_webclient_usage(); + if (g_testentity && request.entity) { + free(request.entity); } + return NULL; } - request.buflen = WEBCLIENT_BUF_SIZE; + ssl_config = g_https? &g_config : NULL; /* before sending request, * must initialize keyvalue list for request headers @@ -233,80 +285,47 @@ pthread_addr_t webclient_cb(void *arg) http_keyvalue_list_add(&headers, headerfield_useragent, headerfield_tinyara); request.headers = &headers; -#ifdef CONFIG_NET_SECURITY_TLS - /* send HTTPS request */ - if (!strncmp(request.url, "https", 5)) { - ssl_config.root_ca = (char *)c_ca_crt_rsa; - ssl_config.root_ca_len = sizeof(c_ca_crt_rsa); - ssl_config.dev_cert = (char *)c_cli_crt_rsa; - ssl_config.dev_cert_len = sizeof(c_cli_crt_rsa); - ssl_config.private_key = (char *)c_cli_key_rsa; - ssl_config.private_key_len = sizeof(c_cli_key_rsa); - /* before sending request by sync function, - * must initialize response structure - */ - if (http_client_response_init(&response) < 0) { - printf("fail to init\n"); - } else { - if (http_client_send_request(&request, &ssl_config, &response)) { - printf("fail to send request\n"); - http_client_response_release(&response); - goto release_out; - } else { - printf("----------sync response----------\n"); - printf("status %d %s\n", response.status, response.phrase); - printf("%s\n", response.entity); - printf("---------------------------------\n"); - } - /* after sending request by sync function, - * must release response structure - */ - http_client_response_release(&response); - } - - if (http_client_send_request_async(&request, &ssl_config, (wget_callback_t)callback)) { + /* before sending request by sync function, + * must initialize response structure + */ + if (g_async) { + if (http_client_send_request_async(&request, ssl_config, (wget_callback_t)callback)) { printf("fail to send request\n"); goto release_out; } - } else -#endif - if (!strncmp(request.url, "http", 4)) { - /* send HTTP request */ + /* sleep for end request */ + while (request.async_flag > 0) { + usleep(100000); + } + if (request.async_flag < 0) { + printf("fail to send request\n"); + } + } else { if (http_client_response_init(&response) < 0) { - printf("fail to init\n"); - } else { - if (http_client_send_request(&request, NULL, &response)) { - printf("fail to send request\n"); - http_client_response_release(&response); - goto release_out; - } else { - printf("----------sync response----------\n"); - printf("status %d %s\n", response.status, response.phrase); - printf("%s\n", response.entity); - printf("---------------------------------\n"); - } - http_client_response_release(&response); + printf("fail to response init\n"); + goto release_out; } - - if (http_client_send_request_async(&request, NULL, (wget_callback_t)callback)) { + if (http_client_send_request(&request, ssl_config, &response)) { printf("fail to send request\n"); goto release_out; } - } else { - printf("Wrong URI\n"); - dump_webclient_usage(); - return NULL; + printf("----------sync response----------\n"); + printf("status %d %s\n", response.status, response.phrase); + printf("%s\n", response.entity); + printf("---------------------------------\n"); } - /* sleep for end request */ - while (request.async_flag > 0) { - usleep(100000); +release_out: + if (g_testentity) { + free(request.entity); + g_testentity = 0; } - if (request.async_flag < 0) { - printf("fail to send request\n"); + /* after sending request by sync function, + * must release response structure + */ + if (g_async == 0) { + http_client_response_release(&response); } - -release_out: /* before finish of app, * must release keyvalue list for request headers */ diff --git a/apps/examples/webserver/webserver_main.c b/apps/examples/webserver/webserver_main.c index 818955b..b422bba 100644 --- a/apps/examples/webserver/webserver_main.c +++ b/apps/examples/webserver/webserver_main.c @@ -110,7 +110,7 @@ const char srv_key_rsa[] = "CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" "nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" "AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" "sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" "mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" "BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" "whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" "vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" "3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" "3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" "ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" "-----END RSA PRIVATE KEY-----\r\n"; static const char *root_url = "/"; -static const char *devid_url = "/device/:id"; +static const char *busy_url = "/busy"; static const char g_httpcontype[] = "Content-type"; static const char g_httpconhtml[] = "text/html"; @@ -135,42 +135,40 @@ void http_get_root(struct http_client_t *client, struct http_req_message *req) http_keyvalue_list_add(&response_headers, g_httpcontsize, contlen); http_keyvalue_list_add(&response_headers, g_httpconnect, g_httpcnlost); - printf(">>>> get_root\n"); + printf("===== GET_ROOT CALLBACK url : %s =====\n", req->url); if (http_send_response(client, 200, msg, &response_headers) < 0) { printf("Error: Fail to send response\n"); } http_keyvalue_list_release(&response_headers); } -void http_get_device_id(struct http_client_t *client, struct http_req_message *req) +void http_get_callback(struct http_client_t *client, struct http_req_message *req) { - char buf[128] = { 0, }; - - printf("%s\n", req->url); - printf("%s\n", req->query_string); - - snprintf(buf, sizeof(buf), "You asked for device."); + printf("===== GET CALLBACK url : %s =====\n", req->url); - if (http_send_response(client, 200, buf, NULL) < 0) { + if (http_send_response(client, 200, "GET SUCCESS", NULL) < 0) { printf("Error: Fail to send response\n"); } } -void http_get_callback(struct http_client_t *client, struct http_req_message *req) +/* PUT callback */ +void http_put_callback(struct http_client_t *client, struct http_req_message *req) { - printf("===== GET CALLBACK url : %s=====\n", req->url); + printf("===== PUT CALLBACK url : %s entity size : %d =====\n", req->url, strlen(req->entity)); - if (http_send_response(client, 200, "GET SUCCESS\n", NULL) < 0) { + if (http_send_response(client, 200, "PUT SUCCESS", NULL) < 0) { printf("Error: Fail to send response\n"); } } -/* PUT callback */ -void http_put_callback(struct http_client_t *client, struct http_req_message *req) +void http_put_busy(struct http_client_t *client, struct http_req_message *req) { - printf("===== PUT CALLBACK url : %s=====\n", req->url); + int i; + + printf("===== PUT BUSY CALLBACK url : %s entity size : %d =====\n", req->url, strlen(req->entity)); + for (i = 0; i < 100; i++) sleep(1); - if (http_send_response(client, 200, "PUT SUCCESS\n", NULL) < 0) { + if (http_send_response(client, 200, "PUT BUSY Success", NULL) < 0) { printf("Error: Fail to send response\n"); } } @@ -178,7 +176,7 @@ void http_put_callback(struct http_client_t *client, struct http_req_message *r /* POST callback */ void http_post_callback(struct http_client_t *client, struct http_req_message *req) { - printf("===== POST CALLBACK url : %s=====\n", req->url); + printf("===== POST CALLBACK url : %s =====\n", req->url); /* * in callback for POST and PUT request, @@ -190,7 +188,7 @@ void http_post_callback(struct http_client_t *client, struct http_req_message *r return; } - if (http_send_response(client, 200, "POST SUCCESS\n", NULL) < 0) { + if (http_send_response(client, 200, "POST SUCCESS", NULL) < 0) { printf("Error: Fail to send response\n"); } } @@ -198,9 +196,9 @@ void http_post_callback(struct http_client_t *client, struct http_req_message *r /* DELETE callback */ void http_delete_callback(struct http_client_t *client, struct http_req_message *req) { - printf("===== DELETE CALLBACK url : %s=====\n", req->url); + printf("===== DELETE CALLBACK url : %s =====\n", req->url); - if (http_send_response(client, 200, "DELETE SUCCESS\n", NULL) < 0) { + if (http_send_response(client, 200, "DELETE SUCCESS", NULL) < 0) { printf("Error: Fail to send response\n"); } } @@ -316,9 +314,10 @@ void register_callbacks(struct http_server_t *server) { http_server_register_cb(server, HTTP_METHOD_GET, NULL, http_get_callback); http_server_register_cb(server, HTTP_METHOD_GET, root_url, http_get_root); - http_server_register_cb(server, HTTP_METHOD_GET, devid_url, http_get_device_id); http_server_register_cb(server, HTTP_METHOD_PUT, NULL, http_put_callback); + http_server_register_cb(server, HTTP_METHOD_PUT, busy_url, http_put_busy); + http_server_register_cb(server, HTTP_METHOD_POST, NULL, http_post_callback); http_server_register_cb(server, HTTP_METHOD_DELETE, NULL, http_delete_callback); @@ -333,9 +332,10 @@ void deregister_callbacks(struct http_server_t *server) { http_server_deregister_cb(server, HTTP_METHOD_GET, NULL); http_server_deregister_cb(server, HTTP_METHOD_GET, root_url); - http_server_deregister_cb(server, HTTP_METHOD_GET, devid_url); http_server_deregister_cb(server, HTTP_METHOD_PUT, NULL); + http_server_deregister_cb(server, HTTP_METHOD_PUT, busy_url); + http_server_deregister_cb(server, HTTP_METHOD_POST, NULL); http_server_deregister_cb(server, HTTP_METHOD_DELETE, NULL); } diff --git a/apps/include/netutils/webclient.h b/apps/include/netutils/webclient.h index 6778d21..d6c417e 100644 --- a/apps/include/netutils/webclient.h +++ b/apps/include/netutils/webclient.h @@ -101,6 +101,7 @@ struct http_client_tls_t { mbedtls_pk_context tls_pkey; mbedtls_ssl_session tls_session; }; +#endif /** * @brief SSL configure structure. @@ -115,8 +116,6 @@ struct http_client_ssl_config_t { int auth_mode; }; -#endif - /** * @brief HTTP request structure. */