/** * @brief serve_file try to serve a request via filesystem. Using webroot as root. * @param connection * @param client * @return */ static int serve_file(struct MHD_Connection *connection, t_client *client, const char *url) { s_config *config = config_get_config(); struct MHD_Response *response; char filename[PATH_MAX]; int ret = MHD_NO; const char *mimetype = NULL; size_t size; snprintf(filename, PATH_MAX, "%s/%s", config->webroot, url); int fd = open(filename, O_RDONLY); if (fd < 0) return send_error(connection, 404); mimetype = lookup_mimetype(filename); /* serving file and creating response */ size = lseek(fd, 0, SEEK_END); response = MHD_create_response_from_fd(size, fd); if (!response) return send_error(connection, 503); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; }
static int send_error(struct MHD_Connection *connection, int error) { struct MHD_Response *response = NULL; // cannot automate since cannot translate automagically between error number and MHD's status codes -- and cannot rely on MHD_HTTP_ values to provide an upper bound for an array const char *page_400 = "<html><head><title>Error 400</title></head><body><h1>Error 400 - Bad Request</h1></body></html>"; const char *page_403 = "<html><head><title>Error 403</title></head><body><h1>Error 403 - Forbidden</h1></body></html>"; const char *page_404 = "<html><head><title>Error 404</title></head><body><h1>Error 404 - Not Found</h1></body></html>"; const char *page_500 = "<html><head><title>Error 500</title></head><body><h1>Error 500 - Internal Server Error. Oh no!</body></html>"; const char *page_501 = "<html><head><title>Error 501</title></head><body><h1>Error 501 - Not Implemented</h1></body></html>"; const char *page_503 = "<html><head><title>Error 503</title></head><body><h1>Error 503 - Internal Server Error</h1></body></html>"; const char *mimetype = lookup_mimetype("foo.html"); int ret = MHD_NO; switch (error) { case 400: response = MHD_create_response_from_buffer(strlen(page_400), (char *)page_400, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_BAD_REQUEST, response); break; case 403: response = MHD_create_response_from_buffer(strlen(page_403), (char *)page_403, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, response); break; case 404: response = MHD_create_response_from_buffer(strlen(page_404), (char *)page_404, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response); break; case 500: response = MHD_create_response_from_buffer(strlen(page_500), (char *)page_500, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, response); break; case 501: response = MHD_create_response_from_buffer(strlen(page_501), (char *)page_501, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_NOT_IMPLEMENTED, response); break; case 503: response = MHD_create_response_from_buffer(strlen(page_503), (char *)page_503, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, response); break; } if (response) MHD_destroy_response(response); return ret; }
int mimetype_handler(File fc) { if (!fc) { error("File not found 404"); return error_handler(404); } if (!fc->mime) fc->mime = lookup_mimetype(fc->name.data); content_type(client.response->headers, fc->mime->type.data); return fc->mime->handler(fc); }
static int send_refresh(struct MHD_Connection *connection) { struct MHD_Response *response = NULL; const char *refresh = "<html><meta http-equiv=\"refresh\" content=\"1\"><head/></html>"; const char *mimetype = lookup_mimetype("foo.html"); int ret; response = MHD_create_response_from_buffer(strlen(refresh), (char *)refresh, MHD_RESPMEM_PERSISTENT); MHD_add_response_header(response, "Content-Type", mimetype); MHD_add_response_header (response, MHD_HTTP_HEADER_CONNECTION, "close"); ret = MHD_queue_response(connection, 200, response); return ret; }
/** * @brief serve_file try to serve a request via filesystem. Using webroot as root. * @param connection * @param client * @return */ static int serve_file(struct MHD_Connection *connection, t_client *client, const char *url) { struct stat stat_buf; s_config *config = config_get_config(); struct MHD_Response *response; char filename[PATH_MAX]; int ret = MHD_NO; const char *mimetype = NULL; off_t size; snprintf(filename, PATH_MAX, "%s/%s", config->webroot, url); /* check if file exists and is not a directory */ ret = stat(filename, &stat_buf); if (ret) { /* stat failed */ return send_error(connection, 404); } if (!S_ISREG(stat_buf.st_mode)) { #ifdef S_ISLNK /* ignore links */ if (!S_ISLNK(stat_buf.st_mode)) #endif /* S_ISLNK */ return send_error(connection, 404); } int fd = open(filename, O_RDONLY); if (fd < 0) return send_error(connection, 404); mimetype = lookup_mimetype(filename); /* serving file and creating response */ size = lseek(fd, 0, SEEK_END); if (size < 0) return send_error(connection, 404); response = MHD_create_response_from_fd(size, fd); if (!response) return send_error(connection, 503); MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; }
/** * @brief show_splashpage is called when the client clicked on Ok as well when the client doesn't know us yet. * @param connection * @param client * @return */ static int show_splashpage(struct MHD_Connection *connection, t_client *client) { struct MHD_Response *response; struct templater templor; s_config *config = config_get_config(); int ret = -1; char filename[PATH_MAX]; const char *mimetype; int size = 0, bytes = 0; int splashpage_fd; char *splashpage_result; char *splashpage_tmpl; snprintf(filename, PATH_MAX, "%s/%s",config->webroot ,config->splashpage); splashpage_fd = open(filename, O_RDONLY); if (splashpage_fd < 0) return send_error(connection, 404); mimetype = lookup_mimetype(filename); /* input size */ size = lseek(splashpage_fd, 0, SEEK_END); lseek(splashpage_fd, 0, SEEK_SET); /* we TMPLVAR_SIZE for template variables */ splashpage_tmpl = calloc(1, size); splashpage_result = calloc(1, size + TMPLVAR_SIZE); while (bytes < size) { ret = read(splashpage_fd, splashpage_tmpl+bytes, size-bytes); if (ret < 0) { free(splashpage_result); free(splashpage_tmpl); close(splashpage_fd); return send_error(connection, 503); } bytes += ret; } char *uptime = get_uptime_string(); char *nclients = NULL; char *maxclients = NULL; char *denyaction = NULL; char *authaction = NULL; char *authtarget = NULL; const char *redirect_url = NULL; char redirect_url_encoded[2048]; char *imagesdir = NULL; char *pagesdir = NULL; memset(redirect_url_encoded, 0, sizeof(redirect_url_encoded)); redirect_url = get_redirect_url(connection); if (redirect_url) { uh_urlencode(redirect_url_encoded, sizeof(redirect_url_encoded), redirect_url, strlen(redirect_url)); } safe_asprintf(&nclients, "%d", get_client_list_length()); safe_asprintf(&maxclients, "%d", config->maxclients); safe_asprintf(&denyaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->denydir); safe_asprintf(&authaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->authdir); safe_asprintf(&authtarget, "http://%s:%d/%s/?token=%s&redir=%s", config->gw_address, config->gw_port, config->authdir, client->token, redirect_url_encoded); safe_asprintf(&authaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->authdir); safe_asprintf(&pagesdir, "/%s", config->pagesdir); safe_asprintf(&imagesdir, "/%s", config->imagesdir); tmpl_init_templor(&templor); tmpl_set_variable(&templor, "authaction", authaction); tmpl_set_variable(&templor, "authtarget", authtarget); tmpl_set_variable(&templor, "clientip", client->ip); tmpl_set_variable(&templor, "clientmac", client->mac); // tmpl_set_variable(&templor, "content", VERSION); tmpl_set_variable(&templor, "denyaction", denyaction); tmpl_set_variable(&templor, "error_msg", ""); tmpl_set_variable(&templor, "gatewaymac", config->gw_mac); tmpl_set_variable(&templor, "gatewayname", config->gw_name); tmpl_set_variable(&templor, "imagesdir", imagesdir); tmpl_set_variable(&templor, "pagesdir", pagesdir); tmpl_set_variable(&templor, "maxclients", maxclients); tmpl_set_variable(&templor, "nclients", nclients); tmpl_set_variable(&templor, "redir", redirect_url); tmpl_set_variable(&templor, "tok", client->token); tmpl_set_variable(&templor, "uptime", uptime); tmpl_set_variable(&templor, "version", VERSION); tmpl_parse(&templor, splashpage_result, size + TMPLVAR_SIZE, splashpage_tmpl, size); free(authaction); free(denyaction); free(maxclients); free(nclients); free(uptime); free(splashpage_tmpl); free(imagesdir); response = MHD_create_response_from_buffer(strlen(splashpage_result), (void *)splashpage_result, MHD_RESPMEM_MUST_FREE); if (!response) { close(splashpage_fd); return send_error(connection, 503); } MHD_add_response_header(response, "Content-Type", mimetype); ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); close(splashpage_fd); return ret; }
int parseable_file(File fc) { if (!fc->mime) fc->mime = lookup_mimetype(fc->name.data); return fc->mime->handler == lws_handler; }