@@ -5,16 +5,53 @@ import (
55 "net/http"
66 "net/url"
77
8+ "slices"
9+
810 "github.com/storacha/go-ucanto/transport"
911)
1012
13+ // Option is an option configuring a HTTP channel.
14+ type Option func (cfg * chanConfig )
15+
16+ type chanConfig struct {
17+ client * http.Client
18+ method string
19+ statuses []int
20+ }
21+
22+ // WithClient configures the HTTP client the channel should use to make
23+ // requests.
24+ func WithClient (c * http.Client ) Option {
25+ return func (cfg * chanConfig ) {
26+ cfg .client = c
27+ }
28+ }
29+
30+ // WithMethod configures the HTTP method the channel should use when making
31+ // requests.
32+ func WithMethod (method string ) Option {
33+ return func (cfg * chanConfig ) {
34+ cfg .method = method
35+ }
36+ }
37+
38+ // WithSuccessStatusCode configures the HTTP status code(s) that will indicate a
39+ // successful request.
40+ func WithSuccessStatusCode (codes ... int ) Option {
41+ return func (cfg * chanConfig ) {
42+ cfg .statuses = codes
43+ }
44+ }
45+
1146type channel struct {
12- url * url.URL
13- client * http.Client
47+ url * url.URL
48+ client * http.Client
49+ method string
50+ statuses []int
1451}
1552
1653func (c * channel ) Request (req transport.HTTPRequest ) (transport.HTTPResponse , error ) {
17- hr , err := http .NewRequest ("POST" , c .url .String (), req .Body ())
54+ hr , err := http .NewRequest (c . method , c .url .String (), req .Body ())
1855 if err != nil {
1956 return nil , fmt .Errorf ("creating HTTP request: %s" , err )
2057 }
@@ -24,13 +61,31 @@ func (c *channel) Request(req transport.HTTPRequest) (transport.HTTPResponse, er
2461 if err != nil {
2562 return nil , fmt .Errorf ("doing HTTP request: %s" , err )
2663 }
27- if res . StatusCode != http . StatusOK {
64+ if ! slices . Contains ( c . statuses , res . StatusCode ) {
2865 return nil , NewHTTPError (fmt .Sprintf ("HTTP Request failed. %s %s → %d" , hr .Method , c .url .String (), res .StatusCode ), res .StatusCode , res .Header )
2966 }
3067
3168 return NewHTTPResponse (res .StatusCode , res .Body , res .Header ), nil
3269}
3370
34- func NewHTTPChannel (url * url.URL ) transport.Channel {
35- return & channel {url : url , client : & http.Client {}}
71+ func NewHTTPChannel (url * url.URL , options ... Option ) transport.Channel {
72+ cfg := chanConfig {}
73+ for _ , opt := range options {
74+ opt (& cfg )
75+ }
76+ if cfg .client == nil {
77+ cfg .client = & http.Client {}
78+ }
79+ if cfg .method == "" {
80+ cfg .method = "POST"
81+ }
82+ if len (cfg .statuses ) == 0 {
83+ cfg .statuses = append (cfg .statuses , http .StatusOK )
84+ }
85+ return & channel {
86+ url : url ,
87+ client : cfg .client ,
88+ method : cfg .method ,
89+ statuses : cfg .statuses ,
90+ }
3691}
0 commit comments