example.c (3633B)
1 #include <stdbool.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include "finwo/fnet.h" 7 #include "finwo/http-parser.h" 8 #include "pierreguillot/thread.h" 9 #include "tidwall/buf.h" 10 11 12 #include "http-server.h" 13 14 uint16_t targetPort = 8080; 15 16 void onServing(char *addr, uint16_t port, void *udata) { 17 printf("Serving at %s:%d\n", addr, port); 18 } 19 20 const int countDownOrg = 20; 21 int countDown = countDownOrg; 22 void onTick(void *udata) { 23 struct http_server_opts *opts = udata; 24 25 // Handle auto-shutdown 26 printf("Shutdown in %d second(s)\n", --countDown); 27 if (countDown <= 0) { 28 opts->shutdown = true; 29 fnet_shutdown(); 30 return; 31 } 32 33 // Handle port re-assign 34 if (opts->port != targetPort) { 35 opts->port = targetPort; 36 fnet_close(opts->listen_connection); 37 } 38 39 } 40 41 void route_get_hello(struct http_server_reqdata *reqdata) { 42 http_parser_header_set(reqdata->reqres->response, "Content-Type", "text/plain"); 43 reqdata->reqres->response->body = calloc(1, sizeof(struct buf)); 44 reqdata->reqres->response->body->data = strdup("Hello World\n"); 45 reqdata->reqres->response->body->len = strlen(reqdata->reqres->response->body->data); 46 http_server_response_send(reqdata, true); 47 countDown = countDownOrg; 48 return; 49 } 50 51 void route_get_hello_named(struct http_server_reqdata *reqdata) { 52 http_parser_header_set(reqdata->reqres->response, "Content-Type", "text/plain"); 53 54 const char *name = http_parser_meta_get(reqdata->reqres->request, "param:name"); 55 if (!name) name = "there"; 56 57 reqdata->reqres->response->body = calloc(1, sizeof(struct buf)); 58 reqdata->reqres->response->body->data = calloc(7 + strlen(name), sizeof(char)); 59 strcat(reqdata->reqres->response->body->data, "Hello "); 60 strcat(reqdata->reqres->response->body->data, name); 61 reqdata->reqres->response->body->len = strlen(reqdata->reqres->response->body->data); 62 http_server_response_send(reqdata, true); 63 countDown = countDownOrg; 64 return; 65 } 66 67 void route_post_port(struct http_server_reqdata *reqdata) { 68 http_parser_header_set(reqdata->reqres->response, "Content-Type", "text/plain"); 69 targetPort = atoi(reqdata->reqres->request->body->data); 70 reqdata->reqres->response->body = calloc(1, sizeof(struct buf)); 71 reqdata->reqres->response->body->data = strdup("OK\n"); 72 reqdata->reqres->response->body->len = strlen(reqdata->reqres->response->body->data); 73 http_server_response_send(reqdata, true); 74 return; 75 } 76 77 void route_404(struct http_server_reqdata *reqdata) { 78 http_parser_header_set(reqdata->reqres->response, "Content-Type", "text/plain"); 79 reqdata->reqres->response->status = 404; 80 reqdata->reqres->response->body = calloc(1, sizeof(struct buf)); 81 reqdata->reqres->response->body->data = strdup("not found\n"); 82 reqdata->reqres->response->body->len = strlen(reqdata->reqres->response->body->data); 83 http_server_response_send(reqdata, true); 84 return; 85 } 86 87 int main() { 88 struct http_server_events evs = { 89 .serving = onServing, 90 .close = NULL, 91 .notFound = route_404, 92 .tick = onTick, 93 }; 94 struct http_server_opts opts = { 95 .evs = &evs, 96 .addr = "0.0.0.0", 97 .port = targetPort, 98 .udata = &opts, 99 }; 100 101 http_server_route("GET" , "/hello" , route_get_hello); 102 http_server_route("POST", "/port" , route_post_port); 103 http_server_route("GET" , "/hello/:name", route_get_hello_named); 104 105 /* // Launch network management thread */ 106 /* thd_thread thread; */ 107 /* thd_thread_detach(&thread, fnet_thread, NULL); */ 108 109 http_server_main(&opts); 110 fnet_shutdown(); 111 112 /* thd_thread_join(&thread); */ 113 114 printf("Server has shut down\n"); 115 }