response: Implement Write method
This commit is contained in:
parent
a3a995df35
commit
aab3ac4dfe
19
response.go
19
response.go
@ -3,6 +3,7 @@ package gemini
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@ -135,6 +136,24 @@ func (b *readCloserBody) Read(p []byte) (n int, err error) {
|
|||||||
return b.ReadCloser.Read(p)
|
return b.ReadCloser.Read(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write writes r to w in the Gemini response format, including the
|
||||||
|
// header and body.
|
||||||
|
//
|
||||||
|
// This method consults the Status, Meta, and Body fields of the response.
|
||||||
|
// The Response Body is closed after it is sent.
|
||||||
|
func (r *Response) Write(w io.Writer) error {
|
||||||
|
if _, err := fmt.Fprintf(w, "%02d %s\r\n", r.Status, r.Meta); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if r.Body != nil {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if _, err := io.Copy(w, r.Body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// A ResponseWriter interface is used by a Gemini handler to construct
|
// A ResponseWriter interface is used by a Gemini handler to construct
|
||||||
// a Gemini response.
|
// a Gemini response.
|
||||||
//
|
//
|
||||||
|
@ -6,13 +6,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadResponse(t *testing.T) {
|
func TestReadWriteResponse(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Raw string
|
Raw string
|
||||||
Status int
|
Status int
|
||||||
Meta string
|
Meta string
|
||||||
Body string
|
Body string
|
||||||
Err error
|
Err error
|
||||||
|
SkipWrite bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Raw: "20 text/gemini\r\nHello, world!\nWelcome to my capsule.",
|
Raw: "20 text/gemini\r\nHello, world!\nWelcome to my capsule.",
|
||||||
@ -34,6 +35,7 @@ func TestReadResponse(t *testing.T) {
|
|||||||
Raw: "31 /redirect\r\nThis body is ignored.",
|
Raw: "31 /redirect\r\nThis body is ignored.",
|
||||||
Status: 31,
|
Status: 31,
|
||||||
Meta: "/redirect",
|
Meta: "/redirect",
|
||||||
|
SkipWrite: true, // skip write test since result won't match Raw
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Raw: "99 Unknown status code\r\n",
|
Raw: "99 Unknown status code\r\n",
|
||||||
@ -100,4 +102,26 @@ func TestReadResponse(t *testing.T) {
|
|||||||
t.Errorf("expected body = %#v, got %#v", test.Body, body)
|
t.Errorf("expected body = %#v, got %#v", test.Body, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
if test.Err != nil || test.SkipWrite {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resp := &Response{
|
||||||
|
Status: test.Status,
|
||||||
|
Meta: test.Meta,
|
||||||
|
Body: io.NopCloser(strings.NewReader(test.Body)),
|
||||||
|
}
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
if err := resp.Write(&b); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
got := b.String()
|
||||||
|
if got != test.Raw {
|
||||||
|
t.Errorf("expected %#v, got %#v", test.Raw, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user