1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.util.MimeType;
13 
14 import hunt.util.AcceptMimeType;
15 
16 import hunt.collection;
17 import hunt.logging;
18 
19 import hunt.text.Charset;
20 import hunt.text.Common;
21 import hunt.Exceptions;
22 // import hunt.text;
23 import hunt.util.Traits;
24 
25 import std.algorithm;
26 import std.array;
27 import std.container.array;
28 import std.conv;
29 import std.file;
30 import std.path;
31 import std.range;
32 import std.stdio;
33 import std.string;
34 import std.uni;
35 
36 class MimeType {
37     /**
38 	 * A string equivalent of {@link MimeType#ALL}.
39 	 */
40 	enum string ALL_VALUE = "*/*";
41 
42 	/**
43 	 * A string equivalent of {@link MimeType#APPLICATION_JSON}.
44 	 */
45 	enum string APPLICATION_JSON_VALUE = "application/json";    
46     
47 	/**
48 	 * A string equivalent of {@link MimeType#APPLICATION_OCTET_STREAM}.
49 	 */
50 	enum string APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
51 
52 	/**
53 	 * A string equivalent of {@link MimeType#APPLICATION_XML}.
54 	 */
55 	enum string APPLICATION_XML_VALUE = "application/xml";
56 
57 	/**
58 	 * A string equivalent of {@link MimeType#IMAGE_GIF}.
59 	 */
60 	enum string IMAGE_GIF_VALUE = "image/gif";
61 
62 	/**
63 	 * A string equivalent of {@link MimeType#IMAGE_JPEG}.
64 	 */
65 	enum string IMAGE_JPEG_VALUE = "image/jpeg";
66 
67 	/**
68 	 * A string equivalent of {@link MimeType#IMAGE_PNG}.
69 	 */
70 	enum string IMAGE_PNG_VALUE = "image/png";
71 
72 	/**
73 	 * A string equivalent of {@link MimeType#TEXT_HTML}.
74 	 */
75 	enum string TEXT_HTML_VALUE = "text/html";
76 
77 	/**
78 	 * A string equivalent of {@link MimeType#TEXT_PLAIN}.
79 	 */
80 	enum string TEXT_PLAIN_VALUE = "text/plain";
81 
82 	/**
83 	 * A string equivalent of {@link MimeType#TEXT_XML}.
84 	 */
85 	enum string TEXT_XML_VALUE = "text/xml";        
86 
87 	/**
88 	 * Public constant mime type that includes all media ranges (i.e. "*/*").
89 	 */
90 	__gshared MimeType ALL;
91     __gshared MimeType APPLICATION_JSON;
92     __gshared MimeType APPLICATION_XML;
93     __gshared MimeType APPLICATION_JSON_8859_1;
94     __gshared MimeType APPLICATION_JSON_UTF_8;
95     __gshared MimeType APPLICATION_OCTET_STREAM;
96 
97     __gshared MimeType FORM_ENCODED;
98 
99     __gshared MimeType IMAGE_GIF;
100     __gshared MimeType IMAGE_JPEG;
101     __gshared MimeType IMAGE_PNG;
102 
103     __gshared MimeType MESSAGE_HTTP;
104     __gshared MimeType MULTIPART_BYTERANGES;
105 
106     __gshared MimeType TEXT_HTML;
107     __gshared MimeType TEXT_PLAIN;
108     __gshared MimeType TEXT_XML;
109     __gshared MimeType TEXT_JSON;
110 
111     __gshared MimeType TEXT_HTML_8859_1;
112     __gshared MimeType TEXT_HTML_UTF_8;
113 
114     __gshared MimeType TEXT_PLAIN_8859_1;
115     __gshared MimeType TEXT_PLAIN_UTF_8;
116 
117     __gshared MimeType TEXT_XML_8859_1;
118     __gshared MimeType TEXT_XML_UTF_8;
119 
120     __gshared MimeType TEXT_JSON_8859_1;
121     __gshared MimeType TEXT_JSON_UTF_8;
122 
123     __gshared Array!MimeType values;
124 
125     shared static this() {
126 
127         ALL = new MimeType(ALL_VALUE);
128         
129         APPLICATION_JSON = new MimeType(APPLICATION_JSON_VALUE, StandardCharsets.UTF_8);
130         APPLICATION_JSON_8859_1 = new MimeType("application/json;charset=iso-8859-1", APPLICATION_JSON);
131         APPLICATION_JSON_UTF_8 = new MimeType("application/json;charset=utf-8", APPLICATION_JSON);
132         APPLICATION_OCTET_STREAM = new MimeType(APPLICATION_OCTET_STREAM_VALUE);
133         APPLICATION_XML = new MimeType(APPLICATION_XML_VALUE, StandardCharsets.UTF_8);
134 
135         IMAGE_GIF = new MimeType(IMAGE_GIF_VALUE);
136         IMAGE_JPEG = new MimeType(IMAGE_JPEG_VALUE);
137         IMAGE_PNG = new MimeType(IMAGE_PNG_VALUE);
138 
139         MESSAGE_HTTP = new MimeType("message/http");
140         MULTIPART_BYTERANGES = new MimeType("multipart/byteranges");
141 
142         TEXT_HTML = new MimeType(TEXT_HTML_VALUE);
143         TEXT_PLAIN = new MimeType(TEXT_PLAIN_VALUE);
144         TEXT_XML = new MimeType(TEXT_XML_VALUE);
145         TEXT_JSON = new MimeType("text/json", StandardCharsets.UTF_8);
146 
147         TEXT_HTML_8859_1 = new MimeType("text/html;charset=iso-8859-1", TEXT_HTML);
148         TEXT_HTML_UTF_8 = new MimeType("text/html;charset=utf-8", TEXT_HTML);
149 
150         TEXT_PLAIN_8859_1 = new MimeType("text/plain;charset=iso-8859-1", TEXT_PLAIN);
151         TEXT_PLAIN_UTF_8 = new MimeType("text/plain;charset=utf-8", TEXT_PLAIN);
152 
153         TEXT_XML_8859_1 = new MimeType("text/xml;charset=iso-8859-1", TEXT_XML);
154         TEXT_XML_UTF_8 = new MimeType("text/xml;charset=utf-8", TEXT_XML);
155 
156         TEXT_JSON_8859_1 = new MimeType("text/json;charset=iso-8859-1", TEXT_JSON);
157         TEXT_JSON_UTF_8 = new MimeType("text/json;charset=utf-8", TEXT_JSON);
158 
159         values.insertBack(ALL);
160         values.insertBack(APPLICATION_JSON);
161         values.insertBack(APPLICATION_XML);
162         values.insertBack(APPLICATION_JSON_8859_1);
163         values.insertBack(APPLICATION_JSON_UTF_8);
164         values.insertBack(APPLICATION_OCTET_STREAM);
165         
166         values.insertBack(IMAGE_GIF);
167         values.insertBack(IMAGE_JPEG);
168         values.insertBack(IMAGE_PNG);
169 
170         values.insertBack(MESSAGE_HTTP);
171         values.insertBack(MULTIPART_BYTERANGES);
172         
173         values.insertBack(TEXT_HTML);
174         values.insertBack(TEXT_PLAIN);
175         values.insertBack(TEXT_XML);
176         values.insertBack(TEXT_JSON);
177         values.insertBack(TEXT_HTML_8859_1);
178         values.insertBack(TEXT_HTML_UTF_8);
179         values.insertBack(TEXT_PLAIN_8859_1);
180         values.insertBack(TEXT_PLAIN_UTF_8);
181         values.insertBack(TEXT_XML_8859_1);
182         values.insertBack(TEXT_XML_UTF_8);
183         values.insertBack(TEXT_JSON_8859_1);
184         values.insertBack(TEXT_JSON_UTF_8);
185     }
186 
187 
188     private string _string;
189     private MimeType _base;
190     private ByteBuffer _buffer;
191     // private Charset _charset;
192     private string _charsetString;
193     private bool _assumedCharset;
194 
195     this(string s) {
196         _string = s;
197         _buffer = BufferUtils.toBuffer(s);
198         _base = this;
199         // _charset = null;
200         _charsetString = null;
201         _assumedCharset = false;
202     }
203 
204     this(string s, MimeType base) {
205         _string = s;
206         _buffer = BufferUtils.toBuffer(s);
207         _base = base;
208         ptrdiff_t i = s.indexOf(";charset=");
209         // _charset = Charset.forName(s.substring(i + 9));
210         if(i == -1) {
211             _charsetString = null;
212             _assumedCharset = true;
213         } else {
214             _charsetString = s[i + 9 .. $].toLower();
215             _assumedCharset = false;
216         }
217     }
218 
219     this(string s, string charset) {
220         _string = s;
221         _base = this;
222         _buffer = BufferUtils.toBuffer(s);
223         // _charset = charset;
224         _charsetString = charset.toLower();
225         _assumedCharset = true;
226     }
227 
228     // ByteBuffer asBuffer() {
229     //     return _buffer.asReadOnlyBuffer();
230     // }
231 
232     // Charset getCharset() {
233     //     return _charset;
234     // }
235 
236     string getCharsetString() {
237         return _charsetString;
238     }
239 
240     bool isSame(string s) {
241         return _string.equalsIgnoreCase(s);
242     }
243 
244     string asString() {
245         return _string;
246     }
247 
248     override
249     string toString() {
250         return _string;
251     }
252 
253     bool isCharsetAssumed() {
254         return _assumedCharset;
255     }
256 
257     MimeType getBaseType() {
258         return _base;
259     }
260 }
261