Skip to content

Commit

Permalink
implemented possibility to get and set all cookies from and to a cook…
Browse files Browse the repository at this point in the history
…iejar;
  • Loading branch information
bogdanfinn committed Sep 18, 2023
1 parent 1b6c4cf commit 39320ce
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 61 deletions.
2 changes: 1 addition & 1 deletion cffi_dist/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ require (
golang.org/x/text v0.6.0 // indirect
)

// replace github.com/bogdanfinn/tls-client => ../
replace github.com/bogdanfinn/tls-client => ../
150 changes: 104 additions & 46 deletions cffi_dist/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import "C"
import (
"encoding/json"
"fmt"
tls_client_cffi_src "github.com/bogdanfinn/tls-client/cffi_src"
"github.com/google/uuid"
"net/url"
"sync"
"unsafe"

http "github.com/bogdanfinn/fhttp"
tls_client_cffi_src "github.com/bogdanfinn/tls-client/cffi_src"
"github.com/google/uuid"
)

var (
Expand Down Expand Up @@ -123,6 +121,50 @@ func getCookiesFromSession(getCookiesParams *C.char) *C.char {
return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

cookies := tlsClient.GetCookieJar().GetAllCookies()

out := tls_client_cffi_src.CookiesFromSessionOutput{
Id: uuid.New().String(),
Cookies: tls_client_cffi_src.TransformCookies(tls_client_cffi_src.ToCookieSlice(cookies)),
}

jsonResponse, marshallError := json.Marshal(out)

if marshallError != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(marshallError)

return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

responseString := C.CString(string(jsonResponse))

unsafePointersLck.Lock()
unsafePointers[out.Id] = responseString
unsafePointersLck.Unlock()

return responseString
}

//export getCookiesFromSessionForUrl
func getCookiesFromSessionForUrl(getCookiesParams *C.char) *C.char {
getCookiesParamsJson := C.GoString(getCookiesParams)

cookiesInput := tls_client_cffi_src.GetCookiesFromSessionForUrlInput{}
marshallError := json.Unmarshal([]byte(getCookiesParamsJson), &cookiesInput)

if marshallError != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(marshallError)

return handleErrorResponse("", false, clientErr)
}

tlsClient, err := tls_client_cffi_src.GetClient(cookiesInput.SessionId)
if err != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(err)

return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

u, parsErr := url.Parse(cookiesInput.Url)
if parsErr != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(parsErr)
Expand All @@ -132,9 +174,10 @@ func getCookiesFromSession(getCookiesParams *C.char) *C.char {

cookies := tlsClient.GetCookies(u)

out := tls_client_cffi_src.CookiesFromSessionOutput{
out := tls_client_cffi_src.CookiesFromSessionForUrlOutput{
Id: uuid.New().String(),
Cookies: transformCookies(cookies),
Url: cookiesInput.Url,
Cookies: tls_client_cffi_src.TransformCookies(cookies),
}

jsonResponse, marshallError := json.Marshal(out)
Expand All @@ -154,11 +197,11 @@ func getCookiesFromSession(getCookiesParams *C.char) *C.char {
return responseString
}

//export addCookiesToSession
func addCookiesToSession(addCookiesParams *C.char) *C.char {
//export addCookiesToSessionForUrl
func addCookiesToSessionForUrl(addCookiesParams *C.char) *C.char {
addCookiesParamsJson := C.GoString(addCookiesParams)

cookiesInput := tls_client_cffi_src.AddCookiesToSessionInput{}
cookiesInput := tls_client_cffi_src.AddCookiesToSessionForUrlInput{}
marshallError := json.Unmarshal([]byte(addCookiesParamsJson), &cookiesInput)

if marshallError != nil {
Expand All @@ -181,13 +224,62 @@ func addCookiesToSession(addCookiesParams *C.char) *C.char {
return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

tlsClient.SetCookies(u, buildCookies(cookiesInput.Cookies))
tlsClient.SetCookies(u, tls_client_cffi_src.BuildCookies(cookiesInput.Cookies))

allCookies := tlsClient.GetCookies(u)

out := tls_client_cffi_src.CookiesFromSessionForUrlOutput{
Id: uuid.New().String(),
Url: cookiesInput.Url,
Cookies: tls_client_cffi_src.TransformCookies(allCookies),
}

jsonResponse, marshallError := json.Marshal(out)

if marshallError != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(marshallError)

return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

responseString := C.CString(string(jsonResponse))

unsafePointersLck.Lock()
unsafePointers[out.Id] = responseString
unsafePointersLck.Unlock()

return responseString
}

//export addCookiesToSession
func addCookiesToSession(addCookiesParams *C.char) *C.char {
addCookiesParamsJson := C.GoString(addCookiesParams)

cookiesInput := tls_client_cffi_src.AddCookiesToSessionInput{}
marshallError := json.Unmarshal([]byte(addCookiesParamsJson), &cookiesInput)

if marshallError != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(marshallError)

return handleErrorResponse("", false, clientErr)
}

tlsClient, err := tls_client_cffi_src.GetClient(cookiesInput.SessionId)
if err != nil {
clientErr := tls_client_cffi_src.NewTLSClientError(err)

return handleErrorResponse(cookiesInput.SessionId, true, clientErr)
}

cookieJar := tlsClient.GetCookieJar()

cookieJar.SetAllCookies(tls_client_cffi_src.ToCookieMap(tls_client_cffi_src.BuildCookies(cookiesInput.Cookies)))

allCookies := cookieJar.GetAllCookies()

out := tls_client_cffi_src.CookiesFromSessionOutput{
Id: uuid.New().String(),
Cookies: transformCookies(allCookies),
Cookies: tls_client_cffi_src.TransformCookies(tls_client_cffi_src.ToCookieSlice(allCookies)),
}

jsonResponse, marshallError := json.Marshal(out)
Expand Down Expand Up @@ -232,7 +324,7 @@ func request(requestParams *C.char) *C.char {
return handleErrorResponse(sessionId, withSession, clientErr)
}

cookies := buildCookies(requestInput.RequestCookies)
cookies := tls_client_cffi_src.BuildCookies(requestInput.RequestCookies)

if len(cookies) > 0 {
tlsClient.SetCookies(req.URL, cookies)
Expand Down Expand Up @@ -306,39 +398,5 @@ func handleErrorResponse(sessionId string, withSession bool, err *tls_client_cff
return responseString
}

func buildCookies(cookies []tls_client_cffi_src.Cookie) []*http.Cookie {
var ret []*http.Cookie

for _, cookie := range cookies {
ret = append(ret, &http.Cookie{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: cookie.Expires.Time,
})
}

return ret
}

func transformCookies(cookies []*http.Cookie) []tls_client_cffi_src.Cookie {
var ret []tls_client_cffi_src.Cookie

for _, cookie := range cookies {
ret = append(ret, tls_client_cffi_src.Cookie{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: tls_client_cffi_src.Timestamp{
Time: cookie.Expires,
},
})
}

return ret
}

func main() {
}
8 changes: 2 additions & 6 deletions cffi_src/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"sync"

http "github.com/bogdanfinn/fhttp"
"github.com/bogdanfinn/fhttp/cookiejar"
"github.com/bogdanfinn/fhttp/http2"
"github.com/bogdanfinn/tls-client"
tls "github.com/bogdanfinn/utls"
Expand Down Expand Up @@ -343,13 +342,10 @@ func getTlsClient(requestInput RequestInput, sessionId string, withSession bool)
jarOptions = append(jarOptions, tls_client.WithDebugLogger())
}

jar := tls_client.NewCookieJar(jarOptions...)

if requestInput.WithDefaultCookieJar {
jar, _ := cookiejar.New(nil)
options = append(options, tls_client.WithCookieJar(jar))
options = append(options, tls_client.WithCookieJar(tls_client.NewHttpCookiejar()))
} else {
options = append(options, tls_client.WithCookieJar(jar))
options = append(options, tls_client.WithCookieJar(tls_client.NewCookieJar(jarOptions...)))
}
}

Expand Down
62 changes: 62 additions & 0 deletions cffi_src/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package tls_client_cffi_src

import (
"fmt"
http "github.com/bogdanfinn/fhttp"
)

func BuildCookies(cookies []Cookie) []*http.Cookie {
var ret []*http.Cookie

for _, cookie := range cookies {
ret = append(ret, &http.Cookie{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: cookie.Expires.Time,
})
}

return ret
}

func ToCookieMap(cookies []*http.Cookie) map[string][]*http.Cookie {
ret := make(map[string][]*http.Cookie)

for _, cookie := range cookies {
urlString := fmt.Sprintf("%s%s", cookie.Domain, cookie.Path)

ret[urlString] = append(ret[urlString], cookie)
}

return ret
}

func ToCookieSlice(cookies map[string][]*http.Cookie) []*http.Cookie {
var ret []*http.Cookie

for _, cookies := range cookies {
ret = append(ret, cookies...)
}

return ret
}

func TransformCookies(cookies []*http.Cookie) []Cookie {
var ret []Cookie

for _, cookie := range cookies {
ret = append(ret, Cookie{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: Timestamp{
Time: cookie.Expires,
},
})
}

return ret
}
17 changes: 16 additions & 1 deletion cffi_src/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,29 @@ type DestroyOutput struct {
type AddCookiesToSessionInput struct {
Cookies []Cookie `json:"cookies"`
SessionId string `json:"sessionId"`
}

type AddCookiesToSessionForUrlInput struct {
Cookies []Cookie `json:"cookies"`
SessionId string `json:"sessionId"`
Url string `json:"url"`
}

type GetCookiesFromSessionInput struct {
type GetCookiesFromSessionForUrlInput struct {
SessionId string `json:"sessionId"`
Url string `json:"url"`
}

type GetCookiesFromSessionInput struct {
SessionId string `json:"sessionId"`
}

type CookiesFromSessionForUrlOutput struct {
Id string `json:"id"`
Url string `json:"url"`
Cookies []Cookie `json:"cookies"`
}

type CookiesFromSessionOutput struct {
Id string `json:"id"`
Cookies []Cookie `json:"cookies"`
Expand Down
16 changes: 11 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ var defaultRedirectFunc = func(req *http.Request, via []*http.Request) error {
type HttpClient interface {
GetCookies(u *url.URL) []*http.Cookie
SetCookies(u *url.URL, cookies []*http.Cookie)
SetCookieJar(jar http.CookieJar)
GetCookieJar() http.CookieJar
SetCookieJar(jar CookieJar)
GetCookieJar() CookieJar
SetProxy(proxyUrl string) error
GetProxy() string
SetFollowRedirect(followRedirect bool)
Expand Down Expand Up @@ -264,13 +264,19 @@ func (c *httpClient) SetCookies(u *url.URL, cookies []*http.Cookie) {
}

// SetCookieJar sets a jar as the clients cookie jar. This is the recommended way when you want to "clear" the existing cookiejar
func (c *httpClient) SetCookieJar(jar http.CookieJar) {
func (c *httpClient) SetCookieJar(jar CookieJar) {
c.Jar = jar
}

// GetCookieJar returns the jar the client is currently using
func (c *httpClient) GetCookieJar() http.CookieJar {
return c.Jar
func (c *httpClient) GetCookieJar() CookieJar {
jar := c.Jar

if jar == nil {
return nil
}

return jar.(CookieJar)
}

// Do issues a given HTTP request and returns the corresponding response.
Expand Down
4 changes: 2 additions & 2 deletions client_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type httpClientConfig struct {
proxyUrl string
serverNameOverwrite string
transportOptions *TransportOptions
cookieJar http.CookieJar
cookieJar CookieJar
clientProfile profiles.ClientProfile
withRandomTlsExtensionOrder bool
forceHttp1 bool
Expand Down Expand Up @@ -85,7 +85,7 @@ func WithCharlesProxy(host string, port string) HttpClientOption {
}

// WithCookieJar configures a HTTP client to use the specified cookie jar.
func WithCookieJar(jar http.CookieJar) HttpClientOption {
func WithCookieJar(jar CookieJar) HttpClientOption {
return func(config *httpClientConfig) {
config.cookieJar = jar
}
Expand Down
Loading

0 comments on commit 39320ce

Please sign in to comment.