Line data Source code
1 : /*
2 : START OF LICENSE STUB
3 : DeDOS: Declarative Dispersion-Oriented Software
4 : Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 :
6 : This program is free software: you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation, either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : END OF LICENSE STUB
19 : */
20 : #include "local_msu.h"
21 : #include "msu_type.h"
22 : #include "msu_message.h"
23 : #include "msu_calls.h"
24 : #include "logging.h"
25 : #include "routing_strategies.h"
26 :
27 : #include "webserver/httpops.h"
28 : #include "webserver/write_msu.h"
29 : #include "webserver/fileio_msu.h"
30 : #include "webserver/cache_msu.h"
31 : #include "webserver/connection-handler.h"
32 : #include "connection-handler.h"
33 :
34 29 : static int ws_fileio_load(struct local_msu *self,
35 : struct msu_msg *msg) {
36 29 : struct response_state *resp = msg->data;
37 29 : resp->body_len = -1;
38 :
39 29 : FILE *file = fopen(resp->path, "rb");
40 29 : if (file == NULL) {
41 0 : log_info("Failed to access requested file %s with errno %d", resp->path, errno);
42 0 : resp->body_len = -1;
43 0 : resp->header_len = generate_header(resp->header, 404, MAX_HEADER_LEN, 0, NULL);
44 : } else {
45 : // Get file size
46 29 : fseek(file, 0, SEEK_END);
47 29 : unsigned int size = ftell(file);
48 29 : fseek(file, 0, SEEK_SET);
49 29 : if (size > MAX_BODY_LEN) {
50 0 : log_warn("File larger (%d) than body buffer (%d). Truncating contents.",
51 : size, MAX_BODY_LEN);
52 0 : size = MAX_BODY_LEN;
53 : }
54 :
55 : // Allocate memory for file contents and populate it
56 29 : resp->body_len = fread(resp->body, sizeof(char), size, file);
57 29 : if (resp->body_len != size) {
58 0 : log_error("Only read %d of %d bytes from file %s", resp->body_len, size, resp->path);
59 : } else {
60 29 : log_info("FileIO read %d byte from file %s", resp->body_len, resp->path);
61 : }
62 :
63 29 : fclose(file);
64 :
65 29 : char *mimetype = path_to_mimetype(resp->path);
66 29 : resp->header_len = generate_header(resp->header, 200, MAX_HEADER_LEN, resp->body_len,
67 : mimetype);
68 : }
69 :
70 29 : call_msu_type(self, &WEBSERVER_CACHE_MSU_TYPE, &msg->hdr, sizeof(*resp), resp);
71 29 : call_msu_type(self, &WEBSERVER_WRITE_MSU_TYPE, &msg->hdr, sizeof(*resp), resp);
72 :
73 29 : return 0;
74 : }
75 :
76 : struct msu_type WEBSERVER_FILEIO_MSU_TYPE = {
77 : .name = "Webserver_fileio_msu",
78 : .id = WEBSERVER_FILEIO_MSU_TYPE_ID,
79 : .receive = ws_fileio_load,
80 : .route = shortest_queue_route
81 : };
|