1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-16 11:37:36 +02:00
ferret/pkg/drivers/cookies.go
Tim Voronov fe7b45df6e
Bugfix/#399 navigation (#432)
* Refactored networking

* Some work

* Added event loop

* Renamed EventHandler to Handler

* wip

* Removed console logs

* Added DOMManager

* Refactored frame managment

* Fixes

* Fixed concurrency issues

* Fixed unit tests

* Improved EventLoop api

* Some fixes

* Refactored event loop.

* Improved logic of initial page load

* Cleaned up

* Fixed linting issues

* Fixed dom.Manager.Close

* SOme works

* Fixes

* Removed fmt.Println statements

* Refactored WaitForNavigation

* Removed filter for e2e tests

* Made Cookies Measurable

* Made Cookies KeyedCollection

* Fixes after code review

* Updated e2e tests for iframes

* Fixed iframe lookup in e2e tests

* Added comments
2019-12-24 18:47:21 -05:00

184 lines
3.0 KiB
Go

package drivers
import (
"context"
"encoding/binary"
"encoding/json"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
"hash/fnv"
"sort"
"github.com/MontFerret/ferret/pkg/runtime/core"
)
type HTTPCookies map[string]HTTPCookie
func NewHTTPCookies() HTTPCookies {
return make(HTTPCookies)
}
func (c HTTPCookies) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]HTTPCookie(c))
}
func (c HTTPCookies) Type() core.Type {
return HTTPCookiesType
}
func (c HTTPCookies) String() string {
j, err := c.MarshalJSON()
if err != nil {
return "{}"
}
return string(j)
}
func (c HTTPCookies) Compare(other core.Value) int64 {
if other.Type() != HTTPCookiesType {
return Compare(HTTPCookiesType, other.Type())
}
oc := other.(HTTPCookies)
switch {
case len(c) > len(oc):
return 1
case len(c) < len(oc):
return -1
}
for name := range c {
cEl, cExists := c.Get(values.NewString(name))
if !cExists {
return -1
}
ocEl, ocExists := oc.Get(values.NewString(name))
if !ocExists {
return 1
}
c := cEl.Compare(ocEl)
if c != 0 {
return c
}
}
return 0
}
func (c HTTPCookies) Unwrap() interface{} {
return map[string]HTTPCookie(c)
}
func (c HTTPCookies) Hash() uint64 {
hash := fnv.New64a()
hash.Write([]byte(c.Type().String()))
hash.Write([]byte(":"))
hash.Write([]byte("{"))
keys := make([]string, 0, len(c))
for key := range c {
keys = append(keys, key)
}
// order does not really matter
// but it will give us a consistent hash sum
sort.Strings(keys)
endIndex := len(keys) - 1
for idx, key := range keys {
hash.Write([]byte(key))
hash.Write([]byte(":"))
el := c[key]
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, el.Hash())
hash.Write(bytes)
if idx != endIndex {
hash.Write([]byte(","))
}
}
hash.Write([]byte("}"))
return hash.Sum64()
}
func (c HTTPCookies) Copy() core.Value {
copied := make(HTTPCookies)
for k, v := range c {
copied[k] = v
}
return copied
}
func (c HTTPCookies) Length() values.Int {
return values.NewInt(len(c))
}
func (c HTTPCookies) Keys() []values.String {
keys := make([]values.String, 0, len(c))
for k := range c {
keys = append(keys, values.NewString(k))
}
return keys
}
func (c HTTPCookies) Get(key values.String) (core.Value, values.Boolean) {
value, found := c[key.String()]
if found {
return value, values.True
}
return values.None, values.False
}
func (c HTTPCookies) Set(key values.String, value core.Value) {
if cookie, ok := value.(HTTPCookie); ok {
c[key.String()] = cookie
}
}
func (c HTTPCookies) GetIn(ctx context.Context, path []core.Value) (core.Value, error) {
if len(path) == 0 {
return values.None, nil
}
segment := path[0]
err := core.ValidateType(segment, types.String)
if err != nil {
return values.None, err
}
cookie, found := c[segment.String()]
if found {
if len(path) == 1 {
return cookie, nil
}
return values.GetIn(ctx, cookie, path[1:])
}
return values.None, nil
}