diff --git a/v2/cmd/wails/internal/commands/doctor/doctor.go b/v2/cmd/wails/internal/commands/doctor/doctor.go index 7fa472835..035e4ad54 100644 --- a/v2/cmd/wails/internal/commands/doctor/doctor.go +++ b/v2/cmd/wails/internal/commands/doctor/doctor.go @@ -5,7 +5,6 @@ import ( "io" "os" "runtime" - "runtime/debug" "strings" "text/tabwriter" @@ -60,20 +59,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error { fmt.Fprintf(w, "------\n") fmt.Fprintf(w, "%s\t%s\n", "Version: ", app.Version()) - if buildInfo, _ := debug.ReadBuildInfo(); buildInfo != nil { - buildSettingToName := map[string]string{ - "vcs.revision": "Revision", - "vcs.modified": "Modified", - } - for _, buildSetting := range buildInfo.Settings { - name := buildSettingToName[buildSetting.Key] - if name == "" { - continue - } - - fmt.Fprintf(w, "%s:\t%s\n", name, buildSetting.Value) - } - } + printBuildSettings(w) // Exit early if PM not found if info.PM != nil { diff --git a/v2/cmd/wails/internal/commands/doctor/doctor_go117.go b/v2/cmd/wails/internal/commands/doctor/doctor_go117.go new file mode 100644 index 000000000..86d817d6b --- /dev/null +++ b/v2/cmd/wails/internal/commands/doctor/doctor_go117.go @@ -0,0 +1,10 @@ +//go:build !go1.18 +// +build !go1.18 + +package doctor + +import "text/tabwriter" + +func printBuildSettings(_ *tabwriter.Writer) { + return +} diff --git a/v2/cmd/wails/internal/commands/doctor/doctor_go118.go b/v2/cmd/wails/internal/commands/doctor/doctor_go118.go new file mode 100644 index 000000000..8118b4955 --- /dev/null +++ b/v2/cmd/wails/internal/commands/doctor/doctor_go118.go @@ -0,0 +1,21 @@ +//go:build go1.18 +// +build go1.18 + +package doctor + +func printBuildSettings(w *tabwriter.Writer) { + if buildInfo, _ := debug.ReadBuildInfo(); buildInfo != nil { + buildSettingToName := map[string]string{ + "vcs.revision": "Revision", + "vcs.modified": "Modified", + } + for _, buildSetting := range buildInfo.Settings { + name := buildSettingToName[buildSetting.Key] + if name == "" { + continue + } + + fmt.Fprintf(w, "%s:\t%s\n", name, buildSetting.Value) + } + } +} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go new file mode 100644 index 000000000..be2536b92 --- /dev/null +++ b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go @@ -0,0 +1,76 @@ +package edge + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +type _ICoreWebView2HttpHeadersCollectionIteratorVtbl struct { + _IUnknownVtbl + GetCurrentHeader ComProc + GetHasCurrentHeader ComProc + MoveNext ComProc +} + +type ICoreWebView2HttpHeadersCollectionIterator struct { + vtbl *_ICoreWebView2HttpHeadersCollectionIteratorVtbl +} + +func (i *ICoreWebView2HttpHeadersCollectionIterator) Release() error { + return i.vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2HttpHeadersCollectionIterator) HasCurrentHeader() (bool, error) { + var hasHeader bool + res, _, err := i.vtbl.GetHasCurrentHeader.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&hasHeader)), + ) + if err != windows.ERROR_SUCCESS { + return false, err + } + if windows.Handle(res) != windows.S_OK { + return false, syscall.Errno(res) + } + return hasHeader, nil +} + +func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, string, error) { + // Create *uint16 to hold result + var _name *uint16 + var _value *uint16 + res, _, err := i.vtbl.GetCurrentHeader.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&_name)), + uintptr(unsafe.Pointer(&_value)), + ) + if err != windows.ERROR_SUCCESS { + return "", "", err + } + if windows.Handle(res) != windows.S_OK { + return "", "", syscall.Errno(res) + } + // Get result and cleanup + name := windows.UTF16PtrToString(_name) + windows.CoTaskMemFree(unsafe.Pointer(_name)) + value := windows.UTF16PtrToString(_value) + windows.CoTaskMemFree(unsafe.Pointer(_value)) + return name, value, nil +} + +func (i *ICoreWebView2HttpHeadersCollectionIterator) MoveNext() (bool, error) { + var next bool + res, _, err := i.vtbl.MoveNext.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&next)), + ) + if err != windows.ERROR_SUCCESS { + return false, err + } + if windows.Handle(res) != windows.S_OK { + return false, syscall.Errno(res) + } + return next, nil +} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go new file mode 100644 index 000000000..a1ad2cb0b --- /dev/null +++ b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go @@ -0,0 +1,43 @@ +package edge + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +type _ICoreWebView2HttpRequestHeadersVtbl struct { + _IUnknownVtbl + GetHeader ComProc + GetHeaders ComProc + Contains ComProc + SetHeader ComProc + RemoveHeader ComProc + GetIterator ComProc +} + +type ICoreWebView2HttpRequestHeaders struct { + vtbl *_ICoreWebView2HttpRequestHeadersVtbl +} + +func (i *ICoreWebView2HttpRequestHeaders) Release() error { + return i.vtbl.CallRelease(unsafe.Pointer(i)) +} + +// GetIterator returns an iterator over the collection of request headers. Make sure to call +// Release on the returned Object after finished using it. +func (i *ICoreWebView2HttpRequestHeaders) GetIterator() (*ICoreWebView2HttpHeadersCollectionIterator, error) { + var headers *ICoreWebView2HttpHeadersCollectionIterator + res, _, err := i.vtbl.GetIterator.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&headers)), + ) + if err != windows.ERROR_SUCCESS { + return nil, err + } + if windows.Handle(res) != windows.S_OK { + return nil, syscall.Errno(res) + } + return headers, nil +} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go index 06a9671cf..f9119ee52 100644 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go +++ b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go @@ -1,6 +1,7 @@ package edge import ( + "syscall" "unsafe" "golang.org/x/sys/windows" @@ -25,6 +26,25 @@ func (i *ICoreWebView2WebResourceRequest) AddRef() uintptr { return i.AddRef() } +func (i *ICoreWebView2WebResourceRequest) GetMethod() (string, error) { + // Create *uint16 to hold result + var _method *uint16 + res, _, err := i.vtbl.GetMethod.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&_method)), + ) + if err != windows.ERROR_SUCCESS { + return "", err + } + if windows.Handle(res) != windows.S_OK { + return "", syscall.Errno(res) + } + // Get result and cleanup + uri := windows.UTF16PtrToString(_method) + windows.CoTaskMemFree(unsafe.Pointer(_method)) + return uri, nil +} + func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) { var err error // Create *uint16 to hold result @@ -41,6 +61,40 @@ func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) { return uri, nil } +// GetContent returns the body of the request. Returns nil if there's no body. Make sure to call +// Release on the returned IStream after finished using it. +func (i *ICoreWebView2WebResourceRequest) GetContent() (*IStream, error) { + var stream *IStream + res, _, err := i.vtbl.GetContent.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&stream)), + ) + if err != windows.ERROR_SUCCESS { + return nil, err + } + if windows.Handle(res) != windows.S_OK { + return nil, syscall.Errno(res) + } + return stream, nil +} + +// GetHeaders returns the mutable HTTP request headers. Make sure to call +// Release on the returned Object after finished using it. +func (i *ICoreWebView2WebResourceRequest) GetHeaders() (*ICoreWebView2HttpRequestHeaders, error) { + var headers *ICoreWebView2HttpRequestHeaders + res, _, err := i.vtbl.GetHeaders.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&headers)), + ) + if err != windows.ERROR_SUCCESS { + return nil, err + } + if windows.Handle(res) != windows.S_OK { + return nil, syscall.Errno(res) + } + return headers, nil +} + func (i *ICoreWebView2WebResourceRequest) Release() error { return i.vtbl.CallRelease(unsafe.Pointer(i)) } diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go index 75ed3e7bc..570390007 100644 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go +++ b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go @@ -1,9 +1,17 @@ package edge -import "unsafe" +import ( + "io" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) type _IStreamVtbl struct { _IUnknownVtbl + Read ComProc + Write ComProc } type IStream struct { @@ -13,3 +21,32 @@ type IStream struct { func (i *IStream) Release() error { return i.vtbl.CallRelease(unsafe.Pointer(i)) } + +func (i *IStream) Read(p []byte) (int, error) { + bufLen := len(p) + if bufLen == 0 { + return 0, nil + } + + var n int + res, _, err := i.vtbl.Read.Call( + uintptr(unsafe.Pointer(i)), + uintptr(unsafe.Pointer(&p[0])), + uintptr(bufLen), + uintptr(unsafe.Pointer(&n)), + ) + if err != windows.ERROR_SUCCESS { + return 0, err + } + + switch windows.Handle(res) { + case windows.S_OK: + // The buffer has been completely filled + return n, nil + case windows.S_FALSE: + // The buffer has been filled with less than len data and the stream is EOF + return n, io.EOF + default: + return 0, syscall.Errno(res) + } +}