@@ -16,6 +16,10 @@ use failure::err_msg;
16
16
use rusoto_s3:: { S3 , PutObjectRequest , GetObjectRequest , S3Client } ;
17
17
use rusoto_core:: region:: Region ;
18
18
use rusoto_credential:: DefaultCredentialsProvider ;
19
+ #[ cfg( not( windows) ) ]
20
+ use magic:: { Cookie , flags} ;
21
+ #[ cfg( not( windows) ) ]
22
+ use std:: ffi:: OsStr ;
19
23
20
24
21
25
const MAX_CONCURRENT_UPLOADS : usize = 1000 ;
@@ -155,12 +159,9 @@ pub fn add_path_into_database<P: AsRef<Path>>(conn: &Connection,
155
159
prefix : & str ,
156
160
path : P )
157
161
-> Result < Json > {
158
- use magic:: { Cookie , flags} ;
159
- let cookie = Cookie :: open ( flags:: MIME_TYPE ) ?;
160
- cookie. load :: < & str > ( & [ ] ) ?;
161
-
162
162
let trans = conn. transaction ( ) ?;
163
-
163
+ #[ cfg( not( windows) ) ]
164
+ let mime_data = load_mime_data ( ) ?;
164
165
use std:: collections:: HashMap ;
165
166
let mut file_paths_and_mimes: HashMap < PathBuf , String > = HashMap :: new ( ) ;
166
167
use futures:: future:: Future ;
@@ -195,25 +196,10 @@ pub fn add_path_into_database<P: AsRef<Path>>(conn: &Connection,
195
196
#[ cfg( not( windows) ) ]
196
197
let bucket_path = bucket_path. into_os_string ( ) . into_string ( ) . unwrap ( ) ;
197
198
198
- let mime = {
199
- let mime = cookie. buffer ( & content) ?;
200
- // css's are causing some problem in browsers
201
- // magic will return text/plain for css file types
202
- // convert them to text/css
203
- // do the same for javascript files
204
- if mime == "text/plain" {
205
- let e = file_path. extension ( ) . unwrap_or_default ( ) ;
206
- if e == "css" {
207
- "text/css" . to_owned ( )
208
- } else if e == "js" {
209
- "application/javascript" . to_owned ( )
210
- } else {
211
- mime. to_owned ( )
212
- }
213
- } else {
214
- mime. to_owned ( )
215
- }
216
- } ;
199
+ #[ cfg( windows) ]
200
+ let mime = detect_mime ( & content, & file_path) ?;
201
+ #[ cfg( not( windows) ) ]
202
+ let mime = detect_mime ( & content, & file_path, & mime_data) ?;
217
203
218
204
if let Some ( client) = & client {
219
205
futures. push ( client. put_object ( PutObjectRequest {
@@ -276,6 +262,51 @@ pub fn add_path_into_database<P: AsRef<Path>>(conn: &Connection,
276
262
file_list_to_json ( file_list_with_mimes)
277
263
}
278
264
265
+ #[ cfg( not( windows) ) ]
266
+ fn load_mime_data ( ) -> Result < Cookie > {
267
+ let cookie = Cookie :: open ( flags:: MIME_TYPE ) ?;
268
+ cookie. load :: < & str > ( & [ ] ) ?;
269
+ Ok ( cookie)
270
+ }
271
+
272
+ #[ cfg( not( windows) ) ]
273
+ fn detect_mime ( content : & Vec < u8 > , file_path : & Path , cookie : & Cookie ) -> Result < String > {
274
+ let mime = cookie. buffer ( & content) ?;
275
+
276
+ // magic is not specific enough sometimes
277
+ match mime. as_str ( ) {
278
+ "text/plain" => {
279
+ match file_path. extension ( ) . and_then ( OsStr :: to_str) {
280
+ Some ( "md" ) => Ok ( "text/markdown" . to_owned ( ) ) ,
281
+ Some ( "rs" ) => Ok ( "text/rust" . to_owned ( ) ) ,
282
+ Some ( "markdown" ) => Ok ( "text/markdown" . to_owned ( ) ) ,
283
+ Some ( "css" ) => Ok ( "text/css" . to_owned ( ) ) ,
284
+ Some ( "toml" ) => Ok ( "text/x-toml" . to_owned ( ) ) ,
285
+ Some ( "js" ) => Ok ( "application/javascript" . to_owned ( ) ) ,
286
+ Some ( "json" ) => Ok ( "application/json" . to_owned ( ) ) ,
287
+ _ => Ok ( mime. to_owned ( ) )
288
+ }
289
+ }
290
+ "text/troff" => {
291
+ match file_path. extension ( ) . and_then ( OsStr :: to_str) {
292
+ Some ( "css" ) => Ok ( "text/css" . to_owned ( ) ) ,
293
+ _ => Ok ( mime. to_owned ( ) )
294
+ }
295
+ }
296
+ _ => Ok ( mime. to_owned ( ) )
297
+ }
298
+ }
299
+
300
+ #[ cfg( windows) ]
301
+ fn detect_mime ( _content : & Vec < u8 > , file_path : & Path ) -> Result < String > {
302
+ let file_ext = file_path. extension ( ) . map ( |ext| ext. to_str ( ) ) . unwrap_or_default ( ) ;
303
+ Ok ( match file_ext {
304
+ Some ( "md" ) => "text/markdown" . to_owned ( ) ,
305
+ Some ( "rs" ) => "text/rust" . to_owned ( ) ,
306
+ None => "text/plain" . to_owned ( ) ,
307
+ _ => mime_guess:: from_path ( file_path) . first_raw ( ) . map ( |m| m. to_owned ( ) ) . unwrap_or ( "text/plain" . to_owned ( ) )
308
+ } )
309
+ }
279
310
280
311
281
312
fn file_list_to_json ( file_list : Vec < ( String , PathBuf ) > ) -> Result < Json > {
@@ -343,7 +374,7 @@ pub fn move_to_s3(conn: &Connection, n: usize) -> Result<usize> {
343
374
mod test {
344
375
extern crate env_logger;
345
376
use std:: env;
346
- use super :: get_file_list ;
377
+ use super :: * ;
347
378
348
379
#[ test]
349
380
fn test_get_file_list ( ) {
@@ -356,4 +387,29 @@ mod test {
356
387
let files = get_file_list ( env:: current_dir ( ) . unwrap ( ) . join ( "Cargo.toml" ) ) . unwrap ( ) ;
357
388
assert_eq ! ( files[ 0 ] , std:: path:: Path :: new( "Cargo.toml" ) ) ;
358
389
}
390
+ #[ test]
391
+ fn test_mime_types ( ) {
392
+ check_mime ( "/ignored" , ".gitignore" , "text/plain" ) ;
393
+ check_mime ( "[package]" , "hello.toml" , "text/x-toml" ) ;
394
+ check_mime ( ".ok { color:red; }" , "hello.css" , "text/css" ) ;
395
+ check_mime ( "var x = 1" , "hello.js" , "application/javascript" ) ;
396
+ check_mime ( "<html>" , "hello.html" , "text/html" ) ;
397
+ check_mime ( "## HELLO" , "hello.hello.md" , "text/markdown" ) ;
398
+ check_mime ( "## WORLD" , "hello.markdown" , "text/markdown" ) ;
399
+ check_mime ( "{}" , "hello.json" , "application/json" ) ;
400
+ check_mime ( "hello world" , "hello.txt" , "text/plain" ) ;
401
+ check_mime ( "//! Simple module to ..." , "file.rs" , "text/rust" ) ;
402
+ }
403
+
404
+ fn check_mime ( content : & str , path : & str , expected_mime : & str ) {
405
+ #[ cfg( not( windows) ) ]
406
+ let mime_data = load_mime_data ( ) . unwrap ( ) ;
407
+ #[ cfg( windows) ]
408
+ let detected_mime = detect_mime ( & content. as_bytes ( ) . to_vec ( ) , Path :: new ( & path) ) ;
409
+ #[ cfg( not( windows) ) ]
410
+ let detected_mime = detect_mime ( & content. as_bytes ( ) . to_vec ( ) , Path :: new ( & path) , & mime_data) ;
411
+ let detected_mime = detected_mime. expect ( "no mime was given" ) ;
412
+ assert_eq ! ( detected_mime, expected_mime) ;
413
+ }
359
414
}
415
+
0 commit comments