package main import ( "log" "net/http" "os" "path" "strings" ) type submissionHandler func(w http.ResponseWriter, r *http.Request, sURL []string) type submissionChecker struct { kind string next submissionHandler } type submissionTeamHandler func(w http.ResponseWriter, r *http.Request, team string, sURL []string) type submissionTeamChecker struct { kind string next submissionTeamHandler teamsDir string simulator string } func (c submissionChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) { if addr := r.Header.Get("X-Forwarded-For"); addr != "" { r.RemoteAddr = addr } team := "-" if t := r.Header.Get("X-FIC-Team"); t != "" { team = t } log.Printf("%s %s \"%s %s\" => %s [%s]\n", r.RemoteAddr, team, r.Method, r.URL.Path, c.kind, r.UserAgent()) w.Header().Set("Content-Type", "application/json") // Check request type and size if r.Method != "POST" || r.ContentLength < 0 { http.Error(w, "{\"errmsg\":\"Requête invalide.\"}", http.StatusBadRequest) return } else if r.ContentLength > 4097 { http.Error(w, "{\"errmsg\":\"Requête trop longue\"}", http.StatusRequestEntityTooLarge) return } // Extract URL arguments var sURL = strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/") c.next(w, r, sURL) } func (c submissionTeamChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) { submissionChecker{c.kind, func(w http.ResponseWriter, r *http.Request, sURL []string) { team := c.simulator if t := r.Header.Get("X-FIC-Team"); t != "" { team = t } // Check team validity and existance if len(team) < 1 || team == "-" || team == "public" { log.Println("INVALID TEAM:", team) http.Error(w, "{\"errmsg\":\"Équipe inexistante.\"}", http.StatusBadRequest) return } else if _, err := os.Stat(path.Join(c.teamsDir, team)); os.IsNotExist(err) { log.Println("UNKNOWN TEAM:", team) http.Error(w, "{\"errmsg\":\"Équipe inexistante.\"}", http.StatusBadRequest) return } c.next(w, r, team, sURL) }}.ServeHTTP(w, r) }