275 lines
6.4 KiB
Go
275 lines
6.4 KiB
Go
package playwright
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type serializedFallbackOverrides struct {
|
|
URL *string
|
|
Method *string
|
|
Headers map[string]string
|
|
PostDataBuffer []byte
|
|
}
|
|
|
|
type requestImpl struct {
|
|
channelOwner
|
|
timing *RequestTiming
|
|
provisionalHeaders *rawHeaders
|
|
allHeaders *rawHeaders
|
|
redirectedFrom Request
|
|
redirectedTo Request
|
|
failureText string
|
|
fallbackOverrides *serializedFallbackOverrides
|
|
}
|
|
|
|
func (r *requestImpl) URL() string {
|
|
if r.fallbackOverrides.URL != nil {
|
|
return *r.fallbackOverrides.URL
|
|
}
|
|
return r.initializer["url"].(string)
|
|
}
|
|
|
|
func (r *requestImpl) ResourceType() string {
|
|
return r.initializer["resourceType"].(string)
|
|
}
|
|
|
|
func (r *requestImpl) Method() string {
|
|
if r.fallbackOverrides.Method != nil {
|
|
return *r.fallbackOverrides.Method
|
|
}
|
|
return r.initializer["method"].(string)
|
|
}
|
|
|
|
func (r *requestImpl) PostData() (string, error) {
|
|
body, err := r.PostDataBuffer()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(body), err
|
|
}
|
|
|
|
func (r *requestImpl) PostDataJSON(v interface{}) error {
|
|
body, err := r.PostDataBuffer()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(body, v)
|
|
}
|
|
|
|
func (r *requestImpl) PostDataBuffer() ([]byte, error) {
|
|
if r.fallbackOverrides.PostDataBuffer != nil {
|
|
return r.fallbackOverrides.PostDataBuffer, nil
|
|
}
|
|
if _, ok := r.initializer["postData"]; !ok {
|
|
return nil, nil
|
|
}
|
|
return base64.StdEncoding.DecodeString(r.initializer["postData"].(string))
|
|
}
|
|
|
|
func (r *requestImpl) Headers() map[string]string {
|
|
if r.fallbackOverrides.Headers != nil {
|
|
return newRawHeaders(serializeMapToNameAndValue(r.fallbackOverrides.Headers)).Headers()
|
|
}
|
|
return r.provisionalHeaders.Headers()
|
|
}
|
|
|
|
func (r *requestImpl) Response() (Response, error) {
|
|
channel, err := r.channel.Send("response")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
channelOwner := fromNullableChannel(channel)
|
|
if channelOwner == nil {
|
|
// no response
|
|
return nil, nil
|
|
}
|
|
return channelOwner.(*responseImpl), nil
|
|
}
|
|
|
|
func (r *requestImpl) Frame() Frame {
|
|
channel, ok := r.initializer["frame"]
|
|
if !ok {
|
|
// Service Worker requests do not have an associated frame.
|
|
return nil
|
|
}
|
|
frame := fromChannel(channel).(*frameImpl)
|
|
if frame.page == nil {
|
|
// Frame for this navigation request is not available, because the request
|
|
// was issued before the frame is created. You can check whether the request
|
|
// is a navigation request by calling IsNavigationRequest() method.
|
|
return nil
|
|
}
|
|
return frame
|
|
}
|
|
|
|
func (r *requestImpl) IsNavigationRequest() bool {
|
|
return r.initializer["isNavigationRequest"].(bool)
|
|
}
|
|
|
|
func (r *requestImpl) RedirectedFrom() Request {
|
|
return r.redirectedFrom
|
|
}
|
|
|
|
func (r *requestImpl) RedirectedTo() Request {
|
|
return r.redirectedTo
|
|
}
|
|
|
|
func (r *requestImpl) Failure() error {
|
|
if r.failureText == "" {
|
|
return nil
|
|
}
|
|
return fmt.Errorf("%v", r.failureText)
|
|
}
|
|
|
|
func (r *requestImpl) Timing() *RequestTiming {
|
|
return r.timing
|
|
}
|
|
|
|
func (r *requestImpl) AllHeaders() (map[string]string, error) {
|
|
headers, err := r.ActualHeaders()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return headers.Headers(), nil
|
|
}
|
|
|
|
func (r *requestImpl) HeadersArray() ([]NameValue, error) {
|
|
headers, err := r.ActualHeaders()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return headers.HeadersArray(), nil
|
|
}
|
|
|
|
func (r *requestImpl) HeaderValue(name string) (string, error) {
|
|
headers, err := r.ActualHeaders()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return headers.Get(name), err
|
|
}
|
|
|
|
func (r *requestImpl) HeaderValues(name string) ([]string, error) {
|
|
headers, err := r.ActualHeaders()
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
return headers.GetAll(name), err
|
|
}
|
|
|
|
func (r *requestImpl) ActualHeaders() (*rawHeaders, error) {
|
|
if r.fallbackOverrides.Headers != nil {
|
|
return newRawHeaders(serializeMapToNameAndValue(r.fallbackOverrides.Headers)), nil
|
|
}
|
|
if r.allHeaders == nil {
|
|
response, err := r.Response()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response == nil {
|
|
return r.provisionalHeaders, nil
|
|
}
|
|
headers, err := r.channel.Send("rawRequestHeaders")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
r.allHeaders = newRawHeaders(headers)
|
|
}
|
|
return r.allHeaders, nil
|
|
}
|
|
|
|
func (r *requestImpl) ServiceWorker() Worker {
|
|
channel, ok := r.initializer["serviceWorker"]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return fromChannel(channel).(*workerImpl)
|
|
}
|
|
|
|
func (r *requestImpl) Sizes() (*RequestSizesResult, error) {
|
|
response, err := r.Response()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sizes, err := response.(*responseImpl).channel.Send("sizes")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := &RequestSizesResult{}
|
|
remapMapToStruct(sizes, result)
|
|
return result, nil
|
|
}
|
|
|
|
func (r *requestImpl) applyFallbackOverrides(options RouteFallbackOptions) {
|
|
if options.URL != nil {
|
|
r.fallbackOverrides.URL = options.URL
|
|
}
|
|
if options.Method != nil {
|
|
r.fallbackOverrides.Method = options.Method
|
|
}
|
|
r.fallbackOverrides.Headers = options.Headers
|
|
if options.PostData != nil {
|
|
switch v := options.PostData.(type) {
|
|
case string:
|
|
r.fallbackOverrides.PostDataBuffer = []byte(v)
|
|
case []byte:
|
|
r.fallbackOverrides.PostDataBuffer = v
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *requestImpl) targetClosed() <-chan error {
|
|
page := r.safePage()
|
|
if page == nil {
|
|
return make(<-chan error, 1)
|
|
}
|
|
return page.closedOrCrashed
|
|
}
|
|
|
|
func (r *requestImpl) setResponseEndTiming(t float64) {
|
|
r.timing.ResponseEnd = t
|
|
if r.timing.ResponseStart == -1 {
|
|
r.timing.ResponseStart = t
|
|
}
|
|
}
|
|
|
|
func (r *requestImpl) safePage() *pageImpl {
|
|
channel := fromNullableChannel(r.initializer["frame"])
|
|
if channel == nil {
|
|
return nil
|
|
}
|
|
frame, ok := channel.(*frameImpl)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return frame.page
|
|
}
|
|
|
|
func newRequest(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *requestImpl {
|
|
req := &requestImpl{}
|
|
req.createChannelOwner(req, parent, objectType, guid, initializer)
|
|
redirectedFrom := fromNullableChannel(initializer["redirectedFrom"])
|
|
if redirectedFrom != nil {
|
|
req.redirectedFrom = redirectedFrom.(*requestImpl)
|
|
}
|
|
if req.redirectedFrom != nil {
|
|
req.redirectedFrom.(*requestImpl).redirectedTo = req
|
|
}
|
|
req.timing = &RequestTiming{
|
|
StartTime: 0,
|
|
DomainLookupStart: -1,
|
|
DomainLookupEnd: -1,
|
|
ConnectStart: -1,
|
|
SecureConnectionStart: -1,
|
|
ConnectEnd: -1,
|
|
RequestStart: -1,
|
|
ResponseStart: -1,
|
|
ResponseEnd: -1,
|
|
}
|
|
req.provisionalHeaders = newRawHeaders(req.initializer["headers"])
|
|
req.fallbackOverrides = &serializedFallbackOverrides{}
|
|
return req
|
|
}
|