aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2021-02-23 20:49:42 -0500
committerAdnan Maolood <[email protected]>2021-02-23 20:49:55 -0500
commite8d98ef4ec9dd9b6fd4f0a67c4ef531485354bee (patch)
tree0d4afa0e2df65848ecb5f7652928d107db716dec
parentMake ResponseWriter a struct (diff)
downloadgo-gemini-e8d98ef4ec9dd9b6fd4f0a67c4ef531485354bee.tar.xz
go-gemini-e8d98ef4ec9dd9b6fd4f0a67c4ef531485354bee.zip
Move I/O utilities to io.go
-rw-r--r--client.go53
-rw-r--r--io.go104
-rw-r--r--response.go39
-rw-r--r--response_test.go12
4 files changed, 105 insertions, 103 deletions
diff --git a/client.go b/client.go
index 5d7e4f5..2020e3d 100644
--- a/client.go
+++ b/client.go
@@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"crypto/x509"
- "io"
"net"
"net/url"
"time"
@@ -221,55 +220,3 @@ func punycodeHostname(hostname string) (string, error) {
}
return idna.Lookup.ToASCII(hostname)
}
-
-type contextReader struct {
- ctx context.Context
- done <-chan struct{}
- cancel func()
- rc io.ReadCloser
-}
-
-func (r *contextReader) Read(p []byte) (int, error) {
- select {
- case <-r.done:
- r.rc.Close()
- return 0, r.ctx.Err()
- default:
- }
- n, err := r.rc.Read(p)
- if err != nil {
- r.cancel()
- }
- return n, err
-}
-
-func (r *contextReader) Close() error {
- r.cancel()
- return r.rc.Close()
-}
-
-type contextWriter struct {
- ctx context.Context
- done <-chan struct{}
- cancel func()
- wc io.WriteCloser
-}
-
-func (w *contextWriter) Write(b []byte) (int, error) {
- select {
- case <-w.done:
- w.wc.Close()
- return 0, w.ctx.Err()
- default:
- }
- n, err := w.wc.Write(b)
- if err != nil {
- w.cancel()
- }
- return n, err
-}
-
-func (w *contextWriter) Close() error {
- w.cancel()
- return w.wc.Close()
-}
diff --git a/io.go b/io.go
new file mode 100644
index 0000000..3b9e540
--- /dev/null
+++ b/io.go
@@ -0,0 +1,104 @@
+package gemini
+
+import (
+ "bufio"
+ "context"
+ "io"
+)
+
+type contextReader struct {
+ ctx context.Context
+ done <-chan struct{}
+ cancel func()
+ rc io.ReadCloser
+}
+
+func (r *contextReader) Read(p []byte) (int, error) {
+ select {
+ case <-r.done:
+ r.rc.Close()
+ return 0, r.ctx.Err()
+ default:
+ }
+ n, err := r.rc.Read(p)
+ if err != nil {
+ r.cancel()
+ }
+ return n, err
+}
+
+func (r *contextReader) Close() error {
+ r.cancel()
+ return r.rc.Close()
+}
+
+type contextWriter struct {
+ ctx context.Context
+ done <-chan struct{}
+ cancel func()
+ wc io.WriteCloser
+}
+
+func (w *contextWriter) Write(b []byte) (int, error) {
+ select {
+ case <-w.done:
+ w.wc.Close()
+ return 0, w.ctx.Err()
+ default:
+ }
+ n, err := w.wc.Write(b)
+ if err != nil {
+ w.cancel()
+ }
+ return n, err
+}
+
+func (w *contextWriter) Close() error {
+ w.cancel()
+ return w.wc.Close()
+}
+
+type nopCloser struct {
+ io.Writer
+}
+
+func (nopCloser) Close() error {
+ return nil
+}
+
+type nopReadCloser struct{}
+
+func (nopReadCloser) Read(p []byte) (int, error) {
+ return 0, io.EOF
+}
+
+func (nopReadCloser) Close() error {
+ return nil
+}
+
+type bufReadCloser struct {
+ br *bufio.Reader // used until empty
+ io.ReadCloser
+}
+
+func newBufReadCloser(br *bufio.Reader, rc io.ReadCloser) io.ReadCloser {
+ body := &bufReadCloser{ReadCloser: rc}
+ if br.Buffered() != 0 {
+ body.br = br
+ }
+ return body
+}
+
+func (b *bufReadCloser) Read(p []byte) (n int, err error) {
+ if b.br != nil {
+ if n := b.br.Buffered(); len(p) > n {
+ p = p[:n]
+ }
+ n, err = b.br.Read(p)
+ if b.br.Buffered() == 0 {
+ b.br = nil
+ }
+ return n, err
+ }
+ return b.ReadCloser.Read(p)
+}
diff --git a/response.go b/response.go
index 8c7febc..abbc757 100644
--- a/response.go
+++ b/response.go
@@ -81,7 +81,7 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
}
if resp.Status.Class() == StatusSuccess {
- resp.body = newReadCloserBody(br, rc)
+ resp.body = newBufReadCloser(br, rc)
} else {
resp.body = nopReadCloser{}
rc.Close()
@@ -89,43 +89,6 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
return resp, nil
}
-type nopReadCloser struct{}
-
-func (nopReadCloser) Read(p []byte) (int, error) {
- return 0, io.EOF
-}
-
-func (nopReadCloser) Close() error {
- return nil
-}
-
-type readCloserBody struct {
- br *bufio.Reader // used until empty
- io.ReadCloser
-}
-
-func newReadCloserBody(br *bufio.Reader, rc io.ReadCloser) io.ReadCloser {
- body := &readCloserBody{ReadCloser: rc}
- if br.Buffered() != 0 {
- body.br = br
- }
- return body
-}
-
-func (b *readCloserBody) Read(p []byte) (n int, err error) {
- if b.br != nil {
- if n := b.br.Buffered(); len(p) > n {
- p = p[:n]
- }
- n, err = b.br.Read(p)
- if b.br.Buffered() == 0 {
- b.br = nil
- }
- return n, err
- }
- return b.ReadCloser.Read(p)
-}
-
// 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) {
diff --git a/response_test.go b/response_test.go
index 68e0884..2920d64 100644
--- a/response_test.go
+++ b/response_test.go
@@ -123,15 +123,3 @@ func TestReadWriteResponse(t *testing.T) {
}
}
}
-
-type nopCloser struct {
- io.Writer
-}
-
-func (w nopCloser) Write(b []byte) (int, error) {
- return w.Writer.Write(b)
-}
-
-func (nopCloser) Close() error {
- return nil
-}