-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbrowser.go
98 lines (88 loc) · 2.77 KB
/
browser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package browser
import (
"fmt"
"net/http"
"github.com/gost-dom/browser/html"
. "github.com/gost-dom/browser/html"
. "github.com/gost-dom/browser/internal/http"
"github.com/gost-dom/browser/internal/log"
"github.com/gost-dom/browser/scripting/v8host"
)
// Pretty stupid right now, but should _probably_ allow handling multiple
// windows/tabs. This used to be the case for _some_ identity providers, but I'm
// not sure if that even work anymore because of browser security.
type Browser struct {
Client http.Client
ScriptHost ScriptHost
windows []Window
}
// Open will open a new [http.Window], loading the specified location. If the
// server does not respons with a 200 status code, an error is returned.
//
// See [html.NewWindowReader] about the return value, and when the window
// returns.
func (b *Browser) Open(location string) (window Window, err error) {
// log.Debug("Browser: OpenWindow", "URL", location)
resp, err := b.Client.Get(location)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("Non-ok Response: %d", resp.StatusCode)
}
window, err = html.NewWindowReader(resp.Body, b.createOptions(location))
b.windows = append(b.windows, window)
return
}
// NewFromHandler initialises a new [Browser] with the default script engine and
// sets up the internal [http.Client] used with an [http.Roundtripper] that
// bypasses the TCP stack and calls directly into the
//
// Note: There is a current limitation that NO requests from the browser will be
// sent when using this. So sites will not work if they
// - Depend on content from CDN
// - Depend on an external service, e.g., an identity provider.
//
// That is a limitation that was the result of prioritising more important, and
// higher risk features.
func NewFromHandler(handler http.Handler) *Browser {
return &Browser{
ScriptHost: v8host.New(),
Client: NewHttpClientFromHandler(handler),
}
}
// New initialises a new [Browser] with the default script engine.
func New() *Browser {
return &Browser{
ScriptHost: v8host.New(),
Client: NewHttpClient(),
}
}
// NewBrowser should not be called. Call New instead.
//
// This method will selfdestruct in 10 commits
func NewBrowser() *Browser {
return New()
}
// NewBrowserFromHandler should not be called, call, NewFromHandler instead.
//
// This method will selfdestruct in 10 commits
func NewBrowserFromHandler(handler http.Handler) *Browser {
return NewFromHandler(handler)
}
func (b *Browser) createOptions(location string) WindowOptions {
return WindowOptions{
ScriptHost: b.ScriptHost,
HttpClient: b.Client,
BaseLocation: location,
}
}
func (b *Browser) Close() {
log.Debug("Browser: Close()")
for _, win := range b.windows {
win.Close()
}
if b.ScriptHost != nil {
b.ScriptHost.Close()
}
}