fs - simple file server

Check-in [e81f9f06dd]
Login

Check-in [e81f9f06dd]

Overview
Comment:Use Crystal MIME library for determining content-type.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e81f9f06dd267da574dfea849ea11c2cba4e43cfe1a08b9e4b8e9111b0b74e7d
User & Date: marka on 2025-08-15 13:44:14.066
Other Links: manifest | tags
Context
2025-08-15
20:27
Add README. Leaf check-in: 7282daa3d4 user: marka tags: trunk
13:44
Use Crystal MIME library for determining content-type. check-in: e81f9f06dd user: marka tags: trunk
07:04
Serve index.html files correctly. check-in: 87b77ab4de user: marka tags: trunk
Changes
Modified src/fs.cr from [ff1867bb3f] to [9e83e4bd7a].
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15







+







# fs - Crystal implementation of a simple static file server

require "uri"
require "http"
require "option_parser"
require "yaml"
require "logger"
require "mime"

# Class for reading configuration information from fs.yml.

class Config
  # Required settings
  getter host : String # 127.0.0.1 for localhost, 0.0.0.0 for all hosts
  getter port : Int32
91
92
93
94
95
96
97



98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121







+
+
+












-
+







class Server
  def initialize(config : Config)
    @config = config
    @root = config.root
    @server = uninitialized HTTP::Server
  end

  # This gets called if HTTP::StaticFileHandler can't find a file.
  # The most common case is a directory path, in which case
  # we look for index.html in that directory.
  def process_request(context : HTTP::Server::Context)
    request = context.request
    request_path = request.path
    method = request.method

    MyLog.debug "process_request: got path #{request_path}, method #{method}"

    path = File.join(@root, request_path)
    if Dir.exists?(path)
      path = File.join(path, "index.html")
    end
    if File.exists?(path)
      content_type = `file -b --mime-type #{path}`.strip
      content_type = MIME.from_filename(path)
      context.response.content_type = content_type
      MyLog.info "Serving #{path}, content type #{content_type}"
      File.open(path) { |file| IO.copy(file, context.response) }
    else
      MyLog.error "No such file #{path}"
      context.response.respond_with_status(404, "No such file #{request_path}")
    end