Skip to content

Commit

Permalink
Merge 1ab2e8f into 407312a
Browse files Browse the repository at this point in the history
  • Loading branch information
cenkalti committed Sep 4, 2017
2 parents 407312a + 1ab2e8f commit 3c9dd27
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
14 changes: 14 additions & 0 deletions sockjs/rawwebsocket.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sockjs

import (
"encoding/json"
"net/http"

"github.com/gorilla/websocket"
Expand Down Expand Up @@ -76,6 +77,10 @@ func (w *rawWsReceiver) sendFrame(frame string) {
var err error
if frame == "h" {
err = w.conn.WriteMessage(websocket.PingMessage, []byte{})
} else if len(frame) > 0 && frame[0] == 'c' {
status, reason := parseCloseFrame(frame)
msg := websocket.FormatCloseMessage(int(status), reason)
err = w.conn.WriteMessage(websocket.CloseMessage, msg)
} else {
err = w.conn.WriteMessage(websocket.TextMessage, []byte(frame))
}
Expand All @@ -84,6 +89,15 @@ func (w *rawWsReceiver) sendFrame(frame string) {
}
}

func parseCloseFrame(frame string) (status uint32, reason string) {
var items [2]interface{}
json.Unmarshal([]byte(frame)[1:], &items)
statusF := items[0].(float64)
status = uint32(statusF)
reason = items[1].(string)
return
}

func (w *rawWsReceiver) close() {
select {
case <-w.closeCh: // already closed
Expand Down
21 changes: 15 additions & 6 deletions sockjs/rawwebsocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package sockjs
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -53,14 +52,24 @@ func TestHandler_RawWebSocketTerminationByServer(t *testing.T) {
url := "ws" + server.URL[4:]
h.handlerFunc = func(conn Session) {
// close the session without sending any message
conn.Close(1024, "some close message")
conn.Close(3000, "some close message")
conn.Close(0, "this should be ignored")
}
conn, _, err := websocket.DefaultDialer.Dial(url, map[string][]string{"Origin": []string{server.URL}})
_, _, err = conn.ReadMessage()
// gorilla websocket keeps `errUnexpectedEOF` private so we need to introspect the error message
if err != nil {
if !strings.Contains(err.Error(), "unexpected EOF") {
t.Errorf("Expected 'unexpected EOF' error or similar, got '%v'", err)
t.Fatalf("websocket dial failed: %v", err)
}
for i := 0; i < 2; i++ {
_, _, err := conn.ReadMessage()
closeError, ok := err.(*websocket.CloseError)
if !ok {
t.Fatalf("expected close error but got: %v", err)
}
if closeError.Code != 3000 {
t.Errorf("unexpected close status: %v", closeError.Code)
}
if closeError.Text != "some close message" {
t.Errorf("unexpected close reason: '%v'", closeError.Text)
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions sockjs/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,7 @@ func (s *session) closing() {
s.msgWriter.Close()
s.state = SessionClosing
if s.recv != nil {
if !s.raw {
s.recv.sendFrame(s.closeFrame)
}
s.recv.sendFrame(s.closeFrame)
s.recv.close()
}
}
Expand Down
5 changes: 4 additions & 1 deletion sockjs/websocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ func TestHandler_WebSocketTerminationByServer(t *testing.T) {
conn.Close(0, "this should be ignored")
}
conn, _, err := websocket.DefaultDialer.Dial(url, map[string][]string{"Origin": []string{server.URL}})
if err != nil {
t.Fatalf("websocket dial failed: %v", err)
}
_, msg, err := conn.ReadMessage()
if string(msg) != "o" || err != nil {
t.Errorf("Open frame expected, got '%s' and error '%v', expected '%s' without error", msg, err, "o")
}
_, msg, err = conn.ReadMessage()
if string(msg) != `c[1024,"some close message"]` || err != nil {
t.Errorf("Open frame expected, got '%s' and error '%v', expected '%s' without error", msg, err, `c[1024,"some close message"]`)
t.Errorf("Close frame expected, got '%s' and error '%v', expected '%s' without error", msg, err, `c[1024,"some close message"]`)
}
_, msg, err = conn.ReadMessage()
// gorilla websocket keeps `errUnexpectedEOF` private so we need to introspect the error message
Expand Down

0 comments on commit 3c9dd27

Please sign in to comment.