//go:build linux && (webkit2_40 || webkit2_41) package webview /* #cgo linux pkg-config: gtk+-3.0 gio-unix-2.0 #cgo !webkit2_41 pkg-config: webkit2gtk-4.0 #cgo webkit2_41 pkg-config: webkit2gtk-4.1 #include "gtk/gtk.h" #include "webkit2/webkit2.h" #include "gio/gunixinputstream.h" */ import "C" import ( "fmt" "io" "net/http" "unsafe" ) func webkit_uri_scheme_request_get_http_body(req *C.WebKitURISchemeRequest) io.ReadCloser { stream := C.webkit_uri_scheme_request_get_http_body(req) if stream == nil { return http.NoBody } return &webkitRequestBody{stream: stream} } type webkitRequestBody struct { stream *C.GInputStream closed bool } // Read implements io.Reader func (r *webkitRequestBody) Read(p []byte) (int, error) { if r.closed { return 0, io.ErrClosedPipe } var content unsafe.Pointer var contentLen int if p != nil { content = unsafe.Pointer(&p[0]) contentLen = len(p) } var n C.gsize var gErr *C.GError res := C.g_input_stream_read_all(r.stream, content, C.gsize(contentLen), &n, nil, &gErr) if res == 0 { return 0, formatGError("stream read failed", gErr) } else if n == 0 { return 0, io.EOF } return int(n), nil } func (r *webkitRequestBody) Close() error { if r.closed { return nil } r.closed = true // https://docs.gtk.org/gio/method.InputStream.close.html // Streams will be automatically closed when the last reference is dropped, but you might want to call this function // to make sure resources are released as early as possible. var err error var gErr *C.GError if C.g_input_stream_close(r.stream, nil, &gErr) == 0 { err = formatGError("stream close failed", gErr) } C.g_object_unref(C.gpointer(r.stream)) r.stream = nil return err } func formatGError(msg string, gErr *C.GError, args ...any) error { if gErr != nil && gErr.message != nil { msg += ": " + C.GoString(gErr.message) C.g_error_free(gErr) } return fmt.Errorf(msg, args...) }