Skip to content

Commit

Permalink
feat(core): raw responses
Browse files Browse the repository at this point in the history
  • Loading branch information
ConsoleTVs committed Jan 13, 2025
1 parent 04359c3 commit 2e83c47
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
22 changes: 22 additions & 0 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
)
Expand Down Expand Up @@ -91,6 +92,12 @@ type Builder struct {
writer func(writer http.ResponseWriter)
}

// RawBuilder is a raw response that can be used
// to return a raw [http.Builder] from a [Handler].
type RawBuilder struct {
http.Handler
}

var (
// ErrWriterRequiresFlusher is an error that determines that
// the given response writer needs a flusher in order to push
Expand All @@ -99,6 +106,12 @@ var (
ErrWriterRequiresFlusher = errors.New("response writer requires a flusher")
)

// Error implements the error interface
// for the Raw builder.
func (raw RawBuilder) Error() string {
return fmt.Sprintf("%v", raw.Handler)
}

// writeHeaders writes the given response headers by calling
// [http.ResponseWriter]'s `WriteHeader` method.
//
Expand Down Expand Up @@ -231,6 +244,15 @@ func DefaultResponderHandler(writer http.ResponseWriter, request *http.Request,
}
}

// Raw is a used to create a [RawBuilder] response
// that can be used to return a [http.Handler] directly
// on [Handler] functions.
func Raw(handler http.Handler) RawBuilder {
return RawBuilder{
Handler: handler,
}
}

// Response is used to create a builder with the given
// HTTP status.
//
Expand Down
11 changes: 11 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func handle(writer http.ResponseWriter, request *http.Request, err error, parent
return
}

if raw, ok := err.(RawResponder); ok {
raw.ServeHTTP(writer, request)
return
}

if responder, ok := err.(Responder); ok {
handleResponder(writer, request, parent, responder)
return
Expand All @@ -67,6 +72,12 @@ func handle(writer http.ResponseWriter, request *http.Request, err error, parent
Handle(writer, request)
}

func RawHandler(handler http.Handler) Handler {
return func(*http.Request) error {
return Raw(handler)
}
}

// ServeHTTP implements the [http.Handler] interface to have
// compatibility with the http package.
func (handler Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
Expand Down
46 changes: 46 additions & 0 deletions handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package akumu_test

import (
"net/http"
"testing"

"github.com/studiolambda/akumu"
)

func exampleRawResponse(request *http.Request) error {
return akumu.Raw(
http.RedirectHandler("foo", http.StatusTemporaryRedirect),
)
}

func TestRawHandler(t *testing.T) {
handler := akumu.RawHandler(http.RedirectHandler("foo", http.StatusTemporaryRedirect))

request, err := http.NewRequest(http.MethodGet, "/", nil)

if err != nil {
t.Fatal("failed to create http request")
}

response := handler.Record(request)

if expected := http.StatusTemporaryRedirect; response.Code != expected {
t.Fatalf("expected status code %d but got %d", expected, response.Code)
}
}

func TestRawResponse(t *testing.T) {
handler := akumu.Handler(exampleRawResponse)

request, err := http.NewRequest(http.MethodGet, "/", nil)

if err != nil {
t.Fatal("failed to create http request")
}

response := handler.Record(request)

if expected := http.StatusTemporaryRedirect; response.Code != expected {
t.Fatalf("expected status code %d but got %d", expected, response.Code)
}
}
6 changes: 6 additions & 0 deletions responder.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ import "net/http"
type Responder interface {
Respond(request *http.Request) Builder
}

// RawBuilder is a raw response that can be used
// to return a raw [http.Builder] from a [Handler].
type RawResponder interface {
http.Handler
}

0 comments on commit 2e83c47

Please sign in to comment.