Path: blob/dev/pkg/protocols/headless/engine/hijack.go
2072 views
package engine12// TODO: redundant from katana - the whole headless package should be replace with katana34import (5"encoding/base64"67"github.com/go-rod/rod"8"github.com/go-rod/rod/lib/proto"9)1011// NewHijack create hijack from page.12func NewHijack(page *rod.Page) *Hijack {13return &Hijack{14page: page,15disable: &proto.FetchDisable{},16}17}1819// HijackHandler type20type HijackHandler = func(e *proto.FetchRequestPaused) error2122// Hijack is a hijack handler23type Hijack struct {24page *rod.Page25enable *proto.FetchEnable26disable *proto.FetchDisable27cancel func()28}2930// SetPattern set pattern directly31func (h *Hijack) SetPattern(pattern *proto.FetchRequestPattern) {32h.enable = &proto.FetchEnable{33Patterns: []*proto.FetchRequestPattern{pattern},34}35}3637// Start hijack.38func (h *Hijack) Start(handler HijackHandler) func() error {39if h.enable == nil {40panic("hijack pattern not set")41}4243p, cancel := h.page.WithCancel()44h.cancel = cancel4546err := h.enable.Call(p)47if err != nil {48return func() error { return err }49}5051wait := p.EachEvent(func(e *proto.FetchRequestPaused) {52if handler != nil {53err = handler(e)54}55})5657return func() error {58wait()59return err60}61}6263// Stop64func (h *Hijack) Stop() error {65if h.cancel != nil {66h.cancel()67}68return h.disable.Call(h.page)69}7071// FetchGetResponseBody get request body.72func FetchGetResponseBody(page *rod.Page, e *proto.FetchRequestPaused) ([]byte, error) {73m := proto.FetchGetResponseBody{74RequestID: e.RequestID,75}76r, err := m.Call(page)77if err != nil {78return nil, err79}8081if !r.Base64Encoded {82return []byte(r.Body), nil83}8485bs, err := base64.StdEncoding.DecodeString(r.Body)86if err != nil {87return nil, err88}89return bs, nil90}9192// FetchContinueRequest continue request93func FetchContinueRequest(page *rod.Page, e *proto.FetchRequestPaused) error {94m := proto.FetchContinueRequest{95RequestID: e.RequestID,96}97return m.Call(page)98}99100101