github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/igm/sockjs-go.v2/sockjs/options.go (about) 1 package sockjs 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "math/rand" 7 "net/http" 8 "sync" 9 "time" 10 ) 11 12 var ( 13 entropy *rand.Rand 14 entropyMutex sync.Mutex 15 ) 16 17 func init() { 18 entropy = rand.New(rand.NewSource(time.Now().UnixNano())) 19 } 20 21 // Options type is used for defining various sockjs options 22 type Options struct { 23 // Transports which don't support cross-domain communication natively ('eventsource' to name one) use an iframe trick. 24 // A simple page is served from the SockJS server (using its foreign domain) and is placed in an invisible iframe. 25 // 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. 26 // This iframe also does need to load SockJS javascript client library, and this option lets you specify its url (if you're unsure, 27 // point it to the latest minified SockJS client release, this is the default). You must explicitly specify this url on the server 28 // side for security reasons - we don't want the possibility of running any foreign javascript within the SockJS domain (aka cross site scripting attack). 29 // Also, sockjs javascript library is probably already cached by the browser - it makes sense to reuse the sockjs url you're using in normally. 30 SockJSURL string 31 // Most streaming transports save responses on the client side and don't free memory used by delivered messages. 32 // Such transports need to be garbage-collected once in a while. `response_limit` sets a minimum number of bytes that can be send 33 // over a single http streaming request before it will be closed. After that client needs to open new request. 34 // Setting this value to one effectively disables streaming and will make streaming transports to behave like polling transports. 35 // The default value is 128K. 36 ResponseLimit uint32 37 // Some load balancers don't support websockets. This option can be used to disable websockets support by the server. By default websockets are enabled. 38 Websocket bool 39 // In order to keep proxies and load balancers from closing long running http requests we need to pretend that the connection is active 40 // and send a heartbeat packet once in a while. This setting controls how often this is done. 41 // By default a heartbeat packet is sent every 25 seconds. 42 HeartbeatDelay time.Duration 43 // The server closes a session when a client receiving connection have not been seen for a while. 44 // This delay is configured by this setting. 45 // By default the session is closed when a receiving connection wasn't seen for 5 seconds. 46 DisconnectDelay time.Duration 47 // Some hosting providers enable sticky sessions only to requests that have JSessionID cookie set. 48 // This setting controls if the server should set this cookie to a dummy value. 49 // By default setting JSessionID cookie is disabled. More sophisticated behaviour can be achieved by supplying a function. 50 JSessionID func(http.ResponseWriter, *http.Request) 51 } 52 53 // DefaultOptions is a convenient set of options to be used for sockjs 54 var DefaultOptions = Options{ 55 Websocket: true, 56 JSessionID: nil, 57 SockJSURL: "/libs/sockjsCli/sockjs.min.js", 58 HeartbeatDelay: 25 * time.Second, 59 DisconnectDelay: 5 * time.Second, 60 ResponseLimit: 128 * 1024, 61 } 62 63 type info struct { 64 Websocket bool `json:"websocket"` 65 CookieNeeded bool `json:"cookie_needed"` 66 Origins []string `json:"origins"` 67 Entropy int32 `json:"entropy"` 68 } 69 70 func (options *Options) info(rw http.ResponseWriter, req *http.Request) { 71 switch req.Method { 72 case "GET": 73 rw.Header().Set("Content-Type", "application/json; charset=UTF-8") 74 json.NewEncoder(rw).Encode(info{ 75 Websocket: options.Websocket, 76 CookieNeeded: options.JSessionID != nil, 77 Origins: []string{"*:*"}, 78 Entropy: generateEntropy(), 79 }) 80 case "OPTIONS": 81 rw.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET") 82 rw.Header().Set("Access-Control-Max-Age", fmt.Sprintf("%d", 365*24*60*60)) 83 rw.WriteHeader(http.StatusNoContent) // 204 84 default: 85 http.NotFound(rw, req) 86 } 87 } 88 89 // DefaultJSessionID is a default behaviour function to be used in options for JSessionID if JSESSIONID is needed 90 func DefaultJSessionID(rw http.ResponseWriter, req *http.Request) { 91 cookie, err := req.Cookie("JSESSIONID") 92 if err == http.ErrNoCookie { 93 cookie = &http.Cookie{ 94 Name: "JSESSIONID", 95 Value: "dummy", 96 } 97 } 98 cookie.Path = "/" 99 header := rw.Header() 100 header.Add("Set-Cookie", cookie.String()) 101 } 102 103 func (options *Options) cookie(rw http.ResponseWriter, req *http.Request) { 104 if options.JSessionID != nil { // cookie is needed 105 options.JSessionID(rw, req) 106 } 107 } 108 109 func generateEntropy() int32 { 110 entropyMutex.Lock() 111 entropy := entropy.Int31() 112 entropyMutex.Unlock() 113 return entropy 114 }