comparison main.go @ 1:3e7247db5c6e

show index.html
author Atarwn Gard <a@qwa.su>
date Mon, 09 Mar 2026 01:04:16 +0500
parents 48bdab3eec8a
children d19133be91ba
comparison
equal deleted inserted replaced
0:48bdab3eec8a 1:3e7247db5c6e
34 f.Close() 34 f.Close()
35 if err != nil { 35 if err != nil {
36 log.Fatalf("d2o: config error: %v", err) 36 log.Fatalf("d2o: config error: %v", err)
37 } 37 }
38 38
39 // Apply @d2o global settings
40 for _, d := range cfg.Abstract("d2o") { 39 for _, d := range cfg.Abstract("d2o") {
41 switch d.Key { 40 switch d.Key {
42 case "threads": 41 case "threads":
43 n, err := strconv.Atoi(safeArg(d.Args, 0)) 42 n, err := strconv.Atoi(safeArg(d.Args, 0))
44 if err == nil && n > 0 { 43 if err == nil && n > 0 {
92 } 91 }
93 log.Printf("d2o: listening on %s (https)", pc.addr) 92 log.Printf("d2o: listening on %s (https)", pc.addr)
94 return http.Serve(ln, h) 93 return http.Serve(ln, h)
95 } 94 }
96 95
97 // collectPorts scans all blocks for port / port+tls directives.
98 func collectPorts(cfg *icf.Config) []portConfig { 96 func collectPorts(cfg *icf.Config) []portConfig {
99 seen := make(map[string]bool) 97 seen := make(map[string]bool)
100 var out []portConfig 98 var out []portConfig
101 99
102 for _, b := range cfg.Blocks { 100 for _, b := range cfg.Blocks {
103 dirs := cfg.ResolveBlock(b, nil) 101 dirs := cfg.ResolveBlock(b, nil)
104 102
105 // Collect tls paths defined in this block
106 var cert, key string 103 var cert, key string
107 for _, d := range dirs { 104 for _, d := range dirs {
108 if d.Key == "tls" { 105 if d.Key == "tls" {
109 cert = safeArg(d.Args, 0) 106 cert = safeArg(d.Args, 0)
110 key = safeArg(d.Args, 1) 107 key = safeArg(d.Args, 1)
147 144
148 func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 145 func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
149 host := stripPort(r.Host) 146 host := stripPort(r.Host)
150 reqPath := path.Clean(r.URL.Path) 147 reqPath := path.Clean(r.URL.Path)
151 148
152 // Try host+path first, then host alone
153 dirs, caps := h.cfg.Match(host + reqPath) 149 dirs, caps := h.cfg.Match(host + reqPath)
154 if dirs == nil { 150 if dirs == nil {
155 dirs, caps = h.cfg.Match(host) 151 dirs, caps = h.cfg.Match(host)
156 } 152 }
157 if dirs == nil { 153 if dirs == nil {
162 h.serve(w, r, dirs, caps) 158 h.serve(w, r, dirs, caps)
163 } 159 }
164 160
165 func (h *handler) serve(w http.ResponseWriter, r *http.Request, dirs []icf.Directive, _ map[string]string) { 161 func (h *handler) serve(w http.ResponseWriter, r *http.Request, dirs []icf.Directive, _ map[string]string) {
166 var ( 162 var (
167 rootDir string 163 rootDir string
168 rootShow bool 164 rootIndex []string
169 fcgiAddr string 165 fcgiAddr string
170 fcgiPat string 166 fcgiPat string
171 rprxAddr string 167 rprxAddr string
172 ) 168 )
173 169
174 for _, d := range dirs { 170 for _, d := range dirs {
175 switch d.Key { 171 switch d.Key {
176 case "root": 172 case "root":
177 rootDir = safeArg(d.Args, 0) 173 rootDir = safeArg(d.Args, 0)
178 switch safeArg(d.Args, 1) { 174 switch safeArg(d.Args, 1) {
179 case "show": 175 case "show":
180 rootShow = true 176 if len(d.Args) >= 3 {
177 rootIndex = d.Args[2:]
178 } else {
179 rootIndex = []string{"index.html"}
180 }
181 case "hide", "": 181 case "hide", "":
182 rootShow = false 182 rootIndex = nil
183 default: 183 default:
184 log.Printf("d2o: root: unknown mode %q (want show|hide)", safeArg(d.Args, 1)) 184 log.Printf("d2o: root: unknown mode %q (want show|hide)", safeArg(d.Args, 1))
185 } 185 }
186 case "fcgi": 186 case "fcgi":
187 fcgiAddr = safeArg(d.Args, 0) 187 fcgiAddr = safeArg(d.Args, 0)
192 case "rprx": 192 case "rprx":
193 rprxAddr = safeArg(d.Args, 0) 193 rprxAddr = safeArg(d.Args, 0)
194 } 194 }
195 } 195 }
196 196
197 // Priority: rprx > fcgi > static root
198 if rprxAddr != "" { 197 if rprxAddr != "" {
199 serveReverseProxy(w, r, rprxAddr) 198 serveReverseProxy(w, r, rprxAddr)
200 return 199 return
201 } 200 }
202 if fcgiAddr != "" && matchGlob(fcgiPat, r.URL.Path) { 201 if fcgiAddr != "" && matchGlob(fcgiPat, r.URL.Path) {
205 http.Error(w, "gateway error", http.StatusBadGateway) 204 http.Error(w, "gateway error", http.StatusBadGateway)
206 } 205 }
207 return 206 return
208 } 207 }
209 if rootDir != "" { 208 if rootDir != "" {
210 serveStatic(w, r, rootDir, rootShow) 209 serveStatic(w, r, rootDir, rootIndex)
211 return 210 return
212 } 211 }
213 212
214 http.Error(w, "not found", http.StatusNotFound) 213 http.Error(w, "not found", http.StatusNotFound)
215 } 214 }
216 215
217 // --- Static ----------------------------------------------------------------- 216 // --- Static -----------------------------------------------------------------
218 217
219 func serveStatic(w http.ResponseWriter, r *http.Request, rootDir string, showDir bool) { 218 func serveStatic(w http.ResponseWriter, r *http.Request, rootDir string, rootIndex []string) {
220 fpath := filepath.Join(rootDir, filepath.FromSlash(path.Clean(r.URL.Path))) 219 fpath := filepath.Join(rootDir, filepath.FromSlash(path.Clean(r.URL.Path)))
221 220
222 info, err := os.Stat(fpath) 221 info, err := os.Stat(fpath)
223 if os.IsNotExist(err) { 222 if os.IsNotExist(err) {
224 http.Error(w, "not found", http.StatusNotFound) 223 http.Error(w, "not found", http.StatusNotFound)
226 } 225 }
227 if err != nil { 226 if err != nil {
228 http.Error(w, "internal error", http.StatusInternalServerError) 227 http.Error(w, "internal error", http.StatusInternalServerError)
229 return 228 return
230 } 229 }
230
231 if info.IsDir() { 231 if info.IsDir() {
232 if !showDir { 232 if rootIndex == nil {
233 http.Error(w, "forbidden", http.StatusForbidden) 233 http.Error(w, "forbidden", http.StatusForbidden)
234 return 234 return
235 } 235 }
236 for _, idx := range rootIndex {
237 idxPath := filepath.Join(fpath, idx)
238 if _, err := os.Stat(idxPath); err == nil {
239 http.ServeFile(w, r, idxPath)
240 return
241 }
242 }
236 listDir(w, r, fpath, r.URL.Path) 243 listDir(w, r, fpath, r.URL.Path)
237 return 244 return
238 } 245 }
246
239 http.ServeFile(w, r, fpath) 247 http.ServeFile(w, r, fpath)
240 } 248 }
241 249
242 func listDir(w http.ResponseWriter, r *http.Request, dir, urlPath string) { 250 func listDir(w http.ResponseWriter, r *http.Request, dir, urlPath string) {
243 entries, err := os.ReadDir(dir) 251 entries, err := os.ReadDir(dir)