Blame view

go/src/themaru/vendor/github.com/gin-contrib/sse/sse-encoder.go 2.2 KB
476d2547e   김태훈   태마루 시스템 설정 / 업데이트...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  // Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
  // Use of this source code is governed by a MIT style
  // license that can be found in the LICENSE file.
  
  package sse
  
  import (
  	"encoding/json"
  	"fmt"
  	"io"
  	"net/http"
  	"reflect"
  	"strconv"
  	"strings"
  )
  
  // Server-Sent Events
  // W3C Working Draft 29 October 2009
  // http://www.w3.org/TR/2009/WD-eventsource-20091029/
  
  const ContentType = "text/event-stream"
  
  var contentType = []string{ContentType}
  var noCache = []string{"no-cache"}
  
  var fieldReplacer = strings.NewReplacer(
  	"
  ", "\
  ",
  	"\r", "\\r")
  
  var dataReplacer = strings.NewReplacer(
  	"
  ", "
  data:",
  	"\r", "\\r")
  
  type Event struct {
  	Event string
  	Id    string
  	Retry uint
  	Data  interface{}
  }
  
  func Encode(writer io.Writer, event Event) error {
  	w := checkWriter(writer)
  	writeId(w, event.Id)
  	writeEvent(w, event.Event)
  	writeRetry(w, event.Retry)
  	return writeData(w, event.Data)
  }
  
  func writeId(w stringWriter, id string) {
  	if len(id) > 0 {
  		w.WriteString("id:")
  		fieldReplacer.WriteString(w, id)
  		w.WriteString("
  ")
  	}
  }
  
  func writeEvent(w stringWriter, event string) {
  	if len(event) > 0 {
  		w.WriteString("event:")
  		fieldReplacer.WriteString(w, event)
  		w.WriteString("
  ")
  	}
  }
  
  func writeRetry(w stringWriter, retry uint) {
  	if retry > 0 {
  		w.WriteString("retry:")
  		w.WriteString(strconv.FormatUint(uint64(retry), 10))
  		w.WriteString("
  ")
  	}
  }
  
  func writeData(w stringWriter, data interface{}) error {
  	w.WriteString("data:")
  	switch kindOfData(data) {
  	case reflect.Struct, reflect.Slice, reflect.Map:
  		err := json.NewEncoder(w).Encode(data)
  		if err != nil {
  			return err
  		}
  		w.WriteString("
  ")
  	default:
  		dataReplacer.WriteString(w, fmt.Sprint(data))
  		w.WriteString("
  
  ")
  	}
  	return nil
  }
  
  func (r Event) Render(w http.ResponseWriter) error {
  	r.WriteContentType(w)
  	return Encode(w, r)
  }
  
  func (r Event) WriteContentType(w http.ResponseWriter) {
  	header := w.Header()
  	header["Content-Type"] = contentType
  
  	if _, exist := header["Cache-Control"]; !exist {
  		header["Cache-Control"] = noCache
  	}
  }
  
  func kindOfData(data interface{}) reflect.Kind {
  	value := reflect.ValueOf(data)
  	valueType := value.Kind()
  	if valueType == reflect.Ptr {
  		valueType = value.Elem().Kind()
  	}
  	return valueType
  }