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  }