114
vendor/gopkg.in/igm/sockjs-go.v2/sockjs/options.go
generated
vendored
Normal file
114
vendor/gopkg.in/igm/sockjs-go.v2/sockjs/options.go
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
package sockjs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
entropy *rand.Rand
|
||||
entropyMutex sync.Mutex
|
||||
)
|
||||
|
||||
func init() {
|
||||
entropy = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
}
|
||||
|
||||
// Options type is used for defining various sockjs options
|
||||
type Options struct {
|
||||
// Transports which don't support cross-domain communication natively ('eventsource' to name one) use an iframe trick.
|
||||
// A simple page is served from the SockJS server (using its foreign domain) and is placed in an invisible iframe.
|
||||
// Code run from this iframe doesn't need to worry about cross-domain issues, as it's being run from domain local to the SockJS server.
|
||||
// This iframe also does need to load SockJS javascript client library, and this option lets you specify its url (if you're unsure,
|
||||
// point it to the latest minified SockJS client release, this is the default). You must explicitly specify this url on the server
|
||||
// side for security reasons - we don't want the possibility of running any foreign javascript within the SockJS domain (aka cross site scripting attack).
|
||||
// Also, sockjs javascript library is probably already cached by the browser - it makes sense to reuse the sockjs url you're using in normally.
|
||||
SockJSURL string
|
||||
// Most streaming transports save responses on the client side and don't free memory used by delivered messages.
|
||||
// Such transports need to be garbage-collected once in a while. `response_limit` sets a minimum number of bytes that can be send
|
||||
// over a single http streaming request before it will be closed. After that client needs to open new request.
|
||||
// Setting this value to one effectively disables streaming and will make streaming transports to behave like polling transports.
|
||||
// The default value is 128K.
|
||||
ResponseLimit uint32
|
||||
// Some load balancers don't support websockets. This option can be used to disable websockets support by the server. By default websockets are enabled.
|
||||
Websocket bool
|
||||
// In order to keep proxies and load balancers from closing long running http requests we need to pretend that the connection is active
|
||||
// and send a heartbeat packet once in a while. This setting controls how often this is done.
|
||||
// By default a heartbeat packet is sent every 25 seconds.
|
||||
HeartbeatDelay time.Duration
|
||||
// The server closes a session when a client receiving connection have not been seen for a while.
|
||||
// This delay is configured by this setting.
|
||||
// By default the session is closed when a receiving connection wasn't seen for 5 seconds.
|
||||
DisconnectDelay time.Duration
|
||||
// Some hosting providers enable sticky sessions only to requests that have JSessionID cookie set.
|
||||
// This setting controls if the server should set this cookie to a dummy value.
|
||||
// By default setting JSessionID cookie is disabled. More sophisticated behaviour can be achieved by supplying a function.
|
||||
JSessionID func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// DefaultOptions is a convenient set of options to be used for sockjs
|
||||
var DefaultOptions = Options{
|
||||
Websocket: true,
|
||||
JSessionID: nil,
|
||||
SockJSURL: "http://cdn.sockjs.org/sockjs-0.3.min.js",
|
||||
HeartbeatDelay: 25 * time.Second,
|
||||
DisconnectDelay: 5 * time.Second,
|
||||
ResponseLimit: 128 * 1024,
|
||||
}
|
||||
|
||||
type info struct {
|
||||
Websocket bool `json:"websocket"`
|
||||
CookieNeeded bool `json:"cookie_needed"`
|
||||
Origins []string `json:"origins"`
|
||||
Entropy int32 `json:"entropy"`
|
||||
}
|
||||
|
||||
func (options *Options) info(rw http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case "GET":
|
||||
rw.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
json.NewEncoder(rw).Encode(info{
|
||||
Websocket: options.Websocket,
|
||||
CookieNeeded: options.JSessionID != nil,
|
||||
Origins: []string{"*:*"},
|
||||
Entropy: generateEntropy(),
|
||||
})
|
||||
case "OPTIONS":
|
||||
rw.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET")
|
||||
rw.Header().Set("Access-Control-Max-Age", fmt.Sprintf("%d", 365*24*60*60))
|
||||
rw.WriteHeader(http.StatusNoContent) // 204
|
||||
default:
|
||||
http.NotFound(rw, req)
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultJSessionID is a default behaviour function to be used in options for JSessionID if JSESSIONID is needed
|
||||
func DefaultJSessionID(rw http.ResponseWriter, req *http.Request) {
|
||||
cookie, err := req.Cookie("JSESSIONID")
|
||||
if err == http.ErrNoCookie {
|
||||
cookie = &http.Cookie{
|
||||
Name: "JSESSIONID",
|
||||
Value: "dummy",
|
||||
}
|
||||
}
|
||||
cookie.Path = "/"
|
||||
header := rw.Header()
|
||||
header.Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
|
||||
func (options *Options) cookie(rw http.ResponseWriter, req *http.Request) {
|
||||
if options.JSessionID != nil { // cookie is needed
|
||||
options.JSessionID(rw, req)
|
||||
}
|
||||
}
|
||||
|
||||
func generateEntropy() int32 {
|
||||
entropyMutex.Lock()
|
||||
entropy := entropy.Int31()
|
||||
entropyMutex.Unlock()
|
||||
return entropy
|
||||
}
|
||||
Reference in New Issue
Block a user