1 module hunt.framework.http.FileResponse;
2 
3 import std.array;
4 import std.conv;
5 import std.datetime;
6 import std.json;
7 import std.path;
8 import std.file;
9 import std.stdio;
10 
11 import hunt.framework.http.Response;
12 import hunt.framework.Init;
13 import hunt.framework.util.String;
14 
15 import hunt.logging;
16 import hunt.http.server;
17 
18 /**
19  * FileResponse represents an HTTP response delivering a file.
20  */
21 class FileResponse : Response {
22     private string _file;
23     private string _name = "undefined.file";
24     private string _contentType;
25 
26     this(string filename) {
27         this.setFile(filename);
28     }
29 
30     FileResponse setFile(string filename) {
31         _file = buildPath(APP_PATH, filename);
32         string contentType = getMimeTypeByFilename(_file);
33 
34         version(HUNT_DEBUG) logInfof("_file=>%s, contentType=%s", _file, contentType);
35 
36         this.setMimeType(contentType);
37         this.setName(baseName(filename));
38         this.loadData();
39         return this;
40     }
41 
42     FileResponse setName(string name) {
43         _name = name;
44         return this;
45     }
46 
47     FileResponse setMimeType(string contentType) {
48         _contentType = contentType;
49         return this;
50     }
51 
52     FileResponse loadData() {
53         version(HUNT_DEBUG) logDebug("downloading file: ", _file);
54 
55         if (exists(_file) && !isDir(_file)) {
56             // setData([0x11, 0x22]);
57             // FIXME: Needing refactor or cleanup -@zxp at 5/24/2018, 6:49:23 PM
58             // download a huge file.
59             // read file
60             auto f = std.stdio.File(_file, "r");
61             scope (exit)
62                 f.close();
63 
64             f.seek(0);
65             // logDebug("file size: ", f.size);
66             auto buf = f.rawRead(new ubyte[cast(uint) f.size]);
67             setData(buf);
68         } else
69             throw new Exception("File does not exist: " ~ _file);
70 
71         return this;
72     }
73 
74     FileResponse setData(in ubyte[] data) {
75         header(HttpHeader.CONTENT_DISPOSITION,
76                 "attachment; filename=" ~ _name ~ "; size=" ~ (to!string(data.length)));
77         setContent(data, _contentType);
78         return this;
79     }
80 }