github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/assetserver/webview/webkit2_40+.go (about) 1 //go:build linux && webkit2_40 2 3 package webview 4 5 /* 6 #cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 gio-unix-2.0 7 8 #include "gtk/gtk.h" 9 #include "webkit2/webkit2.h" 10 #include "gio/gunixinputstream.h" 11 */ 12 import "C" 13 14 import ( 15 "fmt" 16 "io" 17 "net/http" 18 "unsafe" 19 ) 20 21 func webkit_uri_scheme_request_get_http_body(req *C.WebKitURISchemeRequest) io.ReadCloser { 22 stream := C.webkit_uri_scheme_request_get_http_body(req) 23 if stream == nil { 24 return http.NoBody 25 } 26 return &webkitRequestBody{stream: stream} 27 } 28 29 type webkitRequestBody struct { 30 stream *C.GInputStream 31 closed bool 32 } 33 34 // Read implements io.Reader 35 func (r *webkitRequestBody) Read(p []byte) (int, error) { 36 if r.closed { 37 return 0, io.ErrClosedPipe 38 } 39 40 var content unsafe.Pointer 41 var contentLen int 42 if p != nil { 43 content = unsafe.Pointer(&p[0]) 44 contentLen = len(p) 45 } 46 47 var n C.gsize 48 var gErr *C.GError 49 res := C.g_input_stream_read_all(r.stream, content, C.gsize(contentLen), &n, nil, &gErr) 50 if res == 0 { 51 return 0, formatGError("stream read failed", gErr) 52 } else if n == 0 { 53 return 0, io.EOF 54 } 55 return int(n), nil 56 } 57 58 func (r *webkitRequestBody) Close() error { 59 if r.closed { 60 return nil 61 } 62 r.closed = true 63 64 // https://docs.gtk.org/gio/method.InputStream.close.html 65 // Streams will be automatically closed when the last reference is dropped, but you might want to call this function 66 // to make sure resources are released as early as possible. 67 var err error 68 var gErr *C.GError 69 if C.g_input_stream_close(r.stream, nil, &gErr) == 0 { 70 err = formatGError("stream close failed", gErr) 71 } 72 C.g_object_unref(C.gpointer(r.stream)) 73 r.stream = nil 74 return err 75 } 76 77 func formatGError(msg string, gErr *C.GError, args ...any) error { 78 if gErr != nil && gErr.message != nil { 79 msg += ": " + C.GoString(gErr.message) 80 C.g_error_free(gErr) 81 } 82 return fmt.Errorf(msg, args...) 83 }