// Define an event handler function void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { if (ev == MG_EV_POLL) return; /* printf("ev %d\r\n", ev); */ switch (ev) { case MG_EV_ACCEPT: { char addr[32]; mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); printf("%p: Connection from %s\r\n", nc, addr); break; } case MG_EV_HTTP_REQUEST: { struct http_message *hm = (struct http_message *) ev_data; char addr[32]; mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); printf("%p: %.*s %.*s\r\n", nc, (int) hm->method.len, hm->method.p, (int) hm->uri.len, hm->uri.p); mg_send_response_line(nc, 200, "Content-Type: text/html\r\n" "Connection: close"); mg_printf(nc, "\r\n<h1>Hello, %s!</h1>\r\n" "You asked for %.*s\r\n", addr, (int) hm->uri.len, hm->uri.p); nc->flags |= MG_F_SEND_AND_CLOSE; LEDS_INVERT(LED_THREE); break; } case MG_EV_CLOSE: { printf("%p: Connection closed\r\n", nc); break; } } }
static void backend_handler(struct mg_connection *nc, int ev, void *ev_data) { struct http_message *hm = (struct http_message *) ev_data; int i; switch (ev) { case MG_EV_HTTP_REQUEST: mg_send_response_line(nc, 200, "Content-Type: text/html\r\n" "Connection: close\r\n"); mg_printf(nc, "{\"uri\": \"%.*s\", \"method\": \"%.*s\", \"body\": \"%.*s\", " "\"headers\": {", (int) hm->uri.len, hm->uri.p, (int) hm->method.len, hm->method.p, (int) hm->body.len, hm->body.p); for (i = 0; i < MG_MAX_HTTP_HEADERS && hm->header_names[i].len > 0; i++) { struct mg_str hn = hm->header_names[i]; struct mg_str hv = hm->header_values[i]; mg_printf(nc, "%s\"%.*s\": \"%.*s\"", (i != 0 ? "," : ""), (int) hn.len, hn.p, (int) hv.len, hv.p); } mg_printf(nc, "}}"); nc->flags |= MG_F_SEND_AND_CLOSE; break; default: break; } }
/* * Code common to V1 and V2 */ static void upload_handler(struct mg_connection *nc, int ev, void *p) { struct mg_http_multipart_part *mp; struct file_upload_state *fus; switch (ev) { case MG_EV_HTTP_PART_BEGIN: mp = (struct mg_http_multipart_part *) p; fus = (struct file_upload_state *) calloc(1, sizeof(*fus)); if (fus == NULL) { mg_http_send_error(nc, 500, "Out of memory"); break; } fus->fd = ipc_inst_start_ext(SOURCE_WEBSERVER, strlen(mp->file_name), mp->file_name, false); if (fus->fd < 0) { mg_http_send_error(nc, 500, "Failed to queue command"); free(fus); break; } mp->user_data = fus; break; case MG_EV_HTTP_PART_DATA: mp = (struct mg_http_multipart_part *) p; fus = (struct file_upload_state *) mp->user_data; if (!fus) break; ipc_send_data(fus->fd, (char *) mp->data.p, mp->data.len); fus->len += mp->data.len; break; case MG_EV_HTTP_PART_END: mp = (struct mg_http_multipart_part *) p; fus = (struct file_upload_state *) mp->user_data; if (!fus) break; ipc_end(fus->fd); mg_send_response_line(nc, 200, "Content-Type: text/plain\r\n" "Connection: close"); mg_send(nc, "\r\n", 2); mg_printf(nc, "Ok, %s - %d bytes.\r\n", mp->file_name, (int) fus->len); nc->flags |= MG_F_SEND_AND_CLOSE; mp->user_data = NULL; free(fus); break; } }
/* * These functions are for V1 of the protocol */ static void upload_handler_v1(struct mg_connection *nc, int ev, void *p) { struct mg_str *filename, *data; struct http_message *hm; size_t length; char buf[16]; int fd; switch (ev) { case MG_EV_HTTP_REQUEST: hm = (struct http_message *) p; filename = mg_get_http_header(hm, "X_FILENAME"); if (filename == NULL) { mg_http_send_error(nc, 403, NULL); return; } data = mg_get_http_header(hm, "Content-length"); if (data == NULL || data->len >= ARRAY_SIZE(buf)) { mg_http_send_error(nc, 403, NULL); return; } memcpy(buf, data->p, data->len); buf[data->len] = '\0'; length = strtoul(data->p, NULL, 10); if (length == 0) { mg_http_send_error(nc, 403, NULL); return; } fd = ipc_inst_start_ext(SOURCE_WEBSERVER, filename->len, filename->p, false); ipc_send_data(fd, (char *) hm->body.p, hm->body.len); ipc_end(fd); mg_send_response_line(nc, 200, "Content-Type: text/plain\r\n" "Connection: close"); mg_send(nc, "\r\n", 2); mg_printf(nc, "Ok, %.*s - %d bytes.\r\n", (int) filename->len, filename->p, (int) length); nc->flags |= MG_F_SEND_AND_CLOSE; break; default: upload_handler(nc, ev, p); break; } }