-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement http.RoundTripper #10
Comments
Sorry, somehow we missed this issue. I'm definitely open to it! There is some overlap with our HTTP impl but we could probably re-use the objects. |
Out of curiosity, I decided to try and implement this. It works when compiling Wasm code from the The problem with it, which I am not willing to really accept in order to make this part of the PDK is the size of the Wasm, which is over 5x the size when compiled with Here's the implementation, and a client that uses the package stdhttp_compat
import (
"bytes"
"fmt"
"io"
"net/http"
"github.com/extism/go-pdk"
)
type roundTripper struct{}
// convert the *http.Request into an Extism HTTP Request, send it, and convert the
// Extism HTTP Response into the *http.Response.
func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
var method pdk.HTTPMethod
switch req.Method {
case http.MethodGet:
method = pdk.MethodGet
case http.MethodHead:
method = pdk.MethodHead
case http.MethodPost:
method = pdk.MethodPost
case http.MethodPut:
method = pdk.MethodPut
case http.MethodPatch:
method = pdk.MethodPatch
case http.MethodDelete:
method = pdk.MethodDelete
case http.MethodConnect:
method = pdk.MethodConnect
case http.MethodOptions:
method = pdk.MethodOptions
case http.MethodTrace:
method = pdk.MethodTrace
default:
method = pdk.MethodGet
}
extismReq := pdk.NewHTTPRequest(method, req.URL.String())
var body []byte
if req.Body != nil {
var buf bytes.Buffer
_, err := io.Copy(&buf, req.Body)
if err != nil {
return nil, err
}
body = buf.Bytes()
req.Body.Close()
}
extismReq.SetBody(body)
for k := range req.Header {
extismReq.SetHeader(k, req.Header.Get(k))
}
extismResp := extismReq.Send()
var buf bytes.Buffer
conentLength, err := buf.Write(extismResp.Body())
if err != nil {
return nil, err
}
bufCloser := io.NopCloser(&buf)
res := &http.Response{
Status: fmt.Sprintf("%d", extismResp.Status()),
StatusCode: int(extismResp.Status()),
Proto: req.Proto,
ProtoMajor: req.ProtoMajor,
ProtoMinor: req.ProtoMinor,
Header: nil,
Body: bufCloser,
ContentLength: int64(conentLength),
TransferEncoding: nil,
Close: false,
Uncompressed: false,
Trailer: nil,
Request: req,
}
return res, nil
}
var Client = &http.Client{Transport: roundTripper{}} |
To make the HTTP function more accessible to Go developers, it would be nice if
go-pdk
implementedhttp.RoundTripper
to process standard HTTP requests. This way, a larger ecosystem of middleware can be used by plugins.Ideally, this would allow a plugin like this:
There might be quite some things that the
pdk.RoundTripper
cannot support (streaming responses, for example). But since that's not supported anyways, we could just return anerror
explaining what isn't supported. For basic requests/responses this should be relatively doable.The `http.RoundTripper interface is an easy one to implement:
https://github.com/golang/go/blob/a031f4ef83edc132d5f49382bfef491161de2476/src/net/http/client.go#L117-L143
Thoughts?
The text was updated successfully, but these errors were encountered: