@@ -24,40 +24,48 @@ import path = require("path");
2424
2525const { debug, warn } = createLoggers ( "binding-file" , "file-client" ) ;
2626
27+ /**
28+ * Used to determine the Content-Type of a file from the extension in its
29+ * {@link filePath} if no explicit Content-Type is defined.
30+ *
31+ * @param filepath The file path the Content-Type is determined for.
32+ * @returns An appropriate Content-Type or `application/octet-stream` as a fallback.
33+ */
34+ function mapFileExtensionToContentType ( filepath : string ) {
35+ const fileExtension = path . extname ( filepath ) ;
36+ debug ( `FileClient found '${ fileExtension } ' extension` ) ;
37+ switch ( fileExtension ) {
38+ case ".txt" :
39+ case ".log" :
40+ case ".ini" :
41+ case ".cfg" :
42+ return "text/plain" ;
43+ case ".json" :
44+ return "application/json" ;
45+ case ".jsontd" :
46+ return "application/td+json" ;
47+ case ".jsonld" :
48+ return "application/ld+json" ;
49+ default :
50+ warn ( `FileClient cannot determine media type for path '${ filepath } '` ) ;
51+ return "application/octet-stream" ;
52+ }
53+ }
54+
2755export default class FileClient implements ProtocolClient {
2856 public toString ( ) : string {
2957 return "[FileClient]" ;
3058 }
3159
60+ private async readFile ( filepath : string , contentType ?: string ) : Promise < Content > {
61+ const resource = fs . createReadStream ( filepath ) ;
62+ const resourceContentType = contentType ?? mapFileExtensionToContentType ( filepath ) ;
63+ return new Content ( resourceContentType , resource ) ;
64+ }
65+
3266 public async readResource ( form : Form ) : Promise < Content > {
33- const filepath = form . href . split ( "//" ) ;
34- const resource = fs . createReadStream ( filepath [ 1 ] ) ;
35- const extension = path . extname ( filepath [ 1 ] ) ;
36- debug ( `FileClient found '${ extension } ' extension` ) ;
37- let contentType ;
38- if ( form . contentType != null ) {
39- contentType = form . contentType ;
40- } else {
41- // *guess* contentType based on file extension
42- contentType = "application/octet-stream" ;
43- switch ( extension ) {
44- case ".txt" :
45- case ".log" :
46- case ".ini" :
47- case ".cfg" :
48- contentType = "text/plain" ;
49- break ;
50- case ".json" :
51- contentType = "application/json" ;
52- break ;
53- case ".jsonld" :
54- contentType = "application/ld+json" ;
55- break ;
56- default :
57- warn ( `FileClient cannot determine media type of '${ form . href } '` ) ;
58- }
59- }
60- return new Content ( contentType , resource ) ;
67+ const filepath = new URL ( form . href ) . pathname ;
68+ return this . readFile ( filepath , form . contentType ) ;
6169 }
6270
6371 public async writeResource ( form : Form , content : Content ) : Promise < void > {
@@ -72,6 +80,13 @@ export default class FileClient implements ProtocolClient {
7280 throw new Error ( "FileClient does not implement unlink" ) ;
7381 }
7482
83+ /**
84+ * @inheritdoc
85+ */
86+ public async requestThingDescription ( uri : string ) : Promise < Content > {
87+ return this . readFile ( uri , "application/td+json" ) ;
88+ }
89+
7590 public async subscribeResource (
7691 form : Form ,
7792 next : ( value : Content ) => void ,
0 commit comments