github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/igm/sockjs-go.v2/sockjs/xhr.go (about) 1 package sockjs 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "strings" 9 ) 10 11 var ( 12 cFrame = closeFrame(2010, "Another connection still open") 13 xhrStreamingPrelude = strings.Repeat("h", 2048) 14 ) 15 16 func (h *handler) xhrSend(rw http.ResponseWriter, req *http.Request) { 17 if req.Body == nil { 18 httpError(rw, "Payload expected.", http.StatusInternalServerError) 19 return 20 } 21 var messages []string 22 err := json.NewDecoder(req.Body).Decode(&messages) 23 if err == io.EOF { 24 httpError(rw, "Payload expected.", http.StatusInternalServerError) 25 return 26 } 27 if _, ok := err.(*json.SyntaxError); ok || err == io.ErrUnexpectedEOF { 28 httpError(rw, "Broken JSON encoding.", http.StatusInternalServerError) 29 return 30 } 31 sessionID, err := h.parseSessionID(req.URL) 32 if err != nil { 33 http.Error(rw, err.Error(), http.StatusInternalServerError) 34 return 35 } 36 37 h.sessionsMux.Lock() 38 defer h.sessionsMux.Unlock() 39 if sess, ok := h.sessions[sessionID]; !ok { 40 http.NotFound(rw, req) 41 } else { 42 _ = sess.accept(messages...) // TODO(igm) reponse with SISE in case of err? 43 rw.Header().Set("content-type", "text/plain; charset=UTF-8") // Ignored by net/http (but protocol test complains), see https://code.google.com/p/go/source/detail?r=902dc062bff8 44 rw.WriteHeader(http.StatusNoContent) 45 } 46 } 47 48 type xhrFrameWriter struct{} 49 50 func (*xhrFrameWriter) write(w io.Writer, frame string) (int, error) { 51 return fmt.Fprintf(w, "%s\n", frame) 52 } 53 54 func (h *handler) xhrPoll(rw http.ResponseWriter, req *http.Request) { 55 rw.Header().Set("content-type", "application/javascript; charset=UTF-8") 56 sess, _ := h.sessionByRequest(req) // TODO(igm) add err handling, although err should not happen as handler should not pass req in that case 57 receiver := newHTTPReceiver(rw, 1, new(xhrFrameWriter)) 58 if err := sess.attachReceiver(receiver); err != nil { 59 receiver.sendFrame(cFrame) 60 receiver.close() 61 return 62 } 63 64 select { 65 case <-receiver.doneNotify(): 66 case <-receiver.interruptedNotify(): 67 } 68 } 69 70 func (h *handler) xhrStreaming(rw http.ResponseWriter, req *http.Request) { 71 rw.Header().Set("content-type", "application/javascript; charset=UTF-8") 72 fmt.Fprintf(rw, "%s\n", xhrStreamingPrelude) 73 rw.(http.Flusher).Flush() 74 75 sess, _ := h.sessionByRequest(req) 76 receiver := newHTTPReceiver(rw, h.options.ResponseLimit, new(xhrFrameWriter)) 77 78 if err := sess.attachReceiver(receiver); err != nil { 79 receiver.sendFrame(cFrame) 80 receiver.close() 81 return 82 } 83 84 select { 85 case <-receiver.doneNotify(): 86 case <-receiver.interruptedNotify(): 87 } 88 }