comparison main.go @ 2:d19133be91ba

ndex and smarter parser
author Atarwn Gard <a@qwa.su>
date Mon, 09 Mar 2026 01:55:11 +0500
parents 3e7247db5c6e
children eb705d4cdcd7
comparison
equal deleted inserted replaced
1:3e7247db5c6e 2:d19133be91ba
158 h.serve(w, r, dirs, caps) 158 h.serve(w, r, dirs, caps)
159 } 159 }
160 160
161 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) {
162 var ( 162 var (
163 rootDir string 163 rootDir string
164 rootIndex []string 164 rootShow bool
165 fcgiAddr string 165 ndex []string
166 fcgiPat string 166 fcgiAddr string
167 rprxAddr string 167 fcgiPat string
168 rprxAddr string
169 rdirCode int
170 rdirURL string
168 ) 171 )
169 172
170 for _, d := range dirs { 173 for _, d := range dirs {
171 switch d.Key { 174 switch d.Key {
172 case "root": 175 case "root":
173 rootDir = safeArg(d.Args, 0) 176 rootDir = safeArg(d.Args, 0)
174 switch safeArg(d.Args, 1) { 177 rootShow = safeArg(d.Args, 1) == "show"
175 case "show": 178 case "ndex":
176 if len(d.Args) >= 3 { 179 ndex = d.Args
177 rootIndex = d.Args[2:]
178 } else {
179 rootIndex = []string{"index.html"}
180 }
181 case "hide", "":
182 rootIndex = nil
183 default:
184 log.Printf("d2o: root: unknown mode %q (want show|hide)", safeArg(d.Args, 1))
185 }
186 case "fcgi": 180 case "fcgi":
187 fcgiAddr = safeArg(d.Args, 0) 181 fcgiAddr = safeArg(d.Args, 0)
188 fcgiPat = safeArg(d.Args, 1) 182 fcgiPat = safeArg(d.Args, 1)
189 if fcgiPat == "" { 183 if fcgiPat == "" {
190 fcgiPat = "*" 184 fcgiPat = "*"
191 } 185 }
192 case "rprx": 186 case "rprx":
193 rprxAddr = safeArg(d.Args, 0) 187 rprxAddr = safeArg(d.Args, 0)
194 } 188 case "rdir":
195 } 189 rdirCode, _ = strconv.Atoi(safeArg(d.Args, 0))
196 190 rdirURL = safeArg(d.Args, 1)
191 }
192 }
193
194 if rdirURL != "" {
195 if rdirCode == 0 {
196 rdirCode = http.StatusFound
197 }
198 http.Redirect(w, r, rdirURL, rdirCode)
199 return
200 }
197 if rprxAddr != "" { 201 if rprxAddr != "" {
198 serveReverseProxy(w, r, rprxAddr) 202 serveReverseProxy(w, r, rprxAddr)
199 return 203 return
200 } 204 }
201 if fcgiAddr != "" && matchGlob(fcgiPat, r.URL.Path) { 205 if fcgiAddr != "" && matchGlob(fcgiPat, r.URL.Path) {
204 http.Error(w, "gateway error", http.StatusBadGateway) 208 http.Error(w, "gateway error", http.StatusBadGateway)
205 } 209 }
206 return 210 return
207 } 211 }
208 if rootDir != "" { 212 if rootDir != "" {
209 serveStatic(w, r, rootDir, rootIndex) 213 serveStatic(w, r, rootDir, rootShow, ndex)
210 return 214 return
211 } 215 }
212 216
213 http.Error(w, "not found", http.StatusNotFound) 217 http.Error(w, "not found", http.StatusNotFound)
214 } 218 }
215 219
216 // --- Static ----------------------------------------------------------------- 220 // --- Static -----------------------------------------------------------------
217 221 func serveStatic(w http.ResponseWriter, r *http.Request, rootDir string, show bool, ndex []string) {
218 func serveStatic(w http.ResponseWriter, r *http.Request, rootDir string, rootIndex []string) {
219 fpath := filepath.Join(rootDir, filepath.FromSlash(path.Clean(r.URL.Path))) 222 fpath := filepath.Join(rootDir, filepath.FromSlash(path.Clean(r.URL.Path)))
220 223
221 info, err := os.Stat(fpath) 224 info, err := os.Stat(fpath)
222 if os.IsNotExist(err) { 225 if os.IsNotExist(err) {
223 http.Error(w, "not found", http.StatusNotFound) 226 http.Error(w, "not found", http.StatusNotFound)
227 http.Error(w, "internal error", http.StatusInternalServerError) 230 http.Error(w, "internal error", http.StatusInternalServerError)
228 return 231 return
229 } 232 }
230 233
231 if info.IsDir() { 234 if info.IsDir() {
232 if rootIndex == nil { 235 for _, idx := range ndex {
233 http.Error(w, "forbidden", http.StatusForbidden)
234 return
235 }
236 for _, idx := range rootIndex {
237 idxPath := filepath.Join(fpath, idx) 236 idxPath := filepath.Join(fpath, idx)
238 if _, err := os.Stat(idxPath); err == nil { 237 if _, err := os.Stat(idxPath); err == nil {
239 http.ServeFile(w, r, idxPath) 238 http.ServeFile(w, r, idxPath)
240 return 239 return
241 } 240 }
241 }
242 if !show {
243 http.Error(w, "forbidden", http.StatusForbidden)
244 return
242 } 245 }
243 listDir(w, r, fpath, r.URL.Path) 246 listDir(w, r, fpath, r.URL.Path)
244 return 247 return
245 } 248 }
246 249