Browse Source

Add concurrency protection to cookie jars

master
Jason Chu 6 years ago
parent
commit
8e370696b2
  1. 8
      connect.go
  2. 6
      dump.go
  3. 6
      listen.go
  4. 4
      login.go
  5. 2
      mark_read.go
  6. 2
      meta.go
  7. 4
      profile.go
  8. 2
      send.go
  9. 16
      session.go
  10. 2
      thread.go
  11. 2
      typing.go

8
connect.go

@ -91,7 +91,7 @@ func (s *Session) requestReconnect() error {
req, _ := http.NewRequest(http.MethodGet, reconnectURL, nil)
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}
@ -106,7 +106,7 @@ func (s *Session) connectToStage1() error {
return err
}
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}
@ -179,7 +179,7 @@ func (s *Session) connectToStage2() error {
req, _ := http.NewRequest(http.MethodGet, chatURL+s.l.form.encode(), nil)
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}
@ -200,7 +200,7 @@ func (s *Session) connectToStage3() error {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}

6
dump.go

@ -15,6 +15,9 @@ type sessionDump struct {
// Note that if you restore the session, you may not need to login, but you
// must reconnect to chat.
func (s *Session) DumpSession() ([]byte, error) {
s.requestMutex.RUnlock()
defer s.requestMutex.RLock()
fbCookies := s.client.Jar.Cookies(fbURL)
edgeCookies := s.client.Jar.Cookies(edgeURL)
@ -35,6 +38,9 @@ func (s *Session) DumpSession() ([]byte, error) {
// back into the session. Note that you may not need to login again, but you
// must reconnect to chat.
func (s *Session) RestoreSession(data []byte) error {
s.requestMutex.Lock()
defer s.requestMutex.Unlock()
buf := bytes.NewReader(data)
dec := gob.NewDecoder(buf)
restoredSession := sessionDump{}

6
listen.go

@ -173,7 +173,7 @@ func (s *Session) listenRequest() {
nil)
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
go s.l.onError(ListenError{"HTTP listen", err})
time.Sleep(time.Second)
@ -286,7 +286,7 @@ func (s *Session) fullReload() {
s.l.lastSync = time.Now()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
s.l.onError(ListenError{"reload sync", err})
return
@ -308,7 +308,7 @@ func (s *Session) fullReload() {
req, _ := http.NewRequest(http.MethodPost, threadSyncURL,
strings.NewReader(form.Encode()))
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
s.l.onError(ListenError{"reload thread sync", err})
return

4
login.go

@ -26,7 +26,7 @@ func (s *Session) createLoginRequest(email, password string) (*http.Request, err
req, _ := http.NewRequest(http.MethodGet, facebookURL, nil)
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return nil, err
}
@ -92,7 +92,7 @@ func (s *Session) Login(email, password string) error {
return err
}
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err == nil {
resp.Body.Close()
return ErrLoginError

2
mark_read.go

@ -16,7 +16,7 @@ func (s *Session) MarkAsRead(thread Thread) error {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}

2
meta.go

@ -20,7 +20,7 @@ func (s *Session) populateMeta() error {
req, _ := http.NewRequest(http.MethodGet, facebookURL, nil)
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}

4
profile.go

@ -32,7 +32,7 @@ func (s *Session) UserProfileInfo(userID string) (UserProfile, error) {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return UserProfile{}, err
}
@ -75,7 +75,7 @@ func (s *Session) AllUserProfileInfo() (map[string]UserProfile, error) {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return nil, err
}

2
send.go

@ -95,7 +95,7 @@ func (s *Session) SendMessage(msg *Message) (string, error) {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return "", err
}

16
session.go

@ -3,14 +3,16 @@ package messenger
import (
"net/http"
"net/http/cookiejar"
"sync"
"time"
)
// Session represents a Facebook session.
type Session struct {
client *http.Client
userID string
clientID string
client *http.Client
userID string
clientID string
requestMutex *sync.RWMutex
l listener
meta meta
@ -28,8 +30,16 @@ func NewSession() *Session {
Jar: jar,
Timeout: time.Second * 70,
},
requestMutex: new(sync.RWMutex),
meta: meta{
req: 1,
},
}
}
func (s *Session) doRequest(req *http.Request) (resp *http.Response, err error) {
s.requestMutex.RLock()
resp, err = s.client.Do(req)
s.requestMutex.RUnlock()
return
}

2
thread.go

@ -1,5 +1,7 @@
package messenger
// Thread represents a message thread. If IsGroup is false, ThreadID is the
// other user's ID.
type Thread struct {
ThreadID string
IsGroup bool

2
typing.go

@ -31,7 +31,7 @@ func (s *Session) SetTypingIndicator(thread Thread, typing bool) error {
strings.NewReader(form.Encode()))
req.Header = defaultHeader()
resp, err := s.client.Do(req)
resp, err := s.doRequest(req)
if err != nil {
return err
}

Loading…
Cancel
Save