-static int afb_req_reply_file_if_exist(struct afb_hreq *request, int dirfd, const char *filename)
-{
- int rc;
- int fd;
- unsigned int status;
- struct stat st;
- char etag[1 + 2 * sizeof(int)];
- const char *inm;
- struct MHD_Response *response;
-
- /* Opens the file or directory */
- fd = openat(dirfd, filename, O_RDONLY);
- if (fd < 0) {
- if (errno == ENOENT)
- return 0;
- afb_req_reply_error(request, MHD_HTTP_FORBIDDEN);
- return 1;
- }
-
- /* Retrieves file's status */
- if (fstat(fd, &st) != 0) {
- close(fd);
- afb_req_reply_error(request, MHD_HTTP_INTERNAL_SERVER_ERROR);
- return 1;
- }
-
- /* Don't serve directory */
- if (S_ISDIR(st.st_mode)) {
- rc = afb_req_reply_file_if_exist(request, fd, "index.html");
- close(fd);
- return rc;
- }
-
- /* Don't serve special files */
- if (!S_ISREG(st.st_mode)) {
- close(fd);
- afb_req_reply_error(request, MHD_HTTP_FORBIDDEN);
- return 1;
- }
-
- /* Check the method */
- if ((request->method & (afb_method_get | afb_method_head)) == 0) {
- close(fd);
- afb_req_reply_error(request, MHD_HTTP_METHOD_NOT_ALLOWED);
- return 1;
- }
-
- /* computes the etag */
- sprintf(etag, "%08X%08X", ((int)(st.st_mtim.tv_sec) ^ (int)(st.st_mtim.tv_nsec)), (int)(st.st_size));
-
- /* checks the etag */
- inm = MHD_lookup_connection_value(request->connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_NONE_MATCH);
- if (inm && 0 == strcmp(inm, etag)) {
- /* etag ok, return NOT MODIFIED */
- close(fd);
- if (verbose)
- fprintf(stderr, "Not Modified: [%s]\n", filename);
- response = MHD_create_response_from_buffer(0, empty_string, MHD_RESPMEM_PERSISTENT);
- status = MHD_HTTP_NOT_MODIFIED;
- } else {
- /* check the size */
- if (st.st_size != (off_t) (size_t) st.st_size) {
- close(fd);
- afb_req_reply_error(request, MHD_HTTP_INTERNAL_SERVER_ERROR);
- return 1;
- }
-
- /* create the response */
- response = MHD_create_response_from_fd((size_t) st.st_size, fd);
- status = MHD_HTTP_OK;
-
-#if defined(USE_MAGIC_MIME_TYPE)
- /* set the type */
- if (request->session->magic) {
- const char *mimetype = magic_descriptor(request->session->magic, fd);
- if (mimetype != NULL)
- MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype);
- }
-#endif
- }
-
- /* fills the value and send */
- MHD_add_response_header(response, MHD_HTTP_HEADER_CACHE_CONTROL, request->session->cacheTimeout);
- MHD_add_response_header(response, MHD_HTTP_HEADER_ETAG, etag);
- MHD_queue_response(request->connection, status, response);
- MHD_destroy_response(response);
- return 1;
-}
-
-static int afb_req_reply_file(struct afb_hreq *request, int dirfd, const char *filename)
-{
- int rc = afb_req_reply_file_if_exist(request, dirfd, filename);
- if (rc == 0)
- afb_req_reply_error(request, MHD_HTTP_NOT_FOUND);
- return 1;
-}
-
-struct afb_diralias {
- const char *alias;
- const char *directory;
- size_t lendir;
- int dirfd;
-};
-