package server import ( "net/http" "os" "os/signal" "path" "strings" "syscall" ) type Server struct { addr string } func New(addr string) (*Server, error) { return &Server{ addr: addr, }, nil } func (s *Server) Serve() error { var err error go func() { port := s.addr if !strings.HasPrefix(port, ":") { port = ":" + port } err = http.ListenAndServe(port, s) }() sigc := make(chan os.Signal) signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, ) <-sigc return err } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch advance(r) { case "api": s.api(w, r) default: s.bad(w, r) } } func (s *Server) bad(w http.ResponseWriter, r *http.Request) { http.NotFound(w, r) } func (s *Server) api(w http.ResponseWriter, r *http.Request) { switch advance(r) { case "feed": s.feed(w, r) default: s.bad(w, r) } } func (s *Server) feed(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": case "POST": case "PUT": default: s.bad(w, r) } } func advance(r *http.Request) string { p := path.Clean("/" + r.URL.Path) i := strings.Index(p[1:], "/") + 1 if i <= 0 { r.URL.Path = "/" return p[1:] } r.URL.Path = p[i:] return p[1:i] }