Skip to content

Commit

Permalink
Merge pull request #31 from ninedraft/not-found-body
Browse files Browse the repository at this point in the history
  • Loading branch information
ninedraft committed Feb 12, 2022
2 parents 21a13ab + 4afd772 commit fa3b974
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
8 changes: 8 additions & 0 deletions gemax/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
"strings"
"sync"

"github.com/ninedraft/gemax/gemax/internal/bufwriter"
Expand Down Expand Up @@ -36,6 +37,7 @@ func (rw *responseWriter) WriteStatus(code status.Code, meta string) {
if code == status.Success && meta == "" {
meta = MIMEGemtext
}
meta = metaSanitizer.Replace(meta)
_, _ = fmt.Fprintf(rw.writer, "%d %s\r\n", code, meta)
rw.status = code
rw.statusWritten = true
Expand All @@ -44,6 +46,12 @@ func (rw *responseWriter) WriteStatus(code status.Code, meta string) {
}
}

var metaSanitizer = strings.NewReplacer(
"\r\n", "\t",
"\n", "\t",
"\r", "\t",
)

func (rw *responseWriter) Write(data []byte) (int, error) {
if rw.isClosed {
return 0, io.ErrNoProgress
Expand Down
61 changes: 56 additions & 5 deletions gemax/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,69 @@ func TestURLDotEscape(test *testing.T) {
expectResponse(test, resp, "50 50 PERMANENT FAILURE\r\n")
}

func setupEchoServer(t *testing.T) (*fakeListener, *gemax.Server) {
// emulates michael-lazar/gemini-diagnostics localhost 9999 --checks='PageNotFound'
func TestPageNotFound(test *testing.T) {
test.Run("helper", func(test *testing.T) {
var listener, server = setupServer(test,
func(_ context.Context, rw gemax.ResponseWriter, req gemax.IncomingRequest) {
gemax.NotFound(rw, req)
})
server.Hosts = []string{"example.com"}
defer func() { _ = listener.Close() }()
var ctx, cancel = context.WithCancel(context.Background())
test.Cleanup(cancel)
runTask(test, func() {
var err = server.Serve(ctx, listener)
if err != nil {
test.Logf("test server: Serve: %v", err)
}
})

var resp = listener.next(test.Name(), strings.NewReader("gemini://example.com/notexist\r\n"))

expectResponse(test, resp, "51 gemini://example.com/notexist is not found\r\n")
})

test.Run("custom", func(test *testing.T) {
test.Log("meta must not interfere with response body")
var listener, server = setupServer(test,
func(_ context.Context, rw gemax.ResponseWriter, req gemax.IncomingRequest) {
rw.WriteStatus(status.NotFound, "page is not found\r\ndotdot")
})
server.Hosts = []string{"example.com"}
defer func() { _ = listener.Close() }()
var ctx, cancel = context.WithCancel(context.Background())
test.Cleanup(cancel)
runTask(test, func() {
var err = server.Serve(ctx, listener)
if err != nil {
test.Logf("test server: Serve: %v", err)
}
})

var resp = listener.next(test.Name(), strings.NewReader("gemini://example.com/notexist\r\n"))

expectResponse(test, resp, "51 page is not found\tdotdot\r\n")
})
}

func setupServer(t *testing.T, handler gemax.Handler) (*fakeListener, *gemax.Server) {
t.Helper()
var server = &gemax.Server{
Logf: t.Logf,
Handler: func(ctx context.Context, rw gemax.ResponseWriter, req gemax.IncomingRequest) {
_, _ = rw.Write([]byte(req.URL().String()))
},
Logf: t.Logf,
Handler: handler,
}
var listener = newListener(t.Name())
return listener, server
}

func setupEchoServer(t *testing.T) (*fakeListener, *gemax.Server) {
t.Helper()
return setupServer(t, func(ctx context.Context, rw gemax.ResponseWriter, req gemax.IncomingRequest) {
_, _ = rw.Write([]byte(req.URL().String()))
})
}

func expectResponse(t *testing.T, got io.Reader, want string) {
t.Helper()
var data, err = io.ReadAll(got)
Expand Down
2 changes: 1 addition & 1 deletion gemax/server_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func Redirect(rw ResponseWriter, req IncomingRequest, target string, code status

// NotFound serves a not found error.
func NotFound(rw ResponseWriter, req IncomingRequest) {
rw.WriteStatus(status.NotFound, req.URL().String()+" is not found\r\n")
rw.WriteStatus(status.NotFound, req.URL().String()+" is not found")
}

// ServeContent creates a handler, which serves provided bytes as static page.
Expand Down

0 comments on commit fa3b974

Please sign in to comment.