fix some bugs and make middleware work

This commit is contained in:
dre 2021-07-08 09:34:32 +08:00
parent 1a755192fb
commit 5541785463
2 changed files with 47 additions and 18 deletions

View file

@ -52,8 +52,13 @@ var (
) )
type Request struct { type Request struct {
ctx context.Context ctx context.Context
URL *url.URL URL *url.URL
RemoteAddr string
// RequestURI is the unmodified request-target of the Request-Line as sent by the client
// to a server. Usually the URL field should be used instead.
RequestURI string
} }
type Handler interface { type Handler interface {
@ -135,7 +140,12 @@ func (s *Server) handleConnection(conn net.Conn, sem chan struct{}) {
return return
} }
ctx := context.Background() ctx := context.Background()
r := &Request{ctx: ctx, URL: header.URL} r := &Request{
ctx: ctx,
URL: header.URL,
RequestURI: header.rawuri,
RemoteAddr: conn.RemoteAddr().String(),
}
s.Handler.ServeGemini(conn, r) s.Handler.ServeGemini(conn, r)
case <-time.After(s.ReadTimeout): case <-time.After(s.ReadTimeout):
WriteHeader(conn, StatusServerUnavailable, "") WriteHeader(conn, StatusServerUnavailable, "")
@ -157,48 +167,54 @@ func (s *Server) handleRequestError(conn net.Conn, req request) {
// conn handler // conn handler
type request struct { type request struct {
URL *url.URL rawuri string
err error URL *url.URL
err error
} }
func requestChannel(c net.Conn, rsp chan request) { func requestChannel(c net.Conn, rsp chan request) {
u, err := readHeader(c) r, err := readHeader(c)
rsp <- request{u, err} r.err = err
rsp <- *r
} }
func readHeader(c net.Conn) (*url.URL, error) { func readHeader(c net.Conn) (*request, error) {
r := &request{}
req, err := bufio.NewReader(c).ReadString('\r') req, err := bufio.NewReader(c).ReadString('\r')
if err != nil { if err != nil {
return nil, Error(StatusTemporaryFailure, errors.New("error reading request")) return nil, Error(StatusTemporaryFailure, errors.New("error reading request"))
} }
r.rawuri = req
requestURL := strings.TrimSpace(req) requestURL := strings.TrimSpace(req)
if requestURL == "" { if requestURL == "" {
return nil, Error(StatusBadRequest, errors.New("empty request URL")) return r, Error(StatusBadRequest, errors.New("empty request URL"))
} else if !utf8.ValidString(requestURL) { } else if !utf8.ValidString(requestURL) {
return nil, Error(StatusBadRequest, errors.New("not a valid utf-8 url")) return r, Error(StatusBadRequest, errors.New("not a valid utf-8 url"))
} else if len(requestURL) > URLMaxBytes { } else if len(requestURL) > URLMaxBytes {
return nil, Error(StatusBadRequest, ErrHeaderTooLong) return r, Error(StatusBadRequest, ErrHeaderTooLong)
} }
parsedURL, err := url.Parse(requestURL) parsedURL, err := url.Parse(requestURL)
if err != nil { if err != nil {
return nil, Error(StatusBadRequest, err) return r, Error(StatusBadRequest, err)
} }
r.URL = parsedURL
if parsedURL.Scheme != "" && parsedURL.Scheme != "gemini" { if parsedURL.Scheme != "" && parsedURL.Scheme != "gemini" {
return nil, Error(StatusProxyRequestRefused, fmt.Errorf("unknown protocol scheme %s", parsedURL.Scheme)) return r, Error(StatusProxyRequestRefused, fmt.Errorf("unknown protocol scheme %s", parsedURL.Scheme))
} else if parsedURL.Host == "" { } else if parsedURL.Host == "" {
return nil, Error(StatusBadRequest, errors.New("empty host")) return r, Error(StatusBadRequest, errors.New("empty host"))
} }
if parsedURL.Path == "" { if parsedURL.Path == "" {
return nil, Error(StatusRedirectPermanent, errors.New("./"+parsedURL.Path)) return r, Error(StatusRedirectPermanent, errors.New("./"+parsedURL.Path))
} else if parsedURL.Path != path.Clean(parsedURL.Path) { } else if parsedURL.Path != path.Clean(parsedURL.Path) {
return nil, Error(StatusBadRequest, errors.New("path error")) return r, Error(StatusBadRequest, errors.New("path error"))
} }
return parsedURL, nil return r, nil
} }
func (s *Server) Shutdown(ctx context.Context) error { func (s *Server) Shutdown(ctx context.Context) error {

15
main.go
View file

@ -11,6 +11,7 @@ import (
"mime" "mime"
"os" "os"
"path" "path"
"strings"
"time" "time"
"github.com/n0x1m/gmifs/gemini" "github.com/n0x1m/gmifs/gemini"
@ -112,7 +113,19 @@ func main() {
func logger(next gemini.Handler) gemini.Handler { func logger(next gemini.Handler) gemini.Handler {
fn := func(w io.Writer, r *gemini.Request) { fn := func(w io.Writer, r *gemini.Request) {
log.Println(r.URL) t := time.Now()
next.ServeGemini(w, r)
ip := strings.Split(r.RemoteAddr, ":")[0]
hostname, _ := os.Hostname()
fmt.Printf("%s %s - - [%s] \"%s\" - %v\n",
hostname,
ip,
t.Format("02/Jan/2006:15:04:05 -0700"),
r.URL.Path,
time.Since(t),
)
} }
return gemini.HandlerFunc(fn) return gemini.HandlerFunc(fn)
} }