response: Revert to using fields instead of methods
This commit is contained in:
parent
867074d81b
commit
1bc5c68c3f
2
doc.go
2
doc.go
@ -9,7 +9,7 @@ Client is a Gemini client.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
defer resp.Close()
|
defer resp.Body.Close()
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
Server is a Gemini server.
|
Server is a Gemini server.
|
||||||
|
@ -103,9 +103,9 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
|
|||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch resp.Status().Class() {
|
switch resp.Status.Class() {
|
||||||
case gemini.StatusInput:
|
case gemini.StatusInput:
|
||||||
input, ok := getInput(resp.Meta(), resp.Status() == gemini.StatusSensitiveInput)
|
input, ok := getInput(resp.Meta, resp.Status == gemini.StatusSensitiveInput)
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
|
|||||||
return resp, errors.New("too many redirects")
|
return resp, errors.New("too many redirects")
|
||||||
}
|
}
|
||||||
|
|
||||||
target, err := url.Parse(resp.Meta())
|
target, err := url.Parse(resp.Meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
@ -156,13 +156,13 @@ func main() {
|
|||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
|
||||||
// Handle response
|
// Handle response
|
||||||
if resp.Status().Class() == gemini.StatusSuccess {
|
if resp.Status.Class() == gemini.StatusSuccess {
|
||||||
_, err := io.Copy(os.Stdout, resp)
|
_, err := io.Copy(os.Stdout, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%d %s\n", resp.Status(), resp.Meta())
|
fmt.Printf("%d %s\n", resp.Status, resp.Meta)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
response.go
72
response.go
@ -15,24 +15,29 @@ const defaultMediaType = "text/gemini; charset=utf-8"
|
|||||||
//
|
//
|
||||||
// The Client returns Responses from servers once the response
|
// The Client returns Responses from servers once the response
|
||||||
// header has been received. The response body is streamed on demand
|
// header has been received. The response body is streamed on demand
|
||||||
// as the response is read. If the network connection fails or the server
|
// as the Body field is read.
|
||||||
// terminates the response, Read calls return an error.
|
|
||||||
//
|
|
||||||
// It is the caller's responsibility to close the response.
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
status Status
|
// Status is the response status code.
|
||||||
meta string
|
Status Status
|
||||||
body io.ReadCloser
|
|
||||||
conn net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewResponse returns a new response with the provided status, meta, and body.
|
// Meta returns the response meta.
|
||||||
func NewResponse(status Status, meta string, body io.ReadCloser) *Response {
|
// For successful responses, the meta should contain the media type of the response.
|
||||||
return &Response{
|
// For failure responses, the meta should contain a short description of the failure.
|
||||||
status: status,
|
Meta string
|
||||||
meta: meta,
|
|
||||||
body: body,
|
// Body represents the response body.
|
||||||
}
|
//
|
||||||
|
// The response body is streamed on demand as the Body field
|
||||||
|
// is read. If the network connection fails or the server
|
||||||
|
// terminates the response, Body.Read calls return an error.
|
||||||
|
//
|
||||||
|
// The Gemini client guarantees that Body is always
|
||||||
|
// non-nil, even on responses without a body or responses with
|
||||||
|
// a zero-length body. It is the caller's responsibility to
|
||||||
|
// close Body.
|
||||||
|
Body io.ReadCloser
|
||||||
|
|
||||||
|
conn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadResponse reads a Gemini response from the provided io.ReadCloser.
|
// ReadResponse reads a Gemini response from the provided io.ReadCloser.
|
||||||
@ -49,7 +54,7 @@ func ReadResponse(r io.ReadCloser) (*Response, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrInvalidResponse
|
return nil, ErrInvalidResponse
|
||||||
}
|
}
|
||||||
resp.status = Status(status)
|
resp.Status = Status(status)
|
||||||
|
|
||||||
// Read one space
|
// Read one space
|
||||||
if b, err := br.ReadByte(); err != nil {
|
if b, err := br.ReadByte(); err != nil {
|
||||||
@ -69,11 +74,11 @@ func ReadResponse(r io.ReadCloser) (*Response, error) {
|
|||||||
if len(meta) > 1024 {
|
if len(meta) > 1024 {
|
||||||
return nil, ErrInvalidResponse
|
return nil, ErrInvalidResponse
|
||||||
}
|
}
|
||||||
if resp.status.Class() == StatusSuccess && meta == "" {
|
if resp.Status.Class() == StatusSuccess && meta == "" {
|
||||||
// Use default media type
|
// Use default media type
|
||||||
meta = defaultMediaType
|
meta = defaultMediaType
|
||||||
}
|
}
|
||||||
resp.meta = meta
|
resp.Meta = meta
|
||||||
|
|
||||||
// Read terminating newline
|
// Read terminating newline
|
||||||
if b, err := br.ReadByte(); err != nil {
|
if b, err := br.ReadByte(); err != nil {
|
||||||
@ -82,38 +87,15 @@ func ReadResponse(r io.ReadCloser) (*Response, error) {
|
|||||||
return nil, ErrInvalidResponse
|
return nil, ErrInvalidResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.status.Class() == StatusSuccess {
|
if resp.Status.Class() == StatusSuccess {
|
||||||
resp.body = newBufReadCloser(br, r)
|
resp.Body = newBufReadCloser(br, r)
|
||||||
} else {
|
} else {
|
||||||
resp.body = nopReadCloser{}
|
resp.Body = nopReadCloser{}
|
||||||
r.Close()
|
r.Close()
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status returns the response status code.
|
|
||||||
func (r *Response) Status() Status {
|
|
||||||
return r.status
|
|
||||||
}
|
|
||||||
|
|
||||||
// Meta returns the response meta.
|
|
||||||
// For successful responses, the meta should contain the media type of the response.
|
|
||||||
// For failure responses, the meta should contain a short description of the failure.
|
|
||||||
func (r *Response) Meta() string {
|
|
||||||
return r.meta
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads data from the response body.
|
|
||||||
// The response body is streamed on demand as Read is called.
|
|
||||||
func (r *Response) Read(p []byte) (n int, err error) {
|
|
||||||
return r.body.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the response body.
|
|
||||||
func (r *Response) Close() error {
|
|
||||||
return r.body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conn returns the network connection on which the response was received.
|
// Conn returns the network connection on which the response was received.
|
||||||
func (r *Response) Conn() net.Conn {
|
func (r *Response) Conn() net.Conn {
|
||||||
return r.conn
|
return r.conn
|
||||||
|
@ -91,13 +91,13 @@ func TestReadWriteResponse(t *testing.T) {
|
|||||||
// No response
|
// No response
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if resp.status != test.Status {
|
if resp.Status != test.Status {
|
||||||
t.Errorf("expected status = %d, got %d", test.Status, resp.status)
|
t.Errorf("expected status = %d, got %d", test.Status, resp.Status)
|
||||||
}
|
}
|
||||||
if resp.meta != test.Meta {
|
if resp.Meta != test.Meta {
|
||||||
t.Errorf("expected meta = %s, got %s", test.Meta, resp.meta)
|
t.Errorf("expected meta = %s, got %s", test.Meta, resp.Meta)
|
||||||
}
|
}
|
||||||
b, _ := ioutil.ReadAll(resp.body)
|
b, _ := ioutil.ReadAll(resp.Body)
|
||||||
body := string(b)
|
body := string(b)
|
||||||
if body != test.Body {
|
if body != test.Body {
|
||||||
t.Errorf("expected body = %#v, got %#v", test.Body, body)
|
t.Errorf("expected body = %#v, got %#v", test.Body, body)
|
||||||
|
Loading…
Reference in New Issue
Block a user