Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
name: Bearer PR Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
rule_check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: reviewdog/action-setup@v1
|
||||||
|
with:
|
||||||
|
reviewdog_version: latest
|
||||||
|
|
||||||
|
- name: Run Report
|
||||||
|
id: report
|
||||||
|
uses: bearer/bearer-action@v2
|
||||||
|
with:
|
||||||
|
format: rdjson
|
||||||
|
output: rd.json
|
||||||
|
diff: true
|
||||||
|
|
||||||
|
- name: Run reviewdog
|
||||||
|
if: always()
|
||||||
|
env:
|
||||||
|
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
cat rd.json | reviewdog -f=rdjson -reporter=github-pr-review
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
schedule:
|
||||||
|
- cron: "37 2 * * 5"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: ["go"]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||||
|
# Learn more:
|
||||||
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
schedule:
|
||||||
|
- cron: "41 23 * * 6"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: ["go"]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Goreleaser
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Run GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||||
|
distribution: goreleaser
|
||||||
|
version: latest
|
||||||
|
args: release --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
builds:
|
||||||
|
- # If true, skip the build.
|
||||||
|
# Useful for library projects.
|
||||||
|
# Default is false
|
||||||
|
skip: true
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
use: github
|
||||||
|
groups:
|
||||||
|
- title: Features
|
||||||
|
regexp: "^.*feat[(\\w)]*:+.*$"
|
||||||
|
order: 0
|
||||||
|
- title: "Bug fixes"
|
||||||
|
regexp: "^.*fix[(\\w)]*:+.*$"
|
||||||
|
order: 1
|
||||||
|
- title: "Enhancements"
|
||||||
|
regexp: "^.*chore[(\\w)]*:+.*$"
|
||||||
|
order: 2
|
||||||
|
- title: "Refactor"
|
||||||
|
regexp: "^.*refactor[(\\w)]*:+.*$"
|
||||||
|
order: 3
|
||||||
|
- title: "Build process updates"
|
||||||
|
regexp: ^.*?(build|ci)(\(.+\))??!?:.+$
|
||||||
|
order: 4
|
||||||
|
- title: "Documentation updates"
|
||||||
|
regexp: ^.*?docs?(\(.+\))??!?:.+$
|
||||||
|
order: 4
|
||||||
|
- title: Others
|
||||||
|
order: 999
|
||||||
@@ -13,26 +13,26 @@ Copied from [gin-contrib/sse](https://github.com/gin-contrib/sse)
|
|||||||
import "git.company.lan/gopkg/gin-sse"
|
import "git.company.lan/gopkg/gin-sse"
|
||||||
|
|
||||||
func httpHandler(w http.ResponseWriter, req *http.Request) {
|
func httpHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
// data can be a primitive like a string, an integer or a float
|
// data can be a primitive like a string, an integer or a float
|
||||||
sse.Encode(w, sse.Event{
|
sse.Encode(w, sse.Event{
|
||||||
Event: "message",
|
Event: "message",
|
||||||
Data: "some data\nmore data",
|
Data: "some data\nmore data",
|
||||||
})
|
})
|
||||||
|
|
||||||
// also a complex type, like a map, a struct or a slice
|
// also a complex type, like a map, a struct or a slice
|
||||||
sse.Encode(w, sse.Event{
|
sse.Encode(w, sse.Event{
|
||||||
Id: "124",
|
Id: "124",
|
||||||
Event: "message",
|
Event: "message",
|
||||||
Data: map[string]interface{}{
|
Data: map[string]interface{}{
|
||||||
"user": "manu",
|
"user": "manu",
|
||||||
"date": time.Now().Unix(),
|
"date": time.Now().Unix(),
|
||||||
"content": "hi!",
|
"content": "hi!",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```sh
|
||||||
event: message
|
event: message
|
||||||
data: some data\\nmore data
|
data: some data\\nmore data
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ data: {"content":"hi!","date":1431540810,"user":"manu"}
|
|||||||
fmt.Println(sse.ContentType)
|
fmt.Println(sse.ContentType)
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```sh
|
||||||
text/event-stream
|
text/event-stream
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
module git.company.lan/gopkg/gin-sse
|
module git.company.lan/gopkg/gin-sse
|
||||||
|
|
||||||
go 1.13
|
go 1.23
|
||||||
|
|
||||||
require github.com/stretchr/testify v1.8.0
|
require github.com/stretchr/testify v1.10.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
+7
-6
@@ -7,7 +7,6 @@ package sse
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type decoder struct {
|
type decoder struct {
|
||||||
@@ -22,7 +21,8 @@ func Decode(r io.Reader) ([]Event, error) {
|
|||||||
func (d *decoder) dispatchEvent(event Event, data string) {
|
func (d *decoder) dispatchEvent(event Event, data string) {
|
||||||
dataLength := len(data)
|
dataLength := len(data)
|
||||||
if dataLength > 0 {
|
if dataLength > 0 {
|
||||||
//If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer.
|
// If the data buffer's last character is a U+000A LINE FEED (LF) character,
|
||||||
|
// then remove the last character from the data buffer.
|
||||||
data = data[:dataLength-1]
|
data = data[:dataLength-1]
|
||||||
dataLength--
|
dataLength--
|
||||||
}
|
}
|
||||||
@@ -37,13 +37,13 @@ func (d *decoder) dispatchEvent(event Event, data string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *decoder) decode(r io.Reader) ([]Event, error) {
|
func (d *decoder) decode(r io.Reader) ([]Event, error) {
|
||||||
buf, err := ioutil.ReadAll(r)
|
buf, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentEvent Event
|
var currentEvent Event
|
||||||
var dataBuffer *bytes.Buffer = new(bytes.Buffer)
|
dataBuffer := new(bytes.Buffer)
|
||||||
// TODO (and unit tests)
|
// TODO (and unit tests)
|
||||||
// Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair,
|
// Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair,
|
||||||
// a single U+000A LINE FEED (LF) character,
|
// a single U+000A LINE FEED (LF) character,
|
||||||
@@ -96,7 +96,8 @@ func (d *decoder) decode(r io.Reader) ([]Event, error) {
|
|||||||
currentEvent.Id = string(value)
|
currentEvent.Id = string(value)
|
||||||
case "retry":
|
case "retry":
|
||||||
// If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
|
// If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
|
||||||
// then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer.
|
// then interpret the field value as an integer in base ten, and set the event stream's
|
||||||
|
// reconnection time to that integer.
|
||||||
// Otherwise, ignore the field.
|
// Otherwise, ignore the field.
|
||||||
currentEvent.Id = string(value)
|
currentEvent.Id = string(value)
|
||||||
case "data":
|
case "data":
|
||||||
@@ -105,7 +106,7 @@ func (d *decoder) decode(r io.Reader) ([]Event, error) {
|
|||||||
// then append a single U+000A LINE FEED (LF) character to the data buffer.
|
// then append a single U+000A LINE FEED (LF) character to the data buffer.
|
||||||
dataBuffer.WriteString("\n")
|
dataBuffer.WriteString("\n")
|
||||||
default:
|
default:
|
||||||
//Otherwise. The field is ignored.
|
// Otherwise. The field is ignored.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-16
@@ -20,8 +20,10 @@ import (
|
|||||||
|
|
||||||
const ContentType = "text/event-stream;charset=utf-8"
|
const ContentType = "text/event-stream;charset=utf-8"
|
||||||
|
|
||||||
var contentType = []string{ContentType}
|
var (
|
||||||
var noCache = []string{"no-cache"}
|
contentType = []string{ContentType}
|
||||||
|
noCache = []string{"no-cache"}
|
||||||
|
)
|
||||||
|
|
||||||
var fieldReplacer = strings.NewReplacer(
|
var fieldReplacer = strings.NewReplacer(
|
||||||
"\n", "\\n",
|
"\n", "\\n",
|
||||||
@@ -48,40 +50,48 @@ func Encode(writer io.Writer, event Event) error {
|
|||||||
|
|
||||||
func writeId(w stringWriter, id string) {
|
func writeId(w stringWriter, id string) {
|
||||||
if len(id) > 0 {
|
if len(id) > 0 {
|
||||||
w.WriteString("id:")
|
_, _ = w.WriteString("id:")
|
||||||
fieldReplacer.WriteString(w, id)
|
_, _ = fieldReplacer.WriteString(w, id)
|
||||||
w.WriteString("\n")
|
_, _ = w.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeEvent(w stringWriter, event string) {
|
func writeEvent(w stringWriter, event string) {
|
||||||
if len(event) > 0 {
|
if len(event) > 0 {
|
||||||
w.WriteString("event:")
|
_, _ = w.WriteString("event:")
|
||||||
fieldReplacer.WriteString(w, event)
|
_, _ = fieldReplacer.WriteString(w, event)
|
||||||
w.WriteString("\n")
|
_, _ = w.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeRetry(w stringWriter, retry uint) {
|
func writeRetry(w stringWriter, retry uint) {
|
||||||
if retry > 0 {
|
if retry > 0 {
|
||||||
w.WriteString("retry:")
|
_, _ = w.WriteString("retry:")
|
||||||
w.WriteString(strconv.FormatUint(uint64(retry), 10))
|
_, _ = w.WriteString(strconv.FormatUint(uint64(retry), 10))
|
||||||
w.WriteString("\n")
|
_, _ = w.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeData(w stringWriter, data interface{}) error {
|
func writeData(w stringWriter, data interface{}) error {
|
||||||
w.WriteString("data:")
|
_, _ = w.WriteString("data:")
|
||||||
switch kindOfData(data) {
|
|
||||||
|
bData, ok := data.([]byte)
|
||||||
|
if ok {
|
||||||
|
_, _ = dataReplacer.WriteString(w, string(bData))
|
||||||
|
_, _ = w.WriteString("\n\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch kindOfData(data) { //nolint:exhaustive
|
||||||
case reflect.Struct, reflect.Slice, reflect.Map:
|
case reflect.Struct, reflect.Slice, reflect.Map:
|
||||||
err := json.NewEncoder(w).Encode(data)
|
err := json.NewEncoder(w).Encode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.WriteString("\n")
|
_, _ = w.WriteString("\n")
|
||||||
default:
|
default:
|
||||||
dataReplacer.WriteString(w, fmt.Sprint(data))
|
_, _ = dataReplacer.WriteString(w, fmt.Sprint(data))
|
||||||
w.WriteString("\n\n")
|
_, _ = w.WriteString("\n\n")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -170,22 +170,25 @@ func TestEncodeFloat(t *testing.T) {
|
|||||||
func TestEncodeStream(t *testing.T) {
|
func TestEncodeStream(t *testing.T) {
|
||||||
w := new(bytes.Buffer)
|
w := new(bytes.Buffer)
|
||||||
|
|
||||||
Encode(w, Event{
|
_ = Encode(w, Event{
|
||||||
Event: "float",
|
Event: "float",
|
||||||
Data: 1.5,
|
Data: 1.5,
|
||||||
})
|
})
|
||||||
|
|
||||||
Encode(w, Event{
|
_ = Encode(w, Event{
|
||||||
Id: "123",
|
Id: "123",
|
||||||
Data: map[string]interface{}{"foo": "bar", "bar": "foo"},
|
Data: map[string]interface{}{"foo": "bar", "bar": "foo"},
|
||||||
})
|
})
|
||||||
|
|
||||||
Encode(w, Event{
|
_ = Encode(w, Event{
|
||||||
Id: "124",
|
Id: "124",
|
||||||
Event: "chat",
|
Event: "chat",
|
||||||
Data: "hi! dude",
|
Data: "hi! dude",
|
||||||
})
|
})
|
||||||
assert.Equal(t, w.String(), "event:float\ndata:1.5\n\nid:123\ndata:{\"bar\":\"foo\",\"foo\":\"bar\"}\n\nid:124\nevent:chat\ndata:hi! dude\n\n")
|
assert.Equal(t, w.String(),
|
||||||
|
"event:float\ndata:1.5\n\n"+
|
||||||
|
"id:123\ndata:{\"bar\":\"foo\",\"foo\":\"bar\"}\n\n"+
|
||||||
|
"id:124\nevent:chat\ndata:hi! dude\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenderSSE(t *testing.T) {
|
func TestRenderSSE(t *testing.T) {
|
||||||
@@ -207,7 +210,7 @@ func BenchmarkResponseWriter(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
(Event{
|
_ = (Event{
|
||||||
Event: "new_message",
|
Event: "new_message",
|
||||||
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
||||||
}).Render(w)
|
}).Render(w)
|
||||||
@@ -219,7 +222,7 @@ func BenchmarkFullSSE(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Encode(buf, Event{
|
_ = Encode(buf, Event{
|
||||||
Event: "new_message",
|
Event: "new_message",
|
||||||
Id: "13435",
|
Id: "13435",
|
||||||
Retry: 10,
|
Retry: 10,
|
||||||
@@ -234,7 +237,7 @@ func BenchmarkNoRetrySSE(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Encode(buf, Event{
|
_ = Encode(buf, Event{
|
||||||
Event: "new_message",
|
Event: "new_message",
|
||||||
Id: "13435",
|
Id: "13435",
|
||||||
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
||||||
@@ -248,7 +251,7 @@ func BenchmarkSimpleSSE(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Encode(buf, Event{
|
_ = Encode(buf, Event{
|
||||||
Event: "new_message",
|
Event: "new_message",
|
||||||
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
Data: "hi! how are you? I am fine. this is a long stupid message!!!",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type stringWrapper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w stringWrapper) WriteString(str string) (int, error) {
|
func (w stringWrapper) WriteString(str string) (int, error) {
|
||||||
return w.Writer.Write([]byte(str))
|
return w.Write([]byte(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkWriter(writer io.Writer) stringWriter {
|
func checkWriter(writer io.Writer) stringWriter {
|
||||||
|
|||||||
Reference in New Issue
Block a user