mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-24 19:52:03 -08:00
Update vendor
This commit is contained in:
parent
be15cc8a36
commit
07fd825349
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package logrus
|
||||||
|
|
||||||
|
// The following code was sourced and modified from the
|
||||||
|
// https://github.com/tebeka/atexit package governed by the following license:
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var handlers = []func(){}
|
||||||
|
|
||||||
|
func runHandler(handler func()) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
handler()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runHandlers() {
|
||||||
|
for _, handler := range handlers {
|
||||||
|
runHandler(handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
||||||
|
func Exit(code int) {
|
||||||
|
runHandlers()
|
||||||
|
os.Exit(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
|
||||||
|
// all handlers. The handlers will also be invoked when any Fatal log entry is
|
||||||
|
// made.
|
||||||
|
//
|
||||||
|
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||||
|
// message but also needs to gracefully shutdown. An example usecase could be
|
||||||
|
// closing database connections, or sending a alert that the application is
|
||||||
|
// closing.
|
||||||
|
func RegisterExitHandler(handler func()) {
|
||||||
|
handlers = append(handlers, handler)
|
||||||
|
}
|
51
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
51
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
@ -3,11 +3,21 @@ package logrus
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var bufferPool *sync.Pool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
bufferPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return new(bytes.Buffer)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Defines the key when adding errors using WithError.
|
// Defines the key when adding errors using WithError.
|
||||||
var ErrorKey = "error"
|
var ErrorKey = "error"
|
||||||
|
|
||||||
@ -29,6 +39,9 @@ type Entry struct {
|
|||||||
|
|
||||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||||
Message string
|
Message string
|
||||||
|
|
||||||
|
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||||
|
Buffer *bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEntry(logger *Logger) *Entry {
|
func NewEntry(logger *Logger) *Entry {
|
||||||
@ -39,21 +52,15 @@ func NewEntry(logger *Logger) *Entry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a reader for the entry, which is a proxy to the formatter.
|
|
||||||
func (entry *Entry) Reader() (*bytes.Buffer, error) {
|
|
||||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
|
||||||
return bytes.NewBuffer(serialized), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the string representation from the reader and ultimately the
|
// Returns the string representation from the reader and ultimately the
|
||||||
// formatter.
|
// formatter.
|
||||||
func (entry *Entry) String() (string, error) {
|
func (entry *Entry) String() (string, error) {
|
||||||
reader, err := entry.Reader()
|
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
str := string(serialized)
|
||||||
return reader.String(), err
|
return str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||||
@ -81,6 +88,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
|||||||
// This function is not declared with a pointer value because otherwise
|
// This function is not declared with a pointer value because otherwise
|
||||||
// race conditions will occur when using multiple goroutines
|
// race conditions will occur when using multiple goroutines
|
||||||
func (entry Entry) log(level Level, msg string) {
|
func (entry Entry) log(level Level, msg string) {
|
||||||
|
var buffer *bytes.Buffer
|
||||||
entry.Time = time.Now()
|
entry.Time = time.Now()
|
||||||
entry.Level = level
|
entry.Level = level
|
||||||
entry.Message = msg
|
entry.Message = msg
|
||||||
@ -90,21 +98,24 @@ func (entry Entry) log(level Level, msg string) {
|
|||||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||||
entry.Logger.mu.Unlock()
|
entry.Logger.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||||
reader, err := entry.Reader()
|
buffer.Reset()
|
||||||
|
defer bufferPool.Put(buffer)
|
||||||
|
entry.Buffer = buffer
|
||||||
|
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||||
|
entry.Buffer = nil
|
||||||
if err != nil {
|
if err != nil {
|
||||||
entry.Logger.mu.Lock()
|
entry.Logger.mu.Lock()
|
||||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||||
entry.Logger.mu.Unlock()
|
entry.Logger.mu.Unlock()
|
||||||
}
|
} else {
|
||||||
|
|
||||||
entry.Logger.mu.Lock()
|
entry.Logger.mu.Lock()
|
||||||
defer entry.Logger.mu.Unlock()
|
_, err = entry.Logger.Out.Write(serialized)
|
||||||
|
|
||||||
_, err = io.Copy(entry.Logger.Out, reader)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||||
}
|
}
|
||||||
|
entry.Logger.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// To avoid Entry#log() returning a value that only would make sense for
|
// To avoid Entry#log() returning a value that only would make sense for
|
||||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||||
@ -150,7 +161,7 @@ func (entry *Entry) Fatal(args ...interface{}) {
|
|||||||
if entry.Logger.Level >= FatalLevel {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panic(args ...interface{}) {
|
func (entry *Entry) Panic(args ...interface{}) {
|
||||||
@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
|||||||
if entry.Logger.Level >= FatalLevel {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.Fatal(fmt.Sprintf(format, args...))
|
entry.Fatal(fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||||
@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
|
|||||||
if entry.Logger.Level >= FatalLevel {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.Fatal(entry.sprintlnn(args...))
|
entry.Fatal(entry.sprintlnn(args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicln(args ...interface{}) {
|
func (entry *Entry) Panicln(args ...interface{}) {
|
||||||
|
9
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
9
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
// "os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logrus.New()
|
var log = logrus.New()
|
||||||
@ -9,6 +10,14 @@ var log = logrus.New()
|
|||||||
func init() {
|
func init() {
|
||||||
log.Formatter = new(logrus.JSONFormatter)
|
log.Formatter = new(logrus.JSONFormatter)
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
log.Formatter = new(logrus.TextFormatter) // default
|
||||||
|
|
||||||
|
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||||
|
// if err == nil {
|
||||||
|
// log.Out = file
|
||||||
|
// } else {
|
||||||
|
// log.Info("Failed to log to file, using default stderr")
|
||||||
|
// }
|
||||||
|
|
||||||
log.Level = logrus.DebugLevel
|
log.Level = logrus.DebugLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
15
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
@ -31,18 +31,15 @@ type Formatter interface {
|
|||||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||||
// avoid code duplication between the two default formatters.
|
// avoid code duplication between the two default formatters.
|
||||||
func prefixFieldClashes(data Fields) {
|
func prefixFieldClashes(data Fields) {
|
||||||
_, ok := data["time"]
|
if t, ok := data["time"]; ok {
|
||||||
if ok {
|
data["fields.time"] = t
|
||||||
data["fields.time"] = data["time"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok = data["msg"]
|
if m, ok := data["msg"]; ok {
|
||||||
if ok {
|
data["fields.msg"] = m
|
||||||
data["fields.msg"] = data["msg"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok = data["level"]
|
if l, ok := data["level"]; ok {
|
||||||
if ok {
|
data["fields.level"] = l
|
||||||
data["fields.level"] = data["level"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
61
vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
package logstash
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Formatter generates json in logstash format.
|
|
||||||
// Logstash site: http://logstash.net/
|
|
||||||
type LogstashFormatter struct {
|
|
||||||
Type string // if not empty use for logstash type field.
|
|
||||||
|
|
||||||
// TimestampFormat sets the format used for timestamps.
|
|
||||||
TimestampFormat string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
|
||||||
fields := make(logrus.Fields)
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
fields[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
fields["@version"] = 1
|
|
||||||
|
|
||||||
if f.TimestampFormat == "" {
|
|
||||||
f.TimestampFormat = logrus.DefaultTimestampFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
fields["@timestamp"] = entry.Time.Format(f.TimestampFormat)
|
|
||||||
|
|
||||||
// set message field
|
|
||||||
v, ok := entry.Data["message"]
|
|
||||||
if ok {
|
|
||||||
fields["fields.message"] = v
|
|
||||||
}
|
|
||||||
fields["message"] = entry.Message
|
|
||||||
|
|
||||||
// set level field
|
|
||||||
v, ok = entry.Data["level"]
|
|
||||||
if ok {
|
|
||||||
fields["fields.level"] = v
|
|
||||||
}
|
|
||||||
fields["level"] = entry.Level.String()
|
|
||||||
|
|
||||||
// set type field
|
|
||||||
if f.Type != "" {
|
|
||||||
v, ok = entry.Data["type"]
|
|
||||||
if ok {
|
|
||||||
fields["fields.type"] = v
|
|
||||||
}
|
|
||||||
fields["type"] = f.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
serialized, err := json.Marshal(fields)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
|
||||||
}
|
|
||||||
return append(serialized, '\n'), nil
|
|
||||||
}
|
|
39
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
39
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
@ -5,9 +5,40 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type fieldKey string
|
||||||
|
type FieldMap map[fieldKey]string
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldKeyMsg = "msg"
|
||||||
|
FieldKeyLevel = "level"
|
||||||
|
FieldKeyTime = "time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f FieldMap) resolve(key fieldKey) string {
|
||||||
|
if k, ok := f[key]; ok {
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(key)
|
||||||
|
}
|
||||||
|
|
||||||
type JSONFormatter struct {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
TimestampFormat string
|
TimestampFormat string
|
||||||
|
|
||||||
|
// DisableTimestamp allows disabling automatic timestamps in output
|
||||||
|
DisableTimestamp bool
|
||||||
|
|
||||||
|
// FieldMap allows users to customize the names of keys for various fields.
|
||||||
|
// As an example:
|
||||||
|
// formatter := &JSONFormatter{
|
||||||
|
// FieldMap: FieldMap{
|
||||||
|
// FieldKeyTime: "@timestamp",
|
||||||
|
// FieldKeyLevel: "@level",
|
||||||
|
// FieldKeyLevel: "@message",
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
FieldMap FieldMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
@ -29,9 +60,11 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = DefaultTimestampFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
data["time"] = entry.Time.Format(timestampFormat)
|
if !f.DisableTimestamp {
|
||||||
data["msg"] = entry.Message
|
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||||
data["level"] = entry.Level.String()
|
}
|
||||||
|
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||||
|
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||||
|
|
||||||
serialized, err := json.Marshal(data)
|
serialized, err := json.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
162
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
162
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
@ -26,8 +26,31 @@ type Logger struct {
|
|||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged. `logrus.Debug` is useful in
|
// logged. `logrus.Debug` is useful in
|
||||||
Level Level
|
Level Level
|
||||||
// Used to sync writing to the log.
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu sync.Mutex
|
mu MutexWrap
|
||||||
|
// Reusable empty entry
|
||||||
|
entryPool sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
type MutexWrap struct {
|
||||||
|
lock sync.Mutex
|
||||||
|
disabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw *MutexWrap) Lock() {
|
||||||
|
if !mw.disabled {
|
||||||
|
mw.lock.Lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw *MutexWrap) Unlock() {
|
||||||
|
if !mw.disabled {
|
||||||
|
mw.lock.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw *MutexWrap) Disable() {
|
||||||
|
mw.disabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||||
@ -51,162 +74,235 @@ func New() *Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a field to the log entry, note that you it doesn't log until you call
|
func (logger *Logger) newEntry() *Entry {
|
||||||
|
entry, ok := logger.entryPool.Get().(*Entry)
|
||||||
|
if ok {
|
||||||
|
return entry
|
||||||
|
}
|
||||||
|
return NewEntry(logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||||
|
logger.entryPool.Put(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a field to the log entry, note that it doesn't log until you call
|
||||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||||
// If you want multiple fields, use `WithFields`.
|
// If you want multiple fields, use `WithFields`.
|
||||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||||
return NewEntry(logger).WithField(key, value)
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
return entry.WithField(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||||
// each `Field`.
|
// each `Field`.
|
||||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||||
return NewEntry(logger).WithFields(fields)
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
return entry.WithFields(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an error as single field to the log entry. All it does is call
|
// Add an error as single field to the log entry. All it does is call
|
||||||
// `WithError` for the given `error`.
|
// `WithError` for the given `error`.
|
||||||
func (logger *Logger) WithError(err error) *Entry {
|
func (logger *Logger) WithError(err error) *Entry {
|
||||||
return NewEntry(logger).WithError(err)
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
return entry.WithError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
if logger.Level >= DebugLevel {
|
||||||
NewEntry(logger).Debugf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Debugf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
if logger.Level >= InfoLevel {
|
||||||
NewEntry(logger).Infof(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Infof(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||||
NewEntry(logger).Printf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Printf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
if logger.Level >= ErrorLevel {
|
||||||
NewEntry(logger).Errorf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Errorf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
if logger.Level >= FatalLevel {
|
||||||
NewEntry(logger).Fatalf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Fatalf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
if logger.Level >= PanicLevel {
|
||||||
NewEntry(logger).Panicf(format, args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Panicf(format, args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debug(args ...interface{}) {
|
func (logger *Logger) Debug(args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
if logger.Level >= DebugLevel {
|
||||||
NewEntry(logger).Debug(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Debug(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Info(args ...interface{}) {
|
func (logger *Logger) Info(args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
if logger.Level >= InfoLevel {
|
||||||
NewEntry(logger).Info(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Info(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Print(args ...interface{}) {
|
func (logger *Logger) Print(args ...interface{}) {
|
||||||
NewEntry(logger).Info(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Info(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warn(args ...interface{}) {
|
func (logger *Logger) Warn(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warn(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warn(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warning(args ...interface{}) {
|
func (logger *Logger) Warning(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warn(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warn(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Error(args ...interface{}) {
|
func (logger *Logger) Error(args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
if logger.Level >= ErrorLevel {
|
||||||
NewEntry(logger).Error(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Error(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatal(args ...interface{}) {
|
func (logger *Logger) Fatal(args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
if logger.Level >= FatalLevel {
|
||||||
NewEntry(logger).Fatal(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Fatal(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panic(args ...interface{}) {
|
func (logger *Logger) Panic(args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
if logger.Level >= PanicLevel {
|
||||||
NewEntry(logger).Panic(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Panic(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debugln(args ...interface{}) {
|
func (logger *Logger) Debugln(args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
if logger.Level >= DebugLevel {
|
||||||
NewEntry(logger).Debugln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Debugln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Infoln(args ...interface{}) {
|
func (logger *Logger) Infoln(args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
if logger.Level >= InfoLevel {
|
||||||
NewEntry(logger).Infoln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Infoln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Println(args ...interface{}) {
|
func (logger *Logger) Println(args ...interface{}) {
|
||||||
NewEntry(logger).Println(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Println(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warnln(args ...interface{}) {
|
func (logger *Logger) Warnln(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warningln(args ...interface{}) {
|
func (logger *Logger) Warningln(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Errorln(args ...interface{}) {
|
func (logger *Logger) Errorln(args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
if logger.Level >= ErrorLevel {
|
||||||
NewEntry(logger).Errorln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Errorln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
if logger.Level >= FatalLevel {
|
||||||
NewEntry(logger).Fatalln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Fatalln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panicln(args ...interface{}) {
|
func (logger *Logger) Panicln(args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
if logger.Level >= PanicLevel {
|
||||||
NewEntry(logger).Panicln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Panicln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//When file is opened with appending mode, it's safe to
|
||||||
|
//write concurrently to a file (within 4k message on Linux).
|
||||||
|
//In these cases user can choose to disable the lock.
|
||||||
|
func (logger *Logger) SetNoLock() {
|
||||||
|
logger.mu.Disable()
|
||||||
|
}
|
||||||
|
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||||
|
func IsTerminal(f io.Writer) bool {
|
||||||
|
return true
|
||||||
|
}
|
1
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
1
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
@ -1,4 +1,5 @@
|
|||||||
// +build darwin freebsd openbsd netbsd dragonfly
|
// +build darwin freebsd openbsd netbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
|
2
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
2
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
@ -3,6 +3,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
13
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
13
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
@ -4,18 +4,25 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
fd := syscall.Stderr
|
|
||||||
var termios Termios
|
var termios Termios
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
switch v := f.(type) {
|
||||||
|
case *os.File:
|
||||||
|
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||||
return err == 0
|
return err == 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
12
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
@ -1,15 +1,21 @@
|
|||||||
// +build solaris
|
// +build solaris,!appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
|
switch v := f.(type) {
|
||||||
|
case *os.File:
|
||||||
|
_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
|
||||||
return err == nil
|
return err == nil
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
14
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
@ -3,11 +3,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build windows
|
// +build windows,!appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -19,9 +21,13 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
fd := syscall.Stderr
|
switch v := f.(type) {
|
||||||
|
case *os.File:
|
||||||
var st uint32
|
var st uint32
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
|
||||||
return r != 0 && e == 0
|
return r != 0 && e == 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
78
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
78
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
@ -3,9 +3,9 @@ package logrus
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,16 +20,10 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
baseTimestamp time.Time
|
baseTimestamp time.Time
|
||||||
isTerminal bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
baseTimestamp = time.Now()
|
baseTimestamp = time.Now()
|
||||||
isTerminal = IsTerminal()
|
|
||||||
}
|
|
||||||
|
|
||||||
func miniTS() int {
|
|
||||||
return int(time.Since(baseTimestamp) / time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
@ -54,10 +48,32 @@ type TextFormatter struct {
|
|||||||
// that log extremely frequently and don't use the JSON formatter this may not
|
// that log extremely frequently and don't use the JSON formatter this may not
|
||||||
// be desired.
|
// be desired.
|
||||||
DisableSorting bool
|
DisableSorting bool
|
||||||
|
|
||||||
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
|
QuoteEmptyFields bool
|
||||||
|
|
||||||
|
// QuoteCharacter can be set to the override the default quoting character "
|
||||||
|
// with something else. For example: ', or `.
|
||||||
|
QuoteCharacter string
|
||||||
|
|
||||||
|
// Whether the logger's out is to a terminal
|
||||||
|
isTerminal bool
|
||||||
|
|
||||||
|
sync.Once
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) init(entry *Entry) {
|
||||||
|
if len(f.QuoteCharacter) == 0 {
|
||||||
|
f.QuoteCharacter = "\""
|
||||||
|
}
|
||||||
|
if entry.Logger != nil {
|
||||||
|
f.isTerminal = IsTerminal(entry.Logger.Out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
var keys []string = make([]string, 0, len(entry.Data))
|
var b *bytes.Buffer
|
||||||
|
keys := make([]string, 0, len(entry.Data))
|
||||||
for k := range entry.Data {
|
for k := range entry.Data {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
@ -65,13 +81,17 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
if !f.DisableSorting {
|
if !f.DisableSorting {
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
}
|
}
|
||||||
|
if entry.Buffer != nil {
|
||||||
b := &bytes.Buffer{}
|
b = entry.Buffer
|
||||||
|
} else {
|
||||||
|
b = &bytes.Buffer{}
|
||||||
|
}
|
||||||
|
|
||||||
prefixFieldClashes(entry.Data)
|
prefixFieldClashes(entry.Data)
|
||||||
|
|
||||||
isColorTerminal := isTerminal && (runtime.GOOS != "windows")
|
f.Do(func() { f.init(entry) })
|
||||||
isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
|
|
||||||
|
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
@ -111,51 +131,59 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
|||||||
|
|
||||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||||
|
|
||||||
if !f.FullTimestamp {
|
if f.DisableTimestamp {
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
|
||||||
|
} else if !f.FullTimestamp {
|
||||||
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||||
}
|
}
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
v := entry.Data[k]
|
v := entry.Data[k]
|
||||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v)
|
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||||
|
f.appendValue(b, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func needsQuoting(text string) bool {
|
func (f *TextFormatter) needsQuoting(text string) bool {
|
||||||
|
if f.QuoteEmptyFields && len(text) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
for _, ch := range text {
|
for _, ch := range text {
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
if !((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '-' || ch == '.') {
|
ch == '-' || ch == '.') {
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||||
|
|
||||||
b.WriteString(key)
|
b.WriteString(key)
|
||||||
b.WriteByte('=')
|
b.WriteByte('=')
|
||||||
|
f.appendValue(b, value)
|
||||||
|
b.WriteByte(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if needsQuoting(value) {
|
if !f.needsQuoting(value) {
|
||||||
b.WriteString(value)
|
b.WriteString(value)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%q", value)
|
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
||||||
}
|
}
|
||||||
case error:
|
case error:
|
||||||
errmsg := value.Error()
|
errmsg := value.Error()
|
||||||
if needsQuoting(errmsg) {
|
if !f.needsQuoting(errmsg) {
|
||||||
b.WriteString(errmsg)
|
b.WriteString(errmsg)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%q", value)
|
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt.Fprint(b, value)
|
fmt.Fprint(b, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
}
|
||||||
|
39
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
39
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
@ -7,21 +7,52 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (logger *Logger) Writer() *io.PipeWriter {
|
func (logger *Logger) Writer() *io.PipeWriter {
|
||||||
|
return logger.WriterLevel(InfoLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
||||||
|
return NewEntry(logger).WriterLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entry *Entry) Writer() *io.PipeWriter {
|
||||||
|
return entry.WriterLevel(InfoLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||||
reader, writer := io.Pipe()
|
reader, writer := io.Pipe()
|
||||||
|
|
||||||
go logger.writerScanner(reader)
|
var printFunc func(args ...interface{})
|
||||||
|
|
||||||
|
switch level {
|
||||||
|
case DebugLevel:
|
||||||
|
printFunc = entry.Debug
|
||||||
|
case InfoLevel:
|
||||||
|
printFunc = entry.Info
|
||||||
|
case WarnLevel:
|
||||||
|
printFunc = entry.Warn
|
||||||
|
case ErrorLevel:
|
||||||
|
printFunc = entry.Error
|
||||||
|
case FatalLevel:
|
||||||
|
printFunc = entry.Fatal
|
||||||
|
case PanicLevel:
|
||||||
|
printFunc = entry.Panic
|
||||||
|
default:
|
||||||
|
printFunc = entry.Print
|
||||||
|
}
|
||||||
|
|
||||||
|
go entry.writerScanner(reader, printFunc)
|
||||||
runtime.SetFinalizer(writer, writerFinalizer)
|
runtime.SetFinalizer(writer, writerFinalizer)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) writerScanner(reader *io.PipeReader) {
|
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
logger.Print(scanner.Text())
|
printFunc(scanner.Text())
|
||||||
}
|
}
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
logger.Errorf("Error while reading from Writer: %s", err)
|
entry.Errorf("Error while reading from Writer: %s", err)
|
||||||
}
|
}
|
||||||
reader.Close()
|
reader.Close()
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
generated
vendored
13
vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
generated
vendored
@ -23,6 +23,8 @@ import (
|
|||||||
type BotAPI struct {
|
type BotAPI struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
|
Buffer int `json:"buffer"`
|
||||||
|
|
||||||
Self User `json:"-"`
|
Self User `json:"-"`
|
||||||
Client *http.Client `json:"-"`
|
Client *http.Client `json:"-"`
|
||||||
}
|
}
|
||||||
@ -42,11 +44,12 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
|
|||||||
bot := &BotAPI{
|
bot := &BotAPI{
|
||||||
Token: token,
|
Token: token,
|
||||||
Client: client,
|
Client: client,
|
||||||
|
Buffer: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
self, err := bot.GetMe()
|
self, err := bot.GetMe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &BotAPI{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.Self = self
|
bot.Self = self
|
||||||
@ -68,6 +71,10 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse,
|
|||||||
return APIResponse{}, errors.New(ErrAPIForbidden)
|
return APIResponse{}, errors.New(ErrAPIForbidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return APIResponse{}, errors.New(http.StatusText(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
bytes, err := ioutil.ReadAll(resp.Body)
|
bytes, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIResponse{}, err
|
return APIResponse{}, err
|
||||||
@ -457,7 +464,7 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
|||||||
|
|
||||||
// GetUpdatesChan starts and returns a channel for getting updates.
|
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||||
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
||||||
ch := make(chan Update, 100)
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -484,7 +491,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
|||||||
|
|
||||||
// ListenForWebhook registers a http handler for a webhook.
|
// ListenForWebhook registers a http handler for a webhook.
|
||||||
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||||
ch := make(chan Update, 100)
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
bytes, _ := ioutil.ReadAll(r.Body)
|
bytes, _ := ioutil.ReadAll(r.Body)
|
||||||
|
15
vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
generated
vendored
15
vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
generated
vendored
@ -318,21 +318,6 @@ func NewWebhookWithCert(link string, file interface{}) WebhookConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWebhookWithCert creates a new webhook with a certificate and max_connections.
|
|
||||||
//
|
|
||||||
// link is the url you wish to get webhooks,
|
|
||||||
// file contains a string to a file, FileReader, or FileBytes.
|
|
||||||
// maxConnections defines maximum number of connections from telegram to your server
|
|
||||||
func NewWebhookWithCertAndMaxConnections(link string, file interface{}, maxConnections int) WebhookConfig {
|
|
||||||
u, _ := url.Parse(link)
|
|
||||||
|
|
||||||
return WebhookConfig{
|
|
||||||
URL: u,
|
|
||||||
Certificate: file,
|
|
||||||
MaxConnections: maxConnections,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInlineQueryResultArticle creates a new inline query article.
|
// NewInlineQueryResultArticle creates a new inline query article.
|
||||||
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
||||||
return InlineQueryResultArticle{
|
return InlineQueryResultArticle{
|
||||||
|
2
vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
generated
vendored
2
vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
generated
vendored
@ -194,7 +194,7 @@ func (m *Message) CommandArguments() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.SplitN(m.Text, " ", 2)[1]
|
return split[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageEntity contains information about data in a Message.
|
// MessageEntity contains information about data in a Message.
|
||||||
|
47
vendor/github.com/gorilla/schema/cache.go
generated
vendored
47
vendor/github.com/gorilla/schema/cache.go
generated
vendored
@ -138,7 +138,12 @@ func (c *cache) create(t reflect.Type, info *structInfo) *structInfo {
|
|||||||
ft = ft.Elem()
|
ft = ft.Elem()
|
||||||
}
|
}
|
||||||
if ft.Kind() == reflect.Struct {
|
if ft.Kind() == reflect.Struct {
|
||||||
|
bef := len(info.fields)
|
||||||
c.create(ft, info)
|
c.create(ft, info)
|
||||||
|
for _, fi := range info.fields[bef:len(info.fields)] {
|
||||||
|
// exclude required check because duplicated to embedded field
|
||||||
|
fi.required = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.createField(field, info)
|
c.createField(field, info)
|
||||||
@ -148,7 +153,7 @@ func (c *cache) create(t reflect.Type, info *structInfo) *structInfo {
|
|||||||
|
|
||||||
// createField creates a fieldInfo for the given field.
|
// createField creates a fieldInfo for the given field.
|
||||||
func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
||||||
alias := fieldAlias(field, c.tag)
|
alias, options := fieldAlias(field, c.tag)
|
||||||
if alias == "-" {
|
if alias == "-" {
|
||||||
// Ignore this field.
|
// Ignore this field.
|
||||||
return
|
return
|
||||||
@ -173,7 +178,7 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isStruct = ft.Kind() == reflect.Struct; !isStruct {
|
if isStruct = ft.Kind() == reflect.Struct; !isStruct {
|
||||||
if conv := c.conv[ft.Kind()]; conv == nil {
|
if conv := c.converter(ft); conv == nil {
|
||||||
// Type is not supported.
|
// Type is not supported.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -184,6 +189,8 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
|||||||
name: field.Name,
|
name: field.Name,
|
||||||
ss: isSlice && isStruct,
|
ss: isSlice && isStruct,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
|
anon: field.Anonymous,
|
||||||
|
required: options.Contains("required"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +223,8 @@ type fieldInfo struct {
|
|||||||
name string // field name in the struct.
|
name string // field name in the struct.
|
||||||
ss bool // true if this is a slice of structs.
|
ss bool // true if this is a slice of structs.
|
||||||
alias string
|
alias string
|
||||||
|
anon bool // is an embedded field
|
||||||
|
required bool // tag option
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathPart struct {
|
type pathPart struct {
|
||||||
@ -227,19 +236,33 @@ type pathPart struct {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// fieldAlias parses a field tag to get a field alias.
|
// fieldAlias parses a field tag to get a field alias.
|
||||||
func fieldAlias(field reflect.StructField, tagName string) string {
|
func fieldAlias(field reflect.StructField, tagName string) (alias string, options tagOptions) {
|
||||||
var alias string
|
|
||||||
if tag := field.Tag.Get(tagName); tag != "" {
|
if tag := field.Tag.Get(tagName); tag != "" {
|
||||||
// For now tags only support the name but let's follow the
|
alias, options = parseTag(tag)
|
||||||
// comma convention from encoding/json and others.
|
|
||||||
if idx := strings.Index(tag, ","); idx == -1 {
|
|
||||||
alias = tag
|
|
||||||
} else {
|
|
||||||
alias = tag[:idx]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if alias == "" {
|
if alias == "" {
|
||||||
alias = field.Name
|
alias = field.Name
|
||||||
}
|
}
|
||||||
return alias
|
return alias, options
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagOptions is the string following a comma in a struct field's tag, or
|
||||||
|
// the empty string. It does not include the leading comma.
|
||||||
|
type tagOptions []string
|
||||||
|
|
||||||
|
// parseTag splits a struct field's url tag into its name and comma-separated
|
||||||
|
// options.
|
||||||
|
func parseTag(tag string) (string, tagOptions) {
|
||||||
|
s := strings.Split(tag, ",")
|
||||||
|
return s[0], s[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains checks whether the tagOptions contains the specified option.
|
||||||
|
func (o tagOptions) Contains(option string) bool {
|
||||||
|
for _, s := range o {
|
||||||
|
if s == option {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
51
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
51
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
@ -87,9 +87,60 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
|
|||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
return d.checkRequired(t, src, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkRequired checks whether requred field empty
|
||||||
|
//
|
||||||
|
// check type t recursively if t has struct fields, and prefix is same as parsePath: in dotted notation
|
||||||
|
//
|
||||||
|
// src is the source map for decoding, we use it here to see if those required fields are included in src
|
||||||
|
func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix string) error {
|
||||||
|
struc := d.cache.get(t)
|
||||||
|
if struc == nil {
|
||||||
|
// unexpect, cache.get never return nil
|
||||||
|
return errors.New("cache fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range struc.fields {
|
||||||
|
if f.typ.Kind() == reflect.Struct {
|
||||||
|
err := d.checkRequired(f.typ, src, prefix+f.alias+".")
|
||||||
|
if err != nil {
|
||||||
|
if !f.anon {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check embedded parent field.
|
||||||
|
err2 := d.checkRequired(f.typ, src, prefix)
|
||||||
|
if err2 != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f.required {
|
||||||
|
key := f.alias
|
||||||
|
if prefix != "" {
|
||||||
|
key = prefix + key
|
||||||
|
}
|
||||||
|
if isEmpty(f.typ, src[key]) {
|
||||||
|
return fmt.Errorf("%v is empty", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isEmpty returns true if value is empty for specific type
|
||||||
|
func isEmpty(t reflect.Type, value []string) bool {
|
||||||
|
if len(value) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch t.Kind() {
|
||||||
|
case boolType, float32Type, float64Type, intType, int8Type, int32Type, int64Type, stringType, uint8Type, uint16Type, uint32Type, uint64Type:
|
||||||
|
return len(value[0]) == 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// decode fills a struct field using a parsed path.
|
// decode fills a struct field using a parsed path.
|
||||||
func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values []string) error {
|
func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values []string) error {
|
||||||
// Get the field walking the struct fields by index.
|
// Get the field walking the struct fields by index.
|
||||||
|
2
vendor/github.com/gorilla/schema/doc.go
generated
vendored
2
vendor/github.com/gorilla/schema/doc.go
generated
vendored
@ -12,7 +12,7 @@ The basic usage is really simple. Given this struct:
|
|||||||
Phone string
|
Phone string
|
||||||
}
|
}
|
||||||
|
|
||||||
...we can fill it passing a map to the Load() function:
|
...we can fill it passing a map to the Decode() function:
|
||||||
|
|
||||||
values := map[string][]string{
|
values := map[string][]string{
|
||||||
"Name": {"John"},
|
"Name": {"John"},
|
||||||
|
161
vendor/github.com/gorilla/schema/encoder.go
generated
vendored
Normal file
161
vendor/github.com/gorilla/schema/encoder.go
generated
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type encoderFunc func(reflect.Value) string
|
||||||
|
|
||||||
|
// Encoder encodes values from a struct into url.Values.
|
||||||
|
type Encoder struct {
|
||||||
|
cache *cache
|
||||||
|
regenc map[reflect.Type]encoderFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEncoder returns a new Encoder with defaults.
|
||||||
|
func NewEncoder() *Encoder {
|
||||||
|
return &Encoder{cache: newCache(), regenc: make(map[reflect.Type]encoderFunc)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes a struct into map[string][]string.
|
||||||
|
//
|
||||||
|
// Intended for use with url.Values.
|
||||||
|
func (e *Encoder) Encode(src interface{}, dst map[string][]string) error {
|
||||||
|
v := reflect.ValueOf(src)
|
||||||
|
|
||||||
|
return e.encode(v, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterEncoder registers a converter for encoding a custom type.
|
||||||
|
func (e *Encoder) RegisterEncoder(value interface{}, encoder func(reflect.Value) string) {
|
||||||
|
e.regenc[reflect.TypeOf(value)] = encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAliasTag changes the tag used to locate custom field aliases.
|
||||||
|
// The default tag is "schema".
|
||||||
|
func (e *Encoder) SetAliasTag(tag string) {
|
||||||
|
e.cache.tag = tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
|
||||||
|
if v.Kind() == reflect.Ptr {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return errors.New("schema: interface must be a struct")
|
||||||
|
}
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
errors := MultiError{}
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
name, opts := fieldAlias(t.Field(i), e.cache.tag)
|
||||||
|
if name == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Field(i).Type().Kind() == reflect.Struct {
|
||||||
|
e.encode(v.Field(i), dst)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
encFunc := typeEncoder(v.Field(i).Type(), e.regenc)
|
||||||
|
|
||||||
|
// Encode non-slice types and custom implementations immediately.
|
||||||
|
if encFunc != nil {
|
||||||
|
value := encFunc(v.Field(i))
|
||||||
|
if value == "" && opts.Contains("omitempty") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[name] = append(dst[name], value)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Field(i).Type().Kind() == reflect.Slice {
|
||||||
|
encFunc = typeEncoder(v.Field(i).Type().Elem(), e.regenc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if encFunc == nil {
|
||||||
|
errors[v.Field(i).Type().String()] = fmt.Errorf("schema: encoder not found for %v", v.Field(i))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a slice.
|
||||||
|
if v.Field(i).Len() == 0 && opts.Contains("omitempty") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[name] = []string{}
|
||||||
|
for j := 0; j < v.Field(i).Len(); j++ {
|
||||||
|
dst[name] = append(dst[name], encFunc(v.Field(i).Index(j)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func typeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) encoderFunc {
|
||||||
|
if f, ok := reg[t]; ok {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return encodeBool
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return encodeInt
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return encodeUint
|
||||||
|
case reflect.Float32:
|
||||||
|
return encodeFloat32
|
||||||
|
case reflect.Float64:
|
||||||
|
return encodeFloat64
|
||||||
|
case reflect.Ptr:
|
||||||
|
f := typeEncoder(t.Elem(), reg)
|
||||||
|
return func(v reflect.Value) string {
|
||||||
|
if v.IsNil() {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
return f(v.Elem())
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
return encodeString
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeBool(v reflect.Value) string {
|
||||||
|
return strconv.FormatBool(v.Bool())
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeInt(v reflect.Value) string {
|
||||||
|
return strconv.FormatInt(int64(v.Int()), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeUint(v reflect.Value) string {
|
||||||
|
return strconv.FormatUint(uint64(v.Uint()), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeFloat(v reflect.Value, bits int) string {
|
||||||
|
return strconv.FormatFloat(v.Float(), 'f', 6, bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeFloat32(v reflect.Value) string {
|
||||||
|
return encodeFloat(v, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeFloat64(v reflect.Value) string {
|
||||||
|
return encodeFloat(v, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeString(v reflect.Value) string {
|
||||||
|
return v.String()
|
||||||
|
}
|
60
vendor/github.com/gorilla/websocket/client.go
generated
vendored
60
vendor/github.com/gorilla/websocket/client.go
generated
vendored
@ -23,6 +23,8 @@ import (
|
|||||||
// invalid.
|
// invalid.
|
||||||
var ErrBadHandshake = errors.New("websocket: bad handshake")
|
var ErrBadHandshake = errors.New("websocket: bad handshake")
|
||||||
|
|
||||||
|
var errInvalidCompression = errors.New("websocket: invalid compression negotiation")
|
||||||
|
|
||||||
// NewClient creates a new client connection using the given net connection.
|
// NewClient creates a new client connection using the given net connection.
|
||||||
// The URL u specifies the host and request URI. Use requestHeader to specify
|
// The URL u specifies the host and request URI. Use requestHeader to specify
|
||||||
// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
|
// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
|
||||||
@ -64,12 +66,24 @@ type Dialer struct {
|
|||||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||||
HandshakeTimeout time.Duration
|
HandshakeTimeout time.Duration
|
||||||
|
|
||||||
// Input and output buffer sizes. If the buffer size is zero, then a
|
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
|
||||||
// default value of 4096 is used.
|
// size is zero, then a useful default size is used. The I/O buffer sizes
|
||||||
|
// do not limit the size of the messages that can be sent or received.
|
||||||
ReadBufferSize, WriteBufferSize int
|
ReadBufferSize, WriteBufferSize int
|
||||||
|
|
||||||
// Subprotocols specifies the client's requested subprotocols.
|
// Subprotocols specifies the client's requested subprotocols.
|
||||||
Subprotocols []string
|
Subprotocols []string
|
||||||
|
|
||||||
|
// EnableCompression specifies if the client should attempt to negotiate
|
||||||
|
// per message compression (RFC 7692). Setting this value to true does not
|
||||||
|
// guarantee that compression will be supported. Currently only "no context
|
||||||
|
// takeover" modes are supported.
|
||||||
|
EnableCompression bool
|
||||||
|
|
||||||
|
// Jar specifies the cookie jar.
|
||||||
|
// If Jar is nil, cookies are not sent in requests and ignored
|
||||||
|
// in responses.
|
||||||
|
Jar http.CookieJar
|
||||||
}
|
}
|
||||||
|
|
||||||
var errMalformedURL = errors.New("malformed ws or wss URL")
|
var errMalformedURL = errors.New("malformed ws or wss URL")
|
||||||
@ -83,7 +97,6 @@ func parseURL(s string) (*url.URL, error) {
|
|||||||
//
|
//
|
||||||
// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
|
// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
|
||||||
// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
|
// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
|
||||||
|
|
||||||
var u url.URL
|
var u url.URL
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(s, "ws://"):
|
case strings.HasPrefix(s, "ws://"):
|
||||||
@ -193,6 +206,13 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
Host: u.Host,
|
Host: u.Host,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the cookies present in the cookie jar of the dialer
|
||||||
|
if d.Jar != nil {
|
||||||
|
for _, cookie := range d.Jar.Cookies(u) {
|
||||||
|
req.AddCookie(cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the request headers using the capitalization for names and values in
|
// Set the request headers using the capitalization for names and values in
|
||||||
// RFC examples. Although the capitalization shouldn't matter, there are
|
// RFC examples. Although the capitalization shouldn't matter, there are
|
||||||
// servers that depend on it. The Header.Set method is not used because the
|
// servers that depend on it. The Header.Set method is not used because the
|
||||||
@ -214,6 +234,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
k == "Connection" ||
|
k == "Connection" ||
|
||||||
k == "Sec-Websocket-Key" ||
|
k == "Sec-Websocket-Key" ||
|
||||||
k == "Sec-Websocket-Version" ||
|
k == "Sec-Websocket-Version" ||
|
||||||
|
k == "Sec-Websocket-Extensions" ||
|
||||||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
|
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
|
||||||
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
|
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
|
||||||
default:
|
default:
|
||||||
@ -221,6 +242,10 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.EnableCompression {
|
||||||
|
req.Header.Set("Sec-Websocket-Extensions", "permessage-deflate; server_no_context_takeover; client_no_context_takeover")
|
||||||
|
}
|
||||||
|
|
||||||
hostPort, hostNoPort := hostPortNoPort(u)
|
hostPort, hostNoPort := hostPortNoPort(u)
|
||||||
|
|
||||||
var proxyURL *url.URL
|
var proxyURL *url.URL
|
||||||
@ -298,12 +323,8 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
if u.Scheme == "https" {
|
if u.Scheme == "https" {
|
||||||
cfg := d.TLSClientConfig
|
cfg := cloneTLSConfig(d.TLSClientConfig)
|
||||||
if cfg == nil {
|
if cfg.ServerName == "" {
|
||||||
cfg = &tls.Config{ServerName: hostNoPort}
|
|
||||||
} else if cfg.ServerName == "" {
|
|
||||||
shallowCopy := *cfg
|
|
||||||
cfg = &shallowCopy
|
|
||||||
cfg.ServerName = hostNoPort
|
cfg.ServerName = hostNoPort
|
||||||
}
|
}
|
||||||
tlsConn := tls.Client(netConn, cfg)
|
tlsConn := tls.Client(netConn, cfg)
|
||||||
@ -328,6 +349,13 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.Jar != nil {
|
||||||
|
if rc := resp.Cookies(); len(rc) > 0 {
|
||||||
|
d.Jar.SetCookies(u, rc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 101 ||
|
if resp.StatusCode != 101 ||
|
||||||
!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
|
!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
|
||||||
!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
|
!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
|
||||||
@ -341,6 +369,20 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
|
|||||||
return nil, resp, ErrBadHandshake
|
return nil, resp, ErrBadHandshake
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, ext := range parseExtensions(resp.Header) {
|
||||||
|
if ext[""] != "permessage-deflate" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, snct := ext["server_no_context_takeover"]
|
||||||
|
_, cnct := ext["client_no_context_takeover"]
|
||||||
|
if !snct || !cnct {
|
||||||
|
return nil, resp, errInvalidCompression
|
||||||
|
}
|
||||||
|
conn.newCompressionWriter = compressNoContextTakeover
|
||||||
|
conn.newDecompressionReader = decompressNoContextTakeover
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||||
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
||||||
|
|
||||||
|
16
vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
Normal file
16
vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import "crypto/tls"
|
||||||
|
|
||||||
|
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||||
|
if cfg == nil {
|
||||||
|
return &tls.Config{}
|
||||||
|
}
|
||||||
|
return cfg.Clone()
|
||||||
|
}
|
38
vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
Normal file
38
vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import "crypto/tls"
|
||||||
|
|
||||||
|
// cloneTLSConfig clones all public fields except the fields
|
||||||
|
// SessionTicketsDisabled and SessionTicketKey. This avoids copying the
|
||||||
|
// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a
|
||||||
|
// config in active use.
|
||||||
|
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||||
|
if cfg == nil {
|
||||||
|
return &tls.Config{}
|
||||||
|
}
|
||||||
|
return &tls.Config{
|
||||||
|
Rand: cfg.Rand,
|
||||||
|
Time: cfg.Time,
|
||||||
|
Certificates: cfg.Certificates,
|
||||||
|
NameToCertificate: cfg.NameToCertificate,
|
||||||
|
GetCertificate: cfg.GetCertificate,
|
||||||
|
RootCAs: cfg.RootCAs,
|
||||||
|
NextProtos: cfg.NextProtos,
|
||||||
|
ServerName: cfg.ServerName,
|
||||||
|
ClientAuth: cfg.ClientAuth,
|
||||||
|
ClientCAs: cfg.ClientCAs,
|
||||||
|
InsecureSkipVerify: cfg.InsecureSkipVerify,
|
||||||
|
CipherSuites: cfg.CipherSuites,
|
||||||
|
PreferServerCipherSuites: cfg.PreferServerCipherSuites,
|
||||||
|
ClientSessionCache: cfg.ClientSessionCache,
|
||||||
|
MinVersion: cfg.MinVersion,
|
||||||
|
MaxVersion: cfg.MaxVersion,
|
||||||
|
CurvePreferences: cfg.CurvePreferences,
|
||||||
|
}
|
||||||
|
}
|
148
vendor/github.com/gorilla/websocket/compression.go
generated
vendored
Normal file
148
vendor/github.com/gorilla/websocket/compression.go
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/flate"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6
|
||||||
|
maxCompressionLevel = flate.BestCompression
|
||||||
|
defaultCompressionLevel = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
|
||||||
|
flateReaderPool = sync.Pool{New: func() interface{} {
|
||||||
|
return flate.NewReader(nil)
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
|
func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
|
||||||
|
const tail =
|
||||||
|
// Add four bytes as specified in RFC
|
||||||
|
"\x00\x00\xff\xff" +
|
||||||
|
// Add final block to squelch unexpected EOF error from flate reader.
|
||||||
|
"\x01\x00\x00\xff\xff"
|
||||||
|
|
||||||
|
fr, _ := flateReaderPool.Get().(io.ReadCloser)
|
||||||
|
fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
|
||||||
|
return &flateReadWrapper{fr}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidCompressionLevel(level int) bool {
|
||||||
|
return minCompressionLevel <= level && level <= maxCompressionLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
|
||||||
|
p := &flateWriterPools[level-minCompressionLevel]
|
||||||
|
tw := &truncWriter{w: w}
|
||||||
|
fw, _ := p.Get().(*flate.Writer)
|
||||||
|
if fw == nil {
|
||||||
|
fw, _ = flate.NewWriter(tw, level)
|
||||||
|
} else {
|
||||||
|
fw.Reset(tw)
|
||||||
|
}
|
||||||
|
return &flateWriteWrapper{fw: fw, tw: tw, p: p}
|
||||||
|
}
|
||||||
|
|
||||||
|
// truncWriter is an io.Writer that writes all but the last four bytes of the
|
||||||
|
// stream to another io.Writer.
|
||||||
|
type truncWriter struct {
|
||||||
|
w io.WriteCloser
|
||||||
|
n int
|
||||||
|
p [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *truncWriter) Write(p []byte) (int, error) {
|
||||||
|
n := 0
|
||||||
|
|
||||||
|
// fill buffer first for simplicity.
|
||||||
|
if w.n < len(w.p) {
|
||||||
|
n = copy(w.p[w.n:], p)
|
||||||
|
p = p[n:]
|
||||||
|
w.n += n
|
||||||
|
if len(p) == 0 {
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m := len(p)
|
||||||
|
if m > len(w.p) {
|
||||||
|
m = len(w.p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nn, err := w.w.Write(w.p[:m]); err != nil {
|
||||||
|
return n + nn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(w.p[:], w.p[m:])
|
||||||
|
copy(w.p[len(w.p)-m:], p[len(p)-m:])
|
||||||
|
nn, err := w.w.Write(p[:len(p)-m])
|
||||||
|
return n + nn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type flateWriteWrapper struct {
|
||||||
|
fw *flate.Writer
|
||||||
|
tw *truncWriter
|
||||||
|
p *sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *flateWriteWrapper) Write(p []byte) (int, error) {
|
||||||
|
if w.fw == nil {
|
||||||
|
return 0, errWriteClosed
|
||||||
|
}
|
||||||
|
return w.fw.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *flateWriteWrapper) Close() error {
|
||||||
|
if w.fw == nil {
|
||||||
|
return errWriteClosed
|
||||||
|
}
|
||||||
|
err1 := w.fw.Flush()
|
||||||
|
w.p.Put(w.fw)
|
||||||
|
w.fw = nil
|
||||||
|
if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
|
||||||
|
return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
|
||||||
|
}
|
||||||
|
err2 := w.tw.w.Close()
|
||||||
|
if err1 != nil {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
type flateReadWrapper struct {
|
||||||
|
fr io.ReadCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *flateReadWrapper) Read(p []byte) (int, error) {
|
||||||
|
if r.fr == nil {
|
||||||
|
return 0, io.ErrClosedPipe
|
||||||
|
}
|
||||||
|
n, err := r.fr.Read(p)
|
||||||
|
if err == io.EOF {
|
||||||
|
// Preemptively place the reader back in the pool. This helps with
|
||||||
|
// scenarios where the application does not call NextReader() soon after
|
||||||
|
// this final read.
|
||||||
|
r.Close()
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *flateReadWrapper) Close() error {
|
||||||
|
if r.fr == nil {
|
||||||
|
return io.ErrClosedPipe
|
||||||
|
}
|
||||||
|
err := r.fr.Close()
|
||||||
|
flateReaderPool.Put(r.fr)
|
||||||
|
r.fr = nil
|
||||||
|
return err
|
||||||
|
}
|
612
vendor/github.com/gorilla/websocket/conn.go
generated
vendored
612
vendor/github.com/gorilla/websocket/conn.go
generated
vendored
@ -13,14 +13,24 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Frame header byte 0 bits from Section 5.2 of RFC 6455
|
||||||
|
finalBit = 1 << 7
|
||||||
|
rsv1Bit = 1 << 6
|
||||||
|
rsv2Bit = 1 << 5
|
||||||
|
rsv3Bit = 1 << 4
|
||||||
|
|
||||||
|
// Frame header byte 1 bits from Section 5.2 of RFC 6455
|
||||||
|
maskBit = 1 << 7
|
||||||
|
|
||||||
maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
|
maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
|
||||||
maxControlFramePayloadSize = 125
|
maxControlFramePayloadSize = 125
|
||||||
finalBit = 1 << 7
|
|
||||||
maskBit = 1 << 7
|
|
||||||
writeWait = time.Second
|
writeWait = time.Second
|
||||||
|
|
||||||
defaultReadBufferSize = 4096
|
defaultReadBufferSize = 4096
|
||||||
@ -43,6 +53,8 @@ const (
|
|||||||
CloseMessageTooBig = 1009
|
CloseMessageTooBig = 1009
|
||||||
CloseMandatoryExtension = 1010
|
CloseMandatoryExtension = 1010
|
||||||
CloseInternalServerErr = 1011
|
CloseInternalServerErr = 1011
|
||||||
|
CloseServiceRestart = 1012
|
||||||
|
CloseTryAgainLater = 1013
|
||||||
CloseTLSHandshake = 1015
|
CloseTLSHandshake = 1015
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -169,6 +181,11 @@ var (
|
|||||||
errInvalidControlFrame = errors.New("websocket: invalid control frame")
|
errInvalidControlFrame = errors.New("websocket: invalid control frame")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func newMaskKey() [4]byte {
|
||||||
|
n := rand.Uint32()
|
||||||
|
return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
|
||||||
|
}
|
||||||
|
|
||||||
func hideTempErr(err error) error {
|
func hideTempErr(err error) error {
|
||||||
if e, ok := err.(net.Error); ok && e.Temporary() {
|
if e, ok := err.(net.Error); ok && e.Temporary() {
|
||||||
err = &netError{msg: e.Error(), timeout: e.Timeout()}
|
err = &netError{msg: e.Error(), timeout: e.Timeout()}
|
||||||
@ -184,74 +201,138 @@ func isData(frameType int) bool {
|
|||||||
return frameType == TextMessage || frameType == BinaryMessage
|
return frameType == TextMessage || frameType == BinaryMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func maskBytes(key [4]byte, pos int, b []byte) int {
|
var validReceivedCloseCodes = map[int]bool{
|
||||||
for i := range b {
|
// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
|
||||||
b[i] ^= key[pos&3]
|
|
||||||
pos++
|
CloseNormalClosure: true,
|
||||||
}
|
CloseGoingAway: true,
|
||||||
return pos & 3
|
CloseProtocolError: true,
|
||||||
|
CloseUnsupportedData: true,
|
||||||
|
CloseNoStatusReceived: false,
|
||||||
|
CloseAbnormalClosure: false,
|
||||||
|
CloseInvalidFramePayloadData: true,
|
||||||
|
ClosePolicyViolation: true,
|
||||||
|
CloseMessageTooBig: true,
|
||||||
|
CloseMandatoryExtension: true,
|
||||||
|
CloseInternalServerErr: true,
|
||||||
|
CloseServiceRestart: true,
|
||||||
|
CloseTryAgainLater: true,
|
||||||
|
CloseTLSHandshake: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMaskKey() [4]byte {
|
func isValidReceivedCloseCode(code int) bool {
|
||||||
n := rand.Uint32()
|
return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
|
||||||
return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conn represents a WebSocket connection.
|
// The Conn type represents a WebSocket connection.
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
isServer bool
|
isServer bool
|
||||||
subprotocol string
|
subprotocol string
|
||||||
|
|
||||||
// Write fields
|
// Write fields
|
||||||
mu chan bool // used as mutex to protect write to conn and closeSent
|
mu chan bool // used as mutex to protect write to conn
|
||||||
closeSent bool // true if close message was sent
|
|
||||||
|
|
||||||
// Message writer fields.
|
|
||||||
writeErr error
|
|
||||||
writeBuf []byte // frame is constructed in this buffer.
|
writeBuf []byte // frame is constructed in this buffer.
|
||||||
writePos int // end of data in writeBuf.
|
|
||||||
writeFrameType int // type of the current frame.
|
|
||||||
writeSeq int // incremented to invalidate message writers.
|
|
||||||
writeDeadline time.Time
|
writeDeadline time.Time
|
||||||
|
writer io.WriteCloser // the current writer returned to the application
|
||||||
isWriting bool // for best-effort concurrent write detection
|
isWriting bool // for best-effort concurrent write detection
|
||||||
|
|
||||||
|
writeErrMu sync.Mutex
|
||||||
|
writeErr error
|
||||||
|
|
||||||
|
enableWriteCompression bool
|
||||||
|
compressionLevel int
|
||||||
|
newCompressionWriter func(io.WriteCloser, int) io.WriteCloser
|
||||||
|
|
||||||
// Read fields
|
// Read fields
|
||||||
|
reader io.ReadCloser // the current reader returned to the application
|
||||||
readErr error
|
readErr error
|
||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
readRemaining int64 // bytes remaining in current frame.
|
readRemaining int64 // bytes remaining in current frame.
|
||||||
readFinal bool // true the current message has more frames.
|
readFinal bool // true the current message has more frames.
|
||||||
readSeq int // incremented to invalidate message readers.
|
|
||||||
readLength int64 // Message size.
|
readLength int64 // Message size.
|
||||||
readLimit int64 // Maximum message size.
|
readLimit int64 // Maximum message size.
|
||||||
readMaskPos int
|
readMaskPos int
|
||||||
readMaskKey [4]byte
|
readMaskKey [4]byte
|
||||||
handlePong func(string) error
|
handlePong func(string) error
|
||||||
handlePing func(string) error
|
handlePing func(string) error
|
||||||
|
handleClose func(int, string) error
|
||||||
readErrCount int
|
readErrCount int
|
||||||
|
messageReader *messageReader // the current low-level reader
|
||||||
|
|
||||||
|
readDecompress bool // whether last read frame had RSV1 set
|
||||||
|
newDecompressionReader func(io.Reader) io.ReadCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
|
func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
|
||||||
|
return newConnBRW(conn, isServer, readBufferSize, writeBufferSize, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type writeHook struct {
|
||||||
|
p []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wh *writeHook) Write(p []byte) (int, error) {
|
||||||
|
wh.p = p
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, brw *bufio.ReadWriter) *Conn {
|
||||||
mu := make(chan bool, 1)
|
mu := make(chan bool, 1)
|
||||||
mu <- true
|
mu <- true
|
||||||
|
|
||||||
|
var br *bufio.Reader
|
||||||
|
if readBufferSize == 0 && brw != nil && brw.Reader != nil {
|
||||||
|
// Reuse the supplied bufio.Reader if the buffer has a useful size.
|
||||||
|
// This code assumes that peek on a reader returns
|
||||||
|
// bufio.Reader.buf[:0].
|
||||||
|
brw.Reader.Reset(conn)
|
||||||
|
if p, err := brw.Reader.Peek(0); err == nil && cap(p) >= 256 {
|
||||||
|
br = brw.Reader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if br == nil {
|
||||||
if readBufferSize == 0 {
|
if readBufferSize == 0 {
|
||||||
readBufferSize = defaultReadBufferSize
|
readBufferSize = defaultReadBufferSize
|
||||||
}
|
}
|
||||||
|
if readBufferSize < maxControlFramePayloadSize {
|
||||||
|
readBufferSize = maxControlFramePayloadSize
|
||||||
|
}
|
||||||
|
br = bufio.NewReaderSize(conn, readBufferSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
var writeBuf []byte
|
||||||
|
if writeBufferSize == 0 && brw != nil && brw.Writer != nil {
|
||||||
|
// Use the bufio.Writer's buffer if the buffer has a useful size. This
|
||||||
|
// code assumes that bufio.Writer.buf[:1] is passed to the
|
||||||
|
// bufio.Writer's underlying writer.
|
||||||
|
var wh writeHook
|
||||||
|
brw.Writer.Reset(&wh)
|
||||||
|
brw.Writer.WriteByte(0)
|
||||||
|
brw.Flush()
|
||||||
|
if cap(wh.p) >= maxFrameHeaderSize+256 {
|
||||||
|
writeBuf = wh.p[:cap(wh.p)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if writeBuf == nil {
|
||||||
if writeBufferSize == 0 {
|
if writeBufferSize == 0 {
|
||||||
writeBufferSize = defaultWriteBufferSize
|
writeBufferSize = defaultWriteBufferSize
|
||||||
}
|
}
|
||||||
|
writeBuf = make([]byte, writeBufferSize+maxFrameHeaderSize)
|
||||||
|
}
|
||||||
|
|
||||||
c := &Conn{
|
c := &Conn{
|
||||||
isServer: isServer,
|
isServer: isServer,
|
||||||
br: bufio.NewReaderSize(conn, readBufferSize),
|
br: br,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
mu: mu,
|
mu: mu,
|
||||||
readFinal: true,
|
readFinal: true,
|
||||||
writeBuf: make([]byte, writeBufferSize+maxFrameHeaderSize),
|
writeBuf: writeBuf,
|
||||||
writeFrameType: noFrame,
|
enableWriteCompression: true,
|
||||||
writePos: maxFrameHeaderSize,
|
compressionLevel: defaultCompressionLevel,
|
||||||
}
|
}
|
||||||
|
c.SetCloseHandler(nil)
|
||||||
c.SetPingHandler(nil)
|
c.SetPingHandler(nil)
|
||||||
c.SetPongHandler(nil)
|
c.SetPongHandler(nil)
|
||||||
return c
|
return c
|
||||||
@ -279,29 +360,40 @@ func (c *Conn) RemoteAddr() net.Addr {
|
|||||||
|
|
||||||
// Write methods
|
// Write methods
|
||||||
|
|
||||||
|
func (c *Conn) writeFatal(err error) error {
|
||||||
|
err = hideTempErr(err)
|
||||||
|
c.writeErrMu.Lock()
|
||||||
|
if c.writeErr == nil {
|
||||||
|
c.writeErr = err
|
||||||
|
}
|
||||||
|
c.writeErrMu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
|
func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
|
||||||
<-c.mu
|
<-c.mu
|
||||||
defer func() { c.mu <- true }()
|
defer func() { c.mu <- true }()
|
||||||
|
|
||||||
if c.closeSent {
|
c.writeErrMu.Lock()
|
||||||
return ErrCloseSent
|
err := c.writeErr
|
||||||
} else if frameType == CloseMessage {
|
c.writeErrMu.Unlock()
|
||||||
c.closeSent = true
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.conn.SetWriteDeadline(deadline)
|
c.conn.SetWriteDeadline(deadline)
|
||||||
for _, buf := range bufs {
|
for _, buf := range bufs {
|
||||||
if len(buf) > 0 {
|
if len(buf) > 0 {
|
||||||
n, err := c.conn.Write(buf)
|
_, err := c.conn.Write(buf)
|
||||||
if n != len(buf) {
|
|
||||||
// Close on partial write.
|
|
||||||
c.conn.Close()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return c.writeFatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if frameType == CloseMessage {
|
||||||
|
c.writeFatal(ErrCloseSent)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,60 +442,104 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
|
|||||||
}
|
}
|
||||||
defer func() { c.mu <- true }()
|
defer func() { c.mu <- true }()
|
||||||
|
|
||||||
if c.closeSent {
|
c.writeErrMu.Lock()
|
||||||
return ErrCloseSent
|
err := c.writeErr
|
||||||
} else if messageType == CloseMessage {
|
c.writeErrMu.Unlock()
|
||||||
c.closeSent = true
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.conn.SetWriteDeadline(deadline)
|
c.conn.SetWriteDeadline(deadline)
|
||||||
n, err := c.conn.Write(buf)
|
_, err = c.conn.Write(buf)
|
||||||
if n != 0 && n != len(buf) {
|
if err != nil {
|
||||||
c.conn.Close()
|
return c.writeFatal(err)
|
||||||
}
|
}
|
||||||
return hideTempErr(err)
|
if messageType == CloseMessage {
|
||||||
|
c.writeFatal(ErrCloseSent)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextWriter returns a writer for the next message to send. The writer's
|
func (c *Conn) prepWrite(messageType int) error {
|
||||||
// Close method flushes the complete message to the network.
|
// Close previous writer if not already closed by the application. It's
|
||||||
|
// probably better to return an error in this situation, but we cannot
|
||||||
|
// change this without breaking existing applications.
|
||||||
|
if c.writer != nil {
|
||||||
|
c.writer.Close()
|
||||||
|
c.writer = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isControl(messageType) && !isData(messageType) {
|
||||||
|
return errBadWriteOpCode
|
||||||
|
}
|
||||||
|
|
||||||
|
c.writeErrMu.Lock()
|
||||||
|
err := c.writeErr
|
||||||
|
c.writeErrMu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextWriter returns a writer for the next message to send. The writer's Close
|
||||||
|
// method flushes the complete message to the network.
|
||||||
//
|
//
|
||||||
// There can be at most one open writer on a connection. NextWriter closes the
|
// There can be at most one open writer on a connection. NextWriter closes the
|
||||||
// previous writer if the application has not already done so.
|
// previous writer if the application has not already done so.
|
||||||
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
|
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
|
||||||
if c.writeErr != nil {
|
if err := c.prepWrite(messageType); err != nil {
|
||||||
return nil, c.writeErr
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.writeFrameType != noFrame {
|
|
||||||
if err := c.flushFrame(true, nil); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !isControl(messageType) && !isData(messageType) {
|
mw := &messageWriter{
|
||||||
return nil, errBadWriteOpCode
|
c: c,
|
||||||
|
frameType: messageType,
|
||||||
|
pos: maxFrameHeaderSize,
|
||||||
}
|
}
|
||||||
|
c.writer = mw
|
||||||
c.writeFrameType = messageType
|
if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
|
||||||
return messageWriter{c, c.writeSeq}, nil
|
w := c.newCompressionWriter(c.writer, c.compressionLevel)
|
||||||
|
mw.compress = true
|
||||||
|
c.writer = w
|
||||||
|
}
|
||||||
|
return c.writer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) flushFrame(final bool, extra []byte) error {
|
type messageWriter struct {
|
||||||
length := c.writePos - maxFrameHeaderSize + len(extra)
|
c *Conn
|
||||||
|
compress bool // whether next call to flushFrame should set RSV1
|
||||||
|
pos int // end of data in writeBuf.
|
||||||
|
frameType int // type of the current frame.
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *messageWriter) fatal(err error) error {
|
||||||
|
if w.err != nil {
|
||||||
|
w.err = err
|
||||||
|
w.c.writer = nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// flushFrame writes buffered data and extra as a frame to the network. The
|
||||||
|
// final argument indicates that this is the last frame in the message.
|
||||||
|
func (w *messageWriter) flushFrame(final bool, extra []byte) error {
|
||||||
|
c := w.c
|
||||||
|
length := w.pos - maxFrameHeaderSize + len(extra)
|
||||||
|
|
||||||
// Check for invalid control frames.
|
// Check for invalid control frames.
|
||||||
if isControl(c.writeFrameType) &&
|
if isControl(w.frameType) &&
|
||||||
(!final || length > maxControlFramePayloadSize) {
|
(!final || length > maxControlFramePayloadSize) {
|
||||||
c.writeSeq++
|
return w.fatal(errInvalidControlFrame)
|
||||||
c.writeFrameType = noFrame
|
|
||||||
c.writePos = maxFrameHeaderSize
|
|
||||||
return errInvalidControlFrame
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b0 := byte(c.writeFrameType)
|
b0 := byte(w.frameType)
|
||||||
if final {
|
if final {
|
||||||
b0 |= finalBit
|
b0 |= finalBit
|
||||||
}
|
}
|
||||||
|
if w.compress {
|
||||||
|
b0 |= rsv1Bit
|
||||||
|
}
|
||||||
|
w.compress = false
|
||||||
|
|
||||||
b1 := byte(0)
|
b1 := byte(0)
|
||||||
if !c.isServer {
|
if !c.isServer {
|
||||||
b1 |= maskBit
|
b1 |= maskBit
|
||||||
@ -435,10 +571,9 @@ func (c *Conn) flushFrame(final bool, extra []byte) error {
|
|||||||
if !c.isServer {
|
if !c.isServer {
|
||||||
key := newMaskKey()
|
key := newMaskKey()
|
||||||
copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
|
copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
|
||||||
maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:c.writePos])
|
maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
|
||||||
if len(extra) > 0 {
|
if len(extra) > 0 {
|
||||||
c.writeErr = errors.New("websocket: internal error, extra used in client mode")
|
return c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))
|
||||||
return c.writeErr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,46 +586,35 @@ func (c *Conn) flushFrame(final bool, extra []byte) error {
|
|||||||
}
|
}
|
||||||
c.isWriting = true
|
c.isWriting = true
|
||||||
|
|
||||||
c.writeErr = c.write(c.writeFrameType, c.writeDeadline, c.writeBuf[framePos:c.writePos], extra)
|
err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)
|
||||||
|
|
||||||
if !c.isWriting {
|
if !c.isWriting {
|
||||||
panic("concurrent write to websocket connection")
|
panic("concurrent write to websocket connection")
|
||||||
}
|
}
|
||||||
c.isWriting = false
|
c.isWriting = false
|
||||||
|
|
||||||
// Setup for next frame.
|
if err != nil {
|
||||||
c.writePos = maxFrameHeaderSize
|
return w.fatal(err)
|
||||||
c.writeFrameType = continuationFrame
|
}
|
||||||
|
|
||||||
if final {
|
if final {
|
||||||
c.writeSeq++
|
c.writer = nil
|
||||||
c.writeFrameType = noFrame
|
return nil
|
||||||
}
|
}
|
||||||
return c.writeErr
|
|
||||||
}
|
|
||||||
|
|
||||||
type messageWriter struct {
|
// Setup for next frame.
|
||||||
c *Conn
|
w.pos = maxFrameHeaderSize
|
||||||
seq int
|
w.frameType = continuationFrame
|
||||||
}
|
|
||||||
|
|
||||||
func (w messageWriter) err() error {
|
|
||||||
c := w.c
|
|
||||||
if c.writeSeq != w.seq {
|
|
||||||
return errWriteClosed
|
|
||||||
}
|
|
||||||
if c.writeErr != nil {
|
|
||||||
return c.writeErr
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w messageWriter) ncopy(max int) (int, error) {
|
func (w *messageWriter) ncopy(max int) (int, error) {
|
||||||
n := len(w.c.writeBuf) - w.c.writePos
|
n := len(w.c.writeBuf) - w.pos
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
if err := w.c.flushFrame(false, nil); err != nil {
|
if err := w.flushFrame(false, nil); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
n = len(w.c.writeBuf) - w.c.writePos
|
n = len(w.c.writeBuf) - w.pos
|
||||||
}
|
}
|
||||||
if n > max {
|
if n > max {
|
||||||
n = max
|
n = max
|
||||||
@ -498,14 +622,14 @@ func (w messageWriter) ncopy(max int) (int, error) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w messageWriter) write(final bool, p []byte) (int, error) {
|
func (w *messageWriter) Write(p []byte) (int, error) {
|
||||||
if err := w.err(); err != nil {
|
if w.err != nil {
|
||||||
return 0, err
|
return 0, w.err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
|
if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
|
||||||
// Don't buffer large messages.
|
// Don't buffer large messages.
|
||||||
err := w.c.flushFrame(final, p)
|
err := w.flushFrame(false, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -518,20 +642,16 @@ func (w messageWriter) write(final bool, p []byte) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
copy(w.c.writeBuf[w.c.writePos:], p[:n])
|
copy(w.c.writeBuf[w.pos:], p[:n])
|
||||||
w.c.writePos += n
|
w.pos += n
|
||||||
p = p[n:]
|
p = p[n:]
|
||||||
}
|
}
|
||||||
return nn, nil
|
return nn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w messageWriter) Write(p []byte) (int, error) {
|
func (w *messageWriter) WriteString(p string) (int, error) {
|
||||||
return w.write(false, p)
|
if w.err != nil {
|
||||||
}
|
return 0, w.err
|
||||||
|
|
||||||
func (w messageWriter) WriteString(p string) (int, error) {
|
|
||||||
if err := w.err(); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nn := len(p)
|
nn := len(p)
|
||||||
@ -540,27 +660,27 @@ func (w messageWriter) WriteString(p string) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
copy(w.c.writeBuf[w.c.writePos:], p[:n])
|
copy(w.c.writeBuf[w.pos:], p[:n])
|
||||||
w.c.writePos += n
|
w.pos += n
|
||||||
p = p[n:]
|
p = p[n:]
|
||||||
}
|
}
|
||||||
return nn, nil
|
return nn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
|
func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
|
||||||
if err := w.err(); err != nil {
|
if w.err != nil {
|
||||||
return 0, err
|
return 0, w.err
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
if w.c.writePos == len(w.c.writeBuf) {
|
if w.pos == len(w.c.writeBuf) {
|
||||||
err = w.c.flushFrame(false, nil)
|
err = w.flushFrame(false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var n int
|
var n int
|
||||||
n, err = r.Read(w.c.writeBuf[w.c.writePos:])
|
n, err = r.Read(w.c.writeBuf[w.pos:])
|
||||||
w.c.writePos += n
|
w.pos += n
|
||||||
nn += int64(n)
|
nn += int64(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
@ -572,30 +692,64 @@ func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
|
|||||||
return nn, err
|
return nn, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w messageWriter) Close() error {
|
func (w *messageWriter) Close() error {
|
||||||
if err := w.err(); err != nil {
|
if w.err != nil {
|
||||||
|
return w.err
|
||||||
|
}
|
||||||
|
if err := w.flushFrame(true, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return w.c.flushFrame(true, nil)
|
w.err = errWriteClosed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WritePreparedMessage writes prepared message into connection.
|
||||||
|
func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
|
||||||
|
frameType, frameData, err := pm.frame(prepareKey{
|
||||||
|
isServer: c.isServer,
|
||||||
|
compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
|
||||||
|
compressionLevel: c.compressionLevel,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if c.isWriting {
|
||||||
|
panic("concurrent write to websocket connection")
|
||||||
|
}
|
||||||
|
c.isWriting = true
|
||||||
|
err = c.write(frameType, c.writeDeadline, frameData, nil)
|
||||||
|
if !c.isWriting {
|
||||||
|
panic("concurrent write to websocket connection")
|
||||||
|
}
|
||||||
|
c.isWriting = false
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMessage is a helper method for getting a writer using NextWriter,
|
// WriteMessage is a helper method for getting a writer using NextWriter,
|
||||||
// writing the message and closing the writer.
|
// writing the message and closing the writer.
|
||||||
func (c *Conn) WriteMessage(messageType int, data []byte) error {
|
func (c *Conn) WriteMessage(messageType int, data []byte) error {
|
||||||
wr, err := c.NextWriter(messageType)
|
|
||||||
|
if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
|
||||||
|
// Fast path with no allocations and single frame.
|
||||||
|
|
||||||
|
if err := c.prepWrite(messageType); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize}
|
||||||
|
n := copy(c.writeBuf[mw.pos:], data)
|
||||||
|
mw.pos += n
|
||||||
|
data = data[n:]
|
||||||
|
return mw.flushFrame(true, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
w, err := c.NextWriter(messageType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w := wr.(messageWriter)
|
if _, err = w.Write(data); err != nil {
|
||||||
if _, err := w.write(true, data); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.writeSeq == w.seq {
|
return w.Close()
|
||||||
if err := c.flushFrame(true, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriteDeadline sets the write deadline on the underlying network
|
// SetWriteDeadline sets the write deadline on the underlying network
|
||||||
@ -609,22 +763,6 @@ func (c *Conn) SetWriteDeadline(t time.Time) error {
|
|||||||
|
|
||||||
// Read methods
|
// Read methods
|
||||||
|
|
||||||
// readFull is like io.ReadFull except that io.EOF is never returned.
|
|
||||||
func (c *Conn) readFull(p []byte) (err error) {
|
|
||||||
var n int
|
|
||||||
for n < len(p) && err == nil {
|
|
||||||
var nn int
|
|
||||||
nn, err = c.br.Read(p[n:])
|
|
||||||
n += nn
|
|
||||||
}
|
|
||||||
if n == len(p) {
|
|
||||||
err = nil
|
|
||||||
} else if err == io.EOF {
|
|
||||||
err = errUnexpectedEOF
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) advanceFrame() (int, error) {
|
func (c *Conn) advanceFrame() (int, error) {
|
||||||
|
|
||||||
// 1. Skip remainder of previous frame.
|
// 1. Skip remainder of previous frame.
|
||||||
@ -637,19 +775,24 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||||||
|
|
||||||
// 2. Read and parse first two bytes of frame header.
|
// 2. Read and parse first two bytes of frame header.
|
||||||
|
|
||||||
var b [8]byte
|
p, err := c.read(2)
|
||||||
if err := c.readFull(b[:2]); err != nil {
|
if err != nil {
|
||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
|
|
||||||
final := b[0]&finalBit != 0
|
final := p[0]&finalBit != 0
|
||||||
frameType := int(b[0] & 0xf)
|
frameType := int(p[0] & 0xf)
|
||||||
reserved := int((b[0] >> 4) & 0x7)
|
mask := p[1]&maskBit != 0
|
||||||
mask := b[1]&maskBit != 0
|
c.readRemaining = int64(p[1] & 0x7f)
|
||||||
c.readRemaining = int64(b[1] & 0x7f)
|
|
||||||
|
|
||||||
if reserved != 0 {
|
c.readDecompress = false
|
||||||
return noFrame, c.handleProtocolError("unexpected reserved bits " + strconv.Itoa(reserved))
|
if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
|
||||||
|
c.readDecompress = true
|
||||||
|
p[0] &^= rsv1Bit
|
||||||
|
}
|
||||||
|
|
||||||
|
if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {
|
||||||
|
return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch frameType {
|
switch frameType {
|
||||||
@ -678,15 +821,17 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||||||
|
|
||||||
switch c.readRemaining {
|
switch c.readRemaining {
|
||||||
case 126:
|
case 126:
|
||||||
if err := c.readFull(b[:2]); err != nil {
|
p, err := c.read(2)
|
||||||
|
if err != nil {
|
||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
c.readRemaining = int64(binary.BigEndian.Uint16(b[:2]))
|
c.readRemaining = int64(binary.BigEndian.Uint16(p))
|
||||||
case 127:
|
case 127:
|
||||||
if err := c.readFull(b[:8]); err != nil {
|
p, err := c.read(8)
|
||||||
|
if err != nil {
|
||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
c.readRemaining = int64(binary.BigEndian.Uint64(b[:8]))
|
c.readRemaining = int64(binary.BigEndian.Uint64(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Handle frame masking.
|
// 4. Handle frame masking.
|
||||||
@ -697,9 +842,11 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||||||
|
|
||||||
if mask {
|
if mask {
|
||||||
c.readMaskPos = 0
|
c.readMaskPos = 0
|
||||||
if err := c.readFull(c.readMaskKey[:]); err != nil {
|
p, err := c.read(len(c.readMaskKey))
|
||||||
|
if err != nil {
|
||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
|
copy(c.readMaskKey[:], p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. For text and binary messages, enforce read limit and return.
|
// 5. For text and binary messages, enforce read limit and return.
|
||||||
@ -719,9 +866,9 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||||||
|
|
||||||
var payload []byte
|
var payload []byte
|
||||||
if c.readRemaining > 0 {
|
if c.readRemaining > 0 {
|
||||||
payload = make([]byte, c.readRemaining)
|
payload, err = c.read(int(c.readRemaining))
|
||||||
c.readRemaining = 0
|
c.readRemaining = 0
|
||||||
if err := c.readFull(payload); err != nil {
|
if err != nil {
|
||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
if c.isServer {
|
if c.isServer {
|
||||||
@ -741,15 +888,21 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||||||
return noFrame, err
|
return noFrame, err
|
||||||
}
|
}
|
||||||
case CloseMessage:
|
case CloseMessage:
|
||||||
echoMessage := []byte{}
|
|
||||||
closeCode := CloseNoStatusReceived
|
closeCode := CloseNoStatusReceived
|
||||||
closeText := ""
|
closeText := ""
|
||||||
if len(payload) >= 2 {
|
if len(payload) >= 2 {
|
||||||
echoMessage = payload[:2]
|
|
||||||
closeCode = int(binary.BigEndian.Uint16(payload))
|
closeCode = int(binary.BigEndian.Uint16(payload))
|
||||||
closeText = string(payload[2:])
|
if !isValidReceivedCloseCode(closeCode) {
|
||||||
|
return noFrame, c.handleProtocolError("invalid close code")
|
||||||
|
}
|
||||||
|
closeText = string(payload[2:])
|
||||||
|
if !utf8.ValidString(closeText) {
|
||||||
|
return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := c.handleClose(closeCode, closeText); err != nil {
|
||||||
|
return noFrame, err
|
||||||
}
|
}
|
||||||
c.WriteControl(CloseMessage, echoMessage, time.Now().Add(writeWait))
|
|
||||||
return noFrame, &CloseError{Code: closeCode, Text: closeText}
|
return noFrame, &CloseError{Code: closeCode, Text: closeText}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,8 +925,13 @@ func (c *Conn) handleProtocolError(message string) error {
|
|||||||
// permanent. Once this method returns a non-nil error, all subsequent calls to
|
// permanent. Once this method returns a non-nil error, all subsequent calls to
|
||||||
// this method return the same error.
|
// this method return the same error.
|
||||||
func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
|
func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
|
||||||
|
// Close previous reader, only relevant for decompression.
|
||||||
|
if c.reader != nil {
|
||||||
|
c.reader.Close()
|
||||||
|
c.reader = nil
|
||||||
|
}
|
||||||
|
|
||||||
c.readSeq++
|
c.messageReader = nil
|
||||||
c.readLength = 0
|
c.readLength = 0
|
||||||
|
|
||||||
for c.readErr == nil {
|
for c.readErr == nil {
|
||||||
@ -783,7 +941,12 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if frameType == TextMessage || frameType == BinaryMessage {
|
if frameType == TextMessage || frameType == BinaryMessage {
|
||||||
return frameType, messageReader{c, c.readSeq}, nil
|
c.messageReader = &messageReader{c}
|
||||||
|
c.reader = c.messageReader
|
||||||
|
if c.readDecompress {
|
||||||
|
c.reader = c.newDecompressionReader(c.reader)
|
||||||
|
}
|
||||||
|
return frameType, c.reader, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,53 +961,57 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
|
|||||||
return noFrame, nil, c.readErr
|
return noFrame, nil, c.readErr
|
||||||
}
|
}
|
||||||
|
|
||||||
type messageReader struct {
|
type messageReader struct{ c *Conn }
|
||||||
c *Conn
|
|
||||||
seq int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r messageReader) Read(b []byte) (int, error) {
|
func (r *messageReader) Read(b []byte) (int, error) {
|
||||||
|
c := r.c
|
||||||
if r.seq != r.c.readSeq {
|
if c.messageReader != r {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
for r.c.readErr == nil {
|
for c.readErr == nil {
|
||||||
|
|
||||||
if r.c.readRemaining > 0 {
|
if c.readRemaining > 0 {
|
||||||
if int64(len(b)) > r.c.readRemaining {
|
if int64(len(b)) > c.readRemaining {
|
||||||
b = b[:r.c.readRemaining]
|
b = b[:c.readRemaining]
|
||||||
}
|
}
|
||||||
n, err := r.c.br.Read(b)
|
n, err := c.br.Read(b)
|
||||||
r.c.readErr = hideTempErr(err)
|
c.readErr = hideTempErr(err)
|
||||||
if r.c.isServer {
|
if c.isServer {
|
||||||
r.c.readMaskPos = maskBytes(r.c.readMaskKey, r.c.readMaskPos, b[:n])
|
c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
|
||||||
}
|
}
|
||||||
r.c.readRemaining -= int64(n)
|
c.readRemaining -= int64(n)
|
||||||
return n, r.c.readErr
|
if c.readRemaining > 0 && c.readErr == io.EOF {
|
||||||
|
c.readErr = errUnexpectedEOF
|
||||||
|
}
|
||||||
|
return n, c.readErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.c.readFinal {
|
if c.readFinal {
|
||||||
r.c.readSeq++
|
c.messageReader = nil
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
frameType, err := r.c.advanceFrame()
|
frameType, err := c.advanceFrame()
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
r.c.readErr = hideTempErr(err)
|
c.readErr = hideTempErr(err)
|
||||||
case frameType == TextMessage || frameType == BinaryMessage:
|
case frameType == TextMessage || frameType == BinaryMessage:
|
||||||
r.c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
|
c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := r.c.readErr
|
err := c.readErr
|
||||||
if err == io.EOF && r.seq == r.c.readSeq {
|
if err == io.EOF && c.messageReader == r {
|
||||||
err = errUnexpectedEOF
|
err = errUnexpectedEOF
|
||||||
}
|
}
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *messageReader) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadMessage is a helper method for getting a reader using NextReader and
|
// ReadMessage is a helper method for getting a reader using NextReader and
|
||||||
// reading from that reader to a buffer.
|
// reading from that reader to a buffer.
|
||||||
func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
|
func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
|
||||||
@ -872,9 +1039,49 @@ func (c *Conn) SetReadLimit(limit int64) {
|
|||||||
c.readLimit = limit
|
c.readLimit = limit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloseHandler returns the current close handler
|
||||||
|
func (c *Conn) CloseHandler() func(code int, text string) error {
|
||||||
|
return c.handleClose
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCloseHandler sets the handler for close messages received from the peer.
|
||||||
|
// The code argument to h is the received close code or CloseNoStatusReceived
|
||||||
|
// if the close message is empty. The default close handler sends a close frame
|
||||||
|
// back to the peer.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process close messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
|
//
|
||||||
|
// The connection read methods return a CloseError when a close frame is
|
||||||
|
// received. Most applications should handle close messages as part of their
|
||||||
|
// normal error handling. Applications should only set a close handler when the
|
||||||
|
// application must perform some action before sending a close frame back to
|
||||||
|
// the peer.
|
||||||
|
func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
|
||||||
|
if h == nil {
|
||||||
|
h = func(code int, text string) error {
|
||||||
|
message := []byte{}
|
||||||
|
if code != CloseNoStatusReceived {
|
||||||
|
message = FormatCloseMessage(code, "")
|
||||||
|
}
|
||||||
|
c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.handleClose = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// PingHandler returns the current ping handler
|
||||||
|
func (c *Conn) PingHandler() func(appData string) error {
|
||||||
|
return c.handlePing
|
||||||
|
}
|
||||||
|
|
||||||
// SetPingHandler sets the handler for ping messages received from the peer.
|
// SetPingHandler sets the handler for ping messages received from the peer.
|
||||||
// The appData argument to h is the PING frame application data. The default
|
// The appData argument to h is the PING frame application data. The default
|
||||||
// ping handler sends a pong to the peer.
|
// ping handler sends a pong to the peer.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process ping messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
func (c *Conn) SetPingHandler(h func(appData string) error) {
|
func (c *Conn) SetPingHandler(h func(appData string) error) {
|
||||||
if h == nil {
|
if h == nil {
|
||||||
h = func(message string) error {
|
h = func(message string) error {
|
||||||
@ -890,9 +1097,17 @@ func (c *Conn) SetPingHandler(h func(appData string) error) {
|
|||||||
c.handlePing = h
|
c.handlePing = h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PongHandler returns the current pong handler
|
||||||
|
func (c *Conn) PongHandler() func(appData string) error {
|
||||||
|
return c.handlePong
|
||||||
|
}
|
||||||
|
|
||||||
// SetPongHandler sets the handler for pong messages received from the peer.
|
// SetPongHandler sets the handler for pong messages received from the peer.
|
||||||
// The appData argument to h is the PONG frame application data. The default
|
// The appData argument to h is the PONG frame application data. The default
|
||||||
// pong handler does nothing.
|
// pong handler does nothing.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process ping messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
func (c *Conn) SetPongHandler(h func(appData string) error) {
|
func (c *Conn) SetPongHandler(h func(appData string) error) {
|
||||||
if h == nil {
|
if h == nil {
|
||||||
h = func(string) error { return nil }
|
h = func(string) error { return nil }
|
||||||
@ -906,6 +1121,25 @@ func (c *Conn) UnderlyingConn() net.Conn {
|
|||||||
return c.conn
|
return c.conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableWriteCompression enables and disables write compression of
|
||||||
|
// subsequent text and binary messages. This function is a noop if
|
||||||
|
// compression was not negotiated with the peer.
|
||||||
|
func (c *Conn) EnableWriteCompression(enable bool) {
|
||||||
|
c.enableWriteCompression = enable
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCompressionLevel sets the flate compression level for subsequent text and
|
||||||
|
// binary messages. This function is a noop if compression was not negotiated
|
||||||
|
// with the peer. See the compress/flate package for a description of
|
||||||
|
// compression levels.
|
||||||
|
func (c *Conn) SetCompressionLevel(level int) error {
|
||||||
|
if !isValidCompressionLevel(level) {
|
||||||
|
return errors.New("websocket: invalid compression level")
|
||||||
|
}
|
||||||
|
c.compressionLevel = level
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// FormatCloseMessage formats closeCode and text as a WebSocket close message.
|
// FormatCloseMessage formats closeCode and text as a WebSocket close message.
|
||||||
func FormatCloseMessage(closeCode int, text string) []byte {
|
func FormatCloseMessage(closeCode int, text string) []byte {
|
||||||
buf := make([]byte, 2+len(text))
|
buf := make([]byte, 2+len(text))
|
||||||
|
18
vendor/github.com/gorilla/websocket/conn_read.go
generated
vendored
Normal file
18
vendor/github.com/gorilla/websocket/conn_read.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.5
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
func (c *Conn) read(n int) ([]byte, error) {
|
||||||
|
p, err := c.br.Peek(n)
|
||||||
|
if err == io.EOF {
|
||||||
|
err = errUnexpectedEOF
|
||||||
|
}
|
||||||
|
c.br.Discard(len(p))
|
||||||
|
return p, err
|
||||||
|
}
|
21
vendor/github.com/gorilla/websocket/conn_read_legacy.go
generated
vendored
Normal file
21
vendor/github.com/gorilla/websocket/conn_read_legacy.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.5
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
func (c *Conn) read(n int) ([]byte, error) {
|
||||||
|
p, err := c.br.Peek(n)
|
||||||
|
if err == io.EOF {
|
||||||
|
err = errUnexpectedEOF
|
||||||
|
}
|
||||||
|
if len(p) > 0 {
|
||||||
|
// advance over the bytes just read
|
||||||
|
io.ReadFull(c.br, p)
|
||||||
|
}
|
||||||
|
return p, err
|
||||||
|
}
|
34
vendor/github.com/gorilla/websocket/doc.go
generated
vendored
34
vendor/github.com/gorilla/websocket/doc.go
generated
vendored
@ -118,9 +118,10 @@
|
|||||||
//
|
//
|
||||||
// Applications are responsible for ensuring that no more than one goroutine
|
// Applications are responsible for ensuring that no more than one goroutine
|
||||||
// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
|
// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
|
||||||
// WriteJSON) concurrently and that no more than one goroutine calls the read
|
// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
|
||||||
// methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler,
|
// that no more than one goroutine calls the read methods (NextReader,
|
||||||
// SetPingHandler) concurrently.
|
// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
|
||||||
|
// concurrently.
|
||||||
//
|
//
|
||||||
// The Close and WriteControl methods can be called concurrently with all other
|
// The Close and WriteControl methods can be called concurrently with all other
|
||||||
// methods.
|
// methods.
|
||||||
@ -149,4 +150,31 @@
|
|||||||
// The deprecated Upgrade function does not enforce an origin policy. It's the
|
// The deprecated Upgrade function does not enforce an origin policy. It's the
|
||||||
// application's responsibility to check the Origin header before calling
|
// application's responsibility to check the Origin header before calling
|
||||||
// Upgrade.
|
// Upgrade.
|
||||||
|
//
|
||||||
|
// Compression EXPERIMENTAL
|
||||||
|
//
|
||||||
|
// Per message compression extensions (RFC 7692) are experimentally supported
|
||||||
|
// by this package in a limited capacity. Setting the EnableCompression option
|
||||||
|
// to true in Dialer or Upgrader will attempt to negotiate per message deflate
|
||||||
|
// support.
|
||||||
|
//
|
||||||
|
// var upgrader = websocket.Upgrader{
|
||||||
|
// EnableCompression: true,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// If compression was successfully negotiated with the connection's peer, any
|
||||||
|
// message received in compressed form will be automatically decompressed.
|
||||||
|
// All Read methods will return uncompressed bytes.
|
||||||
|
//
|
||||||
|
// Per message compression of messages written to a connection can be enabled
|
||||||
|
// or disabled by calling the corresponding Conn method:
|
||||||
|
//
|
||||||
|
// conn.EnableWriteCompression(false)
|
||||||
|
//
|
||||||
|
// Currently this package does not support compression with "context takeover".
|
||||||
|
// This means that messages must be compressed and decompressed in isolation,
|
||||||
|
// without retaining sliding window or dictionary state across messages. For
|
||||||
|
// more details refer to RFC 7692.
|
||||||
|
//
|
||||||
|
// Use of compression is experimental and may result in decreased performance.
|
||||||
package websocket
|
package websocket
|
||||||
|
27
vendor/github.com/gorilla/websocket/examples/autobahn/server.go
generated
vendored
27
vendor/github.com/gorilla/websocket/examples/autobahn/server.go
generated
vendored
@ -8,17 +8,19 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
var upgrader = websocket.Upgrader{
|
||||||
ReadBufferSize: 4096,
|
ReadBufferSize: 4096,
|
||||||
WriteBufferSize: 4096,
|
WriteBufferSize: 4096,
|
||||||
|
EnableCompression: true,
|
||||||
CheckOrigin: func(r *http.Request) bool {
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
@ -83,7 +85,7 @@ func echoCopyFull(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// echoReadAll echoes messages from the client by reading the entire message
|
// echoReadAll echoes messages from the client by reading the entire message
|
||||||
// with ioutil.ReadAll.
|
// with ioutil.ReadAll.
|
||||||
func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) {
|
func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) {
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Upgrade:", err)
|
log.Println("Upgrade:", err)
|
||||||
@ -107,10 +109,22 @@ func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if writeMessage {
|
if writeMessage {
|
||||||
|
if !writePrepared {
|
||||||
err = conn.WriteMessage(mt, b)
|
err = conn.WriteMessage(mt, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WriteMessage:", err)
|
log.Println("WriteMessage:", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pm, err := websocket.NewPreparedMessage(mt, b)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("NewPreparedMessage:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = conn.WritePreparedMessage(pm)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("WritePreparedMessage:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
w, err := conn.NextWriter(mt)
|
w, err := conn.NextWriter(mt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -130,11 +144,15 @@ func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
|
func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
|
||||||
echoReadAll(w, r, false)
|
echoReadAll(w, r, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
|
func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
echoReadAll(w, r, true)
|
echoReadAll(w, r, true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func echoReadAllWritePreparedMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
echoReadAll(w, r, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveHome(w http.ResponseWriter, r *http.Request) {
|
func serveHome(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -159,6 +177,7 @@ func main() {
|
|||||||
http.HandleFunc("/f", echoCopyFull)
|
http.HandleFunc("/f", echoCopyFull)
|
||||||
http.HandleFunc("/r", echoReadAllWriter)
|
http.HandleFunc("/r", echoReadAllWriter)
|
||||||
http.HandleFunc("/m", echoReadAllWriteMessage)
|
http.HandleFunc("/m", echoReadAllWriteMessage)
|
||||||
|
http.HandleFunc("/p", echoReadAllWritePreparedMessage)
|
||||||
err := http.ListenAndServe(*addr, nil)
|
err := http.ListenAndServe(*addr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("ListenAndServe: ", err)
|
log.Fatal("ListenAndServe: ", err)
|
||||||
|
134
vendor/github.com/gorilla/websocket/examples/chat/client.go
generated
vendored
Normal file
134
vendor/github.com/gorilla/websocket/examples/chat/client.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Time allowed to write a message to the peer.
|
||||||
|
writeWait = 10 * time.Second
|
||||||
|
|
||||||
|
// Time allowed to read the next pong message from the peer.
|
||||||
|
pongWait = 60 * time.Second
|
||||||
|
|
||||||
|
// Send pings to peer with this period. Must be less than pongWait.
|
||||||
|
pingPeriod = (pongWait * 9) / 10
|
||||||
|
|
||||||
|
// Maximum message size allowed from peer.
|
||||||
|
maxMessageSize = 512
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
newline = []byte{'\n'}
|
||||||
|
space = []byte{' '}
|
||||||
|
)
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is a middleman between the websocket connection and the hub.
|
||||||
|
type Client struct {
|
||||||
|
hub *Hub
|
||||||
|
|
||||||
|
// The websocket connection.
|
||||||
|
conn *websocket.Conn
|
||||||
|
|
||||||
|
// Buffered channel of outbound messages.
|
||||||
|
send chan []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// readPump pumps messages from the websocket connection to the hub.
|
||||||
|
//
|
||||||
|
// The application runs readPump in a per-connection goroutine. The application
|
||||||
|
// ensures that there is at most one reader on a connection by executing all
|
||||||
|
// reads from this goroutine.
|
||||||
|
func (c *Client) readPump() {
|
||||||
|
defer func() {
|
||||||
|
c.hub.unregister <- c
|
||||||
|
c.conn.Close()
|
||||||
|
}()
|
||||||
|
c.conn.SetReadLimit(maxMessageSize)
|
||||||
|
c.conn.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
||||||
|
for {
|
||||||
|
_, message, err := c.conn.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
|
||||||
|
log.Printf("error: %v", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
|
||||||
|
c.hub.broadcast <- message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// writePump pumps messages from the hub to the websocket connection.
|
||||||
|
//
|
||||||
|
// A goroutine running writePump is started for each connection. The
|
||||||
|
// application ensures that there is at most one writer to a connection by
|
||||||
|
// executing all writes from this goroutine.
|
||||||
|
func (c *Client) writePump() {
|
||||||
|
ticker := time.NewTicker(pingPeriod)
|
||||||
|
defer func() {
|
||||||
|
ticker.Stop()
|
||||||
|
c.conn.Close()
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case message, ok := <-c.send:
|
||||||
|
c.conn.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
|
if !ok {
|
||||||
|
// The hub closed the channel.
|
||||||
|
c.conn.WriteMessage(websocket.CloseMessage, []byte{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w, err := c.conn.NextWriter(websocket.TextMessage)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(message)
|
||||||
|
|
||||||
|
// Add queued chat messages to the current websocket message.
|
||||||
|
n := len(c.send)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
w.Write(newline)
|
||||||
|
w.Write(<-c.send)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := w.Close(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-ticker.C:
|
||||||
|
c.conn.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
|
if err := c.conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// serveWs handles websocket requests from the peer.
|
||||||
|
func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
|
||||||
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
|
||||||
|
client.hub.register <- client
|
||||||
|
go client.writePump()
|
||||||
|
client.readPump()
|
||||||
|
}
|
105
vendor/github.com/gorilla/websocket/examples/chat/conn.go
generated
vendored
105
vendor/github.com/gorilla/websocket/examples/chat/conn.go
generated
vendored
@ -1,105 +0,0 @@
|
|||||||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Time allowed to write a message to the peer.
|
|
||||||
writeWait = 10 * time.Second
|
|
||||||
|
|
||||||
// Time allowed to read the next pong message from the peer.
|
|
||||||
pongWait = 60 * time.Second
|
|
||||||
|
|
||||||
// Send pings to peer with this period. Must be less than pongWait.
|
|
||||||
pingPeriod = (pongWait * 9) / 10
|
|
||||||
|
|
||||||
// Maximum message size allowed from peer.
|
|
||||||
maxMessageSize = 512
|
|
||||||
)
|
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 1024,
|
|
||||||
}
|
|
||||||
|
|
||||||
// connection is an middleman between the websocket connection and the hub.
|
|
||||||
type connection struct {
|
|
||||||
// The websocket connection.
|
|
||||||
ws *websocket.Conn
|
|
||||||
|
|
||||||
// Buffered channel of outbound messages.
|
|
||||||
send chan []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// readPump pumps messages from the websocket connection to the hub.
|
|
||||||
func (c *connection) readPump() {
|
|
||||||
defer func() {
|
|
||||||
h.unregister <- c
|
|
||||||
c.ws.Close()
|
|
||||||
}()
|
|
||||||
c.ws.SetReadLimit(maxMessageSize)
|
|
||||||
c.ws.SetReadDeadline(time.Now().Add(pongWait))
|
|
||||||
c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
|
||||||
for {
|
|
||||||
_, message, err := c.ws.ReadMessage()
|
|
||||||
if err != nil {
|
|
||||||
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
|
|
||||||
log.Printf("error: %v", err)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
h.broadcast <- message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write writes a message with the given message type and payload.
|
|
||||||
func (c *connection) write(mt int, payload []byte) error {
|
|
||||||
c.ws.SetWriteDeadline(time.Now().Add(writeWait))
|
|
||||||
return c.ws.WriteMessage(mt, payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
// writePump pumps messages from the hub to the websocket connection.
|
|
||||||
func (c *connection) writePump() {
|
|
||||||
ticker := time.NewTicker(pingPeriod)
|
|
||||||
defer func() {
|
|
||||||
ticker.Stop()
|
|
||||||
c.ws.Close()
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case message, ok := <-c.send:
|
|
||||||
if !ok {
|
|
||||||
c.write(websocket.CloseMessage, []byte{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.write(websocket.TextMessage, message); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case <-ticker.C:
|
|
||||||
if err := c.write(websocket.PingMessage, []byte{}); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// serveWs handles websocket requests from the peer.
|
|
||||||
func serveWs(w http.ResponseWriter, r *http.Request) {
|
|
||||||
ws, err := upgrader.Upgrade(w, r, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c := &connection{send: make(chan []byte, 256), ws: ws}
|
|
||||||
h.register <- c
|
|
||||||
go c.writePump()
|
|
||||||
c.readPump()
|
|
||||||
}
|
|
54
vendor/github.com/gorilla/websocket/examples/chat/hub.go
generated
vendored
54
vendor/github.com/gorilla/websocket/examples/chat/hub.go
generated
vendored
@ -4,46 +4,48 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// hub maintains the set of active connections and broadcasts messages to the
|
// hub maintains the set of active clients and broadcasts messages to the
|
||||||
// connections.
|
// clients.
|
||||||
type hub struct {
|
type Hub struct {
|
||||||
// Registered connections.
|
// Registered clients.
|
||||||
connections map[*connection]bool
|
clients map[*Client]bool
|
||||||
|
|
||||||
// Inbound messages from the connections.
|
// Inbound messages from the clients.
|
||||||
broadcast chan []byte
|
broadcast chan []byte
|
||||||
|
|
||||||
// Register requests from the connections.
|
// Register requests from the clients.
|
||||||
register chan *connection
|
register chan *Client
|
||||||
|
|
||||||
// Unregister requests from connections.
|
// Unregister requests from clients.
|
||||||
unregister chan *connection
|
unregister chan *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
var h = hub{
|
func newHub() *Hub {
|
||||||
|
return &Hub{
|
||||||
broadcast: make(chan []byte),
|
broadcast: make(chan []byte),
|
||||||
register: make(chan *connection),
|
register: make(chan *Client),
|
||||||
unregister: make(chan *connection),
|
unregister: make(chan *Client),
|
||||||
connections: make(map[*connection]bool),
|
clients: make(map[*Client]bool),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hub) run() {
|
func (h *Hub) run() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case c := <-h.register:
|
case client := <-h.register:
|
||||||
h.connections[c] = true
|
h.clients[client] = true
|
||||||
case c := <-h.unregister:
|
case client := <-h.unregister:
|
||||||
if _, ok := h.connections[c]; ok {
|
if _, ok := h.clients[client]; ok {
|
||||||
delete(h.connections, c)
|
delete(h.clients, client)
|
||||||
close(c.send)
|
close(client.send)
|
||||||
}
|
}
|
||||||
case m := <-h.broadcast:
|
case message := <-h.broadcast:
|
||||||
for c := range h.connections {
|
for client := range h.clients {
|
||||||
select {
|
select {
|
||||||
case c.send <- m:
|
case client.send <- message:
|
||||||
default:
|
default:
|
||||||
close(c.send)
|
close(client.send)
|
||||||
delete(h.connections, c)
|
delete(h.clients, client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/gorilla/websocket/examples/chat/main.go
generated
vendored
13
vendor/github.com/gorilla/websocket/examples/chat/main.go
generated
vendored
@ -8,13 +8,12 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var addr = flag.String("addr", ":8080", "http service address")
|
var addr = flag.String("addr", ":8080", "http service address")
|
||||||
var homeTempl = template.Must(template.ParseFiles("home.html"))
|
|
||||||
|
|
||||||
func serveHome(w http.ResponseWriter, r *http.Request) {
|
func serveHome(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println(r.URL)
|
||||||
if r.URL.Path != "/" {
|
if r.URL.Path != "/" {
|
||||||
http.Error(w, "Not found", 404)
|
http.Error(w, "Not found", 404)
|
||||||
return
|
return
|
||||||
@ -23,15 +22,17 @@ func serveHome(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "Method not allowed", 405)
|
http.Error(w, "Method not allowed", 405)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
http.ServeFile(w, r, "home.html")
|
||||||
homeTempl.Execute(w, r.Host)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
go h.run()
|
hub := newHub()
|
||||||
|
go hub.run()
|
||||||
http.HandleFunc("/", serveHome)
|
http.HandleFunc("/", serveHome)
|
||||||
http.HandleFunc("/ws", serveWs)
|
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
serveWs(hub, w, r)
|
||||||
|
})
|
||||||
err := http.ListenAndServe(*addr, nil)
|
err := http.ListenAndServe(*addr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("ListenAndServe: ", err)
|
log.Fatal("ListenAndServe: ", err)
|
||||||
|
17
vendor/github.com/gorilla/websocket/examples/command/main.go
generated
vendored
17
vendor/github.com/gorilla/websocket/examples/command/main.go
generated
vendored
@ -12,7 +12,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@ -21,7 +20,6 @@ import (
|
|||||||
var (
|
var (
|
||||||
addr = flag.String("addr", "127.0.0.1:8080", "http service address")
|
addr = flag.String("addr", "127.0.0.1:8080", "http service address")
|
||||||
cmdPath string
|
cmdPath string
|
||||||
homeTempl = template.Must(template.ParseFiles("home.html"))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -36,6 +34,9 @@ const (
|
|||||||
|
|
||||||
// Send pings to peer with this period. Must be less than pongWait.
|
// Send pings to peer with this period. Must be less than pongWait.
|
||||||
pingPeriod = (pongWait * 9) / 10
|
pingPeriod = (pongWait * 9) / 10
|
||||||
|
|
||||||
|
// Time to wait before force close on connection.
|
||||||
|
closeGracePeriod = 10 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
||||||
@ -57,19 +58,24 @@ func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
|||||||
|
|
||||||
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
|
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
|
||||||
defer func() {
|
defer func() {
|
||||||
ws.Close()
|
|
||||||
close(done)
|
|
||||||
}()
|
}()
|
||||||
s := bufio.NewScanner(r)
|
s := bufio.NewScanner(r)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
|
if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
|
||||||
|
ws.Close()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Err() != nil {
|
if s.Err() != nil {
|
||||||
log.Println("scan:", s.Err())
|
log.Println("scan:", s.Err())
|
||||||
}
|
}
|
||||||
|
close(done)
|
||||||
|
|
||||||
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
|
ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
||||||
|
time.Sleep(closeGracePeriod)
|
||||||
|
ws.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ping(ws *websocket.Conn, done chan struct{}) {
|
func ping(ws *websocket.Conn, done chan struct{}) {
|
||||||
@ -168,8 +174,7 @@ func serveHome(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "Method not allowed", 405)
|
http.Error(w, "Method not allowed", 405)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
http.ServeFile(w, r, "home.html")
|
||||||
homeTempl.Execute(w, r.Host)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
4
vendor/github.com/gorilla/websocket/examples/filewatch/main.go
generated
vendored
4
vendor/github.com/gorilla/websocket/examples/filewatch/main.go
generated
vendored
@ -6,12 +6,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@ -120,7 +120,7 @@ func serveWs(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lastMod time.Time
|
var lastMod time.Time
|
||||||
if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err != nil {
|
if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err == nil {
|
||||||
lastMod = time.Unix(0, n)
|
lastMod = time.Unix(0, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
vendor/github.com/gorilla/websocket/mask.go
generated
vendored
Normal file
55
vendor/github.com/gorilla/websocket/mask.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
|
||||||
|
// this source code is governed by a BSD-style license that can be found in the
|
||||||
|
// LICENSE file.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
const wordSize = int(unsafe.Sizeof(uintptr(0)))
|
||||||
|
|
||||||
|
func maskBytes(key [4]byte, pos int, b []byte) int {
|
||||||
|
|
||||||
|
// Mask one byte at a time for small buffers.
|
||||||
|
if len(b) < 2*wordSize {
|
||||||
|
for i := range b {
|
||||||
|
b[i] ^= key[pos&3]
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
return pos & 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask one byte at a time to word boundary.
|
||||||
|
if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
|
||||||
|
n = wordSize - n
|
||||||
|
for i := range b[:n] {
|
||||||
|
b[i] ^= key[pos&3]
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
b = b[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create aligned word size key.
|
||||||
|
var k [wordSize]byte
|
||||||
|
for i := range k {
|
||||||
|
k[i] = key[(pos+i)&3]
|
||||||
|
}
|
||||||
|
kw := *(*uintptr)(unsafe.Pointer(&k))
|
||||||
|
|
||||||
|
// Mask one word at a time.
|
||||||
|
n := (len(b) / wordSize) * wordSize
|
||||||
|
for i := 0; i < n; i += wordSize {
|
||||||
|
*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask one byte at a time for remaining bytes.
|
||||||
|
b = b[n:]
|
||||||
|
for i := range b {
|
||||||
|
b[i] ^= key[pos&3]
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos & 3
|
||||||
|
}
|
15
vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
Normal file
15
vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
|
||||||
|
// this source code is governed by a BSD-style license that can be found in the
|
||||||
|
// LICENSE file.
|
||||||
|
|
||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
func maskBytes(key [4]byte, pos int, b []byte) int {
|
||||||
|
for i := range b {
|
||||||
|
b[i] ^= key[pos&3]
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
return pos & 3
|
||||||
|
}
|
103
vendor/github.com/gorilla/websocket/prepared.go
generated
vendored
Normal file
103
vendor/github.com/gorilla/websocket/prepared.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PreparedMessage caches on the wire representations of a message payload.
|
||||||
|
// Use PreparedMessage to efficiently send a message payload to multiple
|
||||||
|
// connections. PreparedMessage is especially useful when compression is used
|
||||||
|
// because the CPU and memory expensive compression operation can be executed
|
||||||
|
// once for a given set of compression options.
|
||||||
|
type PreparedMessage struct {
|
||||||
|
messageType int
|
||||||
|
data []byte
|
||||||
|
err error
|
||||||
|
mu sync.Mutex
|
||||||
|
frames map[prepareKey]*preparedFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.
|
||||||
|
type prepareKey struct {
|
||||||
|
isServer bool
|
||||||
|
compress bool
|
||||||
|
compressionLevel int
|
||||||
|
}
|
||||||
|
|
||||||
|
// preparedFrame contains data in wire representation.
|
||||||
|
type preparedFrame struct {
|
||||||
|
once sync.Once
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPreparedMessage returns an initialized PreparedMessage. You can then send
|
||||||
|
// it to connection using WritePreparedMessage method. Valid wire
|
||||||
|
// representation will be calculated lazily only once for a set of current
|
||||||
|
// connection options.
|
||||||
|
func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
|
||||||
|
pm := &PreparedMessage{
|
||||||
|
messageType: messageType,
|
||||||
|
frames: make(map[prepareKey]*preparedFrame),
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare a plain server frame.
|
||||||
|
_, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// To protect against caller modifying the data argument, remember the data
|
||||||
|
// copied to the plain server frame.
|
||||||
|
pm.data = frameData[len(frameData)-len(data):]
|
||||||
|
return pm, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
|
||||||
|
pm.mu.Lock()
|
||||||
|
frame, ok := pm.frames[key]
|
||||||
|
if !ok {
|
||||||
|
frame = &preparedFrame{}
|
||||||
|
pm.frames[key] = frame
|
||||||
|
}
|
||||||
|
pm.mu.Unlock()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
frame.once.Do(func() {
|
||||||
|
// Prepare a frame using a 'fake' connection.
|
||||||
|
// TODO: Refactor code in conn.go to allow more direct construction of
|
||||||
|
// the frame.
|
||||||
|
mu := make(chan bool, 1)
|
||||||
|
mu <- true
|
||||||
|
var nc prepareConn
|
||||||
|
c := &Conn{
|
||||||
|
conn: &nc,
|
||||||
|
mu: mu,
|
||||||
|
isServer: key.isServer,
|
||||||
|
compressionLevel: key.compressionLevel,
|
||||||
|
enableWriteCompression: true,
|
||||||
|
writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
|
||||||
|
}
|
||||||
|
if key.compress {
|
||||||
|
c.newCompressionWriter = compressNoContextTakeover
|
||||||
|
}
|
||||||
|
err = c.WriteMessage(pm.messageType, pm.data)
|
||||||
|
frame.data = nc.buf.Bytes()
|
||||||
|
})
|
||||||
|
return pm.messageType, frame.data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type prepareConn struct {
|
||||||
|
buf bytes.Buffer
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) }
|
||||||
|
func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
|
61
vendor/github.com/gorilla/websocket/server.go
generated
vendored
61
vendor/github.com/gorilla/websocket/server.go
generated
vendored
@ -28,8 +28,9 @@ type Upgrader struct {
|
|||||||
HandshakeTimeout time.Duration
|
HandshakeTimeout time.Duration
|
||||||
|
|
||||||
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
|
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
|
||||||
// size is zero, then a default value of 4096 is used. The I/O buffer sizes
|
// size is zero, then buffers allocated by the HTTP server are used. The
|
||||||
// do not limit the size of the messages that can be sent or received.
|
// I/O buffer sizes do not limit the size of the messages that can be sent
|
||||||
|
// or received.
|
||||||
ReadBufferSize, WriteBufferSize int
|
ReadBufferSize, WriteBufferSize int
|
||||||
|
|
||||||
// Subprotocols specifies the server's supported protocols in order of
|
// Subprotocols specifies the server's supported protocols in order of
|
||||||
@ -46,6 +47,12 @@ type Upgrader struct {
|
|||||||
// CheckOrigin is nil, the host in the Origin header must not be set or
|
// CheckOrigin is nil, the host in the Origin header must not be set or
|
||||||
// must match the host of the request.
|
// must match the host of the request.
|
||||||
CheckOrigin func(r *http.Request) bool
|
CheckOrigin func(r *http.Request) bool
|
||||||
|
|
||||||
|
// EnableCompression specify if the server should attempt to negotiate per
|
||||||
|
// message compression (RFC 7692). Setting this value to true does not
|
||||||
|
// guarantee that compression will be supported. Currently only "no context
|
||||||
|
// takeover" modes are supported.
|
||||||
|
EnableCompression bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
|
func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
|
||||||
@ -53,6 +60,7 @@ func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status in
|
|||||||
if u.Error != nil {
|
if u.Error != nil {
|
||||||
u.Error(w, r, status, err)
|
u.Error(w, r, status, err)
|
||||||
} else {
|
} else {
|
||||||
|
w.Header().Set("Sec-Websocket-Version", "13")
|
||||||
http.Error(w, http.StatusText(status), status)
|
http.Error(w, http.StatusText(status), status)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -97,18 +105,23 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header
|
|||||||
// response.
|
// response.
|
||||||
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
|
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: method not GET")
|
return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: not a websocket handshake: request method is not GET")
|
||||||
}
|
}
|
||||||
if values := r.Header["Sec-Websocket-Version"]; len(values) == 0 || values[0] != "13" {
|
|
||||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13")
|
if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
|
||||||
|
return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-Websocket-Extensions' headers are unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
|
if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
|
||||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find connection header with token 'upgrade'")
|
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'upgrade' token not found in 'Connection' header")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
|
if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
|
||||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find upgrade header with token 'websocket'")
|
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'websocket' token not found in 'Upgrade' header")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
|
||||||
|
return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
|
||||||
}
|
}
|
||||||
|
|
||||||
checkOrigin := u.CheckOrigin
|
checkOrigin := u.CheckOrigin
|
||||||
@ -116,19 +129,30 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||||||
checkOrigin = checkSameOrigin
|
checkOrigin = checkSameOrigin
|
||||||
}
|
}
|
||||||
if !checkOrigin(r) {
|
if !checkOrigin(r) {
|
||||||
return u.returnError(w, r, http.StatusForbidden, "websocket: origin not allowed")
|
return u.returnError(w, r, http.StatusForbidden, "websocket: 'Origin' header value not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
challengeKey := r.Header.Get("Sec-Websocket-Key")
|
challengeKey := r.Header.Get("Sec-Websocket-Key")
|
||||||
if challengeKey == "" {
|
if challengeKey == "" {
|
||||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: key missing or blank")
|
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-Websocket-Key' header is missing or blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
subprotocol := u.selectSubprotocol(r, responseHeader)
|
subprotocol := u.selectSubprotocol(r, responseHeader)
|
||||||
|
|
||||||
|
// Negotiate PMCE
|
||||||
|
var compress bool
|
||||||
|
if u.EnableCompression {
|
||||||
|
for _, ext := range parseExtensions(r.Header) {
|
||||||
|
if ext[""] != "permessage-deflate" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
compress = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
netConn net.Conn
|
netConn net.Conn
|
||||||
br *bufio.Reader
|
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -136,21 +160,25 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||||||
if !ok {
|
if !ok {
|
||||||
return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
|
return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
|
||||||
}
|
}
|
||||||
var rw *bufio.ReadWriter
|
var brw *bufio.ReadWriter
|
||||||
netConn, rw, err = h.Hijack()
|
netConn, brw, err = h.Hijack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
|
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
br = rw.Reader
|
|
||||||
|
|
||||||
if br.Buffered() > 0 {
|
if brw.Reader.Buffered() > 0 {
|
||||||
netConn.Close()
|
netConn.Close()
|
||||||
return nil, errors.New("websocket: client sent data before handshake is complete")
|
return nil, errors.New("websocket: client sent data before handshake is complete")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize)
|
c := newConnBRW(netConn, true, u.ReadBufferSize, u.WriteBufferSize, brw)
|
||||||
c.subprotocol = subprotocol
|
c.subprotocol = subprotocol
|
||||||
|
|
||||||
|
if compress {
|
||||||
|
c.newCompressionWriter = compressNoContextTakeover
|
||||||
|
c.newDecompressionReader = decompressNoContextTakeover
|
||||||
|
}
|
||||||
|
|
||||||
p := c.writeBuf[:0]
|
p := c.writeBuf[:0]
|
||||||
p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
|
p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
|
||||||
p = append(p, computeAcceptKey(challengeKey)...)
|
p = append(p, computeAcceptKey(challengeKey)...)
|
||||||
@ -160,6 +188,9 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||||||
p = append(p, c.subprotocol...)
|
p = append(p, c.subprotocol...)
|
||||||
p = append(p, "\r\n"...)
|
p = append(p, "\r\n"...)
|
||||||
}
|
}
|
||||||
|
if compress {
|
||||||
|
p = append(p, "Sec-Websocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
|
||||||
|
}
|
||||||
for k, vs := range responseHeader {
|
for k, vs := range responseHeader {
|
||||||
if k == "Sec-Websocket-Protocol" {
|
if k == "Sec-Websocket-Protocol" {
|
||||||
continue
|
continue
|
||||||
|
196
vendor/github.com/gorilla/websocket/util.go
generated
vendored
196
vendor/github.com/gorilla/websocket/util.go
generated
vendored
@ -13,19 +13,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// tokenListContainsValue returns true if the 1#token header with the given
|
|
||||||
// name contains token.
|
|
||||||
func tokenListContainsValue(header http.Header, name string, value string) bool {
|
|
||||||
for _, v := range header[name] {
|
|
||||||
for _, s := range strings.Split(v, ",") {
|
|
||||||
if strings.EqualFold(value, strings.TrimSpace(s)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||||
|
|
||||||
func computeAcceptKey(challengeKey string) string {
|
func computeAcceptKey(challengeKey string) string {
|
||||||
@ -42,3 +29,186 @@ func generateChallengeKey() (string, error) {
|
|||||||
}
|
}
|
||||||
return base64.StdEncoding.EncodeToString(p), nil
|
return base64.StdEncoding.EncodeToString(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Octet types from RFC 2616.
|
||||||
|
var octetTypes [256]byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
isTokenOctet = 1 << iota
|
||||||
|
isSpaceOctet
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// From RFC 2616
|
||||||
|
//
|
||||||
|
// OCTET = <any 8-bit sequence of data>
|
||||||
|
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||||
|
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||||
|
// CR = <US-ASCII CR, carriage return (13)>
|
||||||
|
// LF = <US-ASCII LF, linefeed (10)>
|
||||||
|
// SP = <US-ASCII SP, space (32)>
|
||||||
|
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||||
|
// <"> = <US-ASCII double-quote mark (34)>
|
||||||
|
// CRLF = CR LF
|
||||||
|
// LWS = [CRLF] 1*( SP | HT )
|
||||||
|
// TEXT = <any OCTET except CTLs, but including LWS>
|
||||||
|
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
|
||||||
|
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||||
|
// token = 1*<any CHAR except CTLs or separators>
|
||||||
|
// qdtext = <any TEXT except <">>
|
||||||
|
|
||||||
|
for c := 0; c < 256; c++ {
|
||||||
|
var t byte
|
||||||
|
isCtl := c <= 31 || c == 127
|
||||||
|
isChar := 0 <= c && c <= 127
|
||||||
|
isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
|
||||||
|
if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
|
||||||
|
t |= isSpaceOctet
|
||||||
|
}
|
||||||
|
if isChar && !isCtl && !isSeparator {
|
||||||
|
t |= isTokenOctet
|
||||||
|
}
|
||||||
|
octetTypes[c] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipSpace(s string) (rest string) {
|
||||||
|
i := 0
|
||||||
|
for ; i < len(s); i++ {
|
||||||
|
if octetTypes[s[i]]&isSpaceOctet == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[i:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextToken(s string) (token, rest string) {
|
||||||
|
i := 0
|
||||||
|
for ; i < len(s); i++ {
|
||||||
|
if octetTypes[s[i]]&isTokenOctet == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:i], s[i:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextTokenOrQuoted(s string) (value string, rest string) {
|
||||||
|
if !strings.HasPrefix(s, "\"") {
|
||||||
|
return nextToken(s)
|
||||||
|
}
|
||||||
|
s = s[1:]
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
switch s[i] {
|
||||||
|
case '"':
|
||||||
|
return s[:i], s[i+1:]
|
||||||
|
case '\\':
|
||||||
|
p := make([]byte, len(s)-1)
|
||||||
|
j := copy(p, s[:i])
|
||||||
|
escape := true
|
||||||
|
for i = i + 1; i < len(s); i++ {
|
||||||
|
b := s[i]
|
||||||
|
switch {
|
||||||
|
case escape:
|
||||||
|
escape = false
|
||||||
|
p[j] = b
|
||||||
|
j += 1
|
||||||
|
case b == '\\':
|
||||||
|
escape = true
|
||||||
|
case b == '"':
|
||||||
|
return string(p[:j]), s[i+1:]
|
||||||
|
default:
|
||||||
|
p[j] = b
|
||||||
|
j += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// tokenListContainsValue returns true if the 1#token header with the given
|
||||||
|
// name contains token.
|
||||||
|
func tokenListContainsValue(header http.Header, name string, value string) bool {
|
||||||
|
headers:
|
||||||
|
for _, s := range header[name] {
|
||||||
|
for {
|
||||||
|
var t string
|
||||||
|
t, s = nextToken(skipSpace(s))
|
||||||
|
if t == "" {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
s = skipSpace(s)
|
||||||
|
if s != "" && s[0] != ',' {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
if strings.EqualFold(t, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if s == "" {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseExtensiosn parses WebSocket extensions from a header.
|
||||||
|
func parseExtensions(header http.Header) []map[string]string {
|
||||||
|
|
||||||
|
// From RFC 6455:
|
||||||
|
//
|
||||||
|
// Sec-WebSocket-Extensions = extension-list
|
||||||
|
// extension-list = 1#extension
|
||||||
|
// extension = extension-token *( ";" extension-param )
|
||||||
|
// extension-token = registered-token
|
||||||
|
// registered-token = token
|
||||||
|
// extension-param = token [ "=" (token | quoted-string) ]
|
||||||
|
// ;When using the quoted-string syntax variant, the value
|
||||||
|
// ;after quoted-string unescaping MUST conform to the
|
||||||
|
// ;'token' ABNF.
|
||||||
|
|
||||||
|
var result []map[string]string
|
||||||
|
headers:
|
||||||
|
for _, s := range header["Sec-Websocket-Extensions"] {
|
||||||
|
for {
|
||||||
|
var t string
|
||||||
|
t, s = nextToken(skipSpace(s))
|
||||||
|
if t == "" {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
ext := map[string]string{"": t}
|
||||||
|
for {
|
||||||
|
s = skipSpace(s)
|
||||||
|
if !strings.HasPrefix(s, ";") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var k string
|
||||||
|
k, s = nextToken(skipSpace(s[1:]))
|
||||||
|
if k == "" {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
s = skipSpace(s)
|
||||||
|
var v string
|
||||||
|
if strings.HasPrefix(s, "=") {
|
||||||
|
v, s = nextTokenOrQuoted(skipSpace(s[1:]))
|
||||||
|
s = skipSpace(s)
|
||||||
|
}
|
||||||
|
if s != "" && s[0] != ',' && s[0] != ';' {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
ext[k] = v
|
||||||
|
}
|
||||||
|
if s != "" && s[0] != ',' {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
result = append(result, ext)
|
||||||
|
if s == "" {
|
||||||
|
continue headers
|
||||||
|
}
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
21
vendor/github.com/jpillora/backoff/LICENSE
generated
vendored
Normal file
21
vendor/github.com/jpillora/backoff/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 Jaime Pillora
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
83
vendor/github.com/jpillora/backoff/backoff.go
generated
vendored
83
vendor/github.com/jpillora/backoff/backoff.go
generated
vendored
@ -1,3 +1,4 @@
|
|||||||
|
// Package backoff provides an exponential-backoff implementation.
|
||||||
package backoff
|
package backoff
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,64 +7,82 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Backoff is a time.Duration counter. It starts at Min.
|
// Backoff is a time.Duration counter, starting at Min. After every call to
|
||||||
//After every call to Duration() it is multiplied by Factor.
|
// the Duration method the current timing is multiplied by Factor, but it
|
||||||
//It is capped at Max. It returns to Min on every call to Reset().
|
// never exceeds Max.
|
||||||
//Used in conjunction with the time package.
|
|
||||||
//
|
//
|
||||||
// Backoff is not threadsafe, but the ForAttempt method can be
|
// Backoff is not generally concurrent-safe, but the ForAttempt method can
|
||||||
// used concurrently if non-zero values for Factor, Max, and Min
|
// be used concurrently.
|
||||||
// are set on the Backoff shared among threads.
|
|
||||||
type Backoff struct {
|
type Backoff struct {
|
||||||
//Factor is the multiplying factor for each increment step
|
//Factor is the multiplying factor for each increment step
|
||||||
attempts, Factor float64
|
attempt, Factor float64
|
||||||
//Jitter eases contention by randomizing backoff steps
|
//Jitter eases contention by randomizing backoff steps
|
||||||
Jitter bool
|
Jitter bool
|
||||||
//Min and Max are the minimum and maximum values of the counter
|
//Min and Max are the minimum and maximum values of the counter
|
||||||
Min, Max time.Duration
|
Min, Max time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the current value of the counter and then
|
// Duration returns the duration for the current attempt before incrementing
|
||||||
//multiplies it Factor
|
// the attempt counter. See ForAttempt.
|
||||||
func (b *Backoff) Duration() time.Duration {
|
func (b *Backoff) Duration() time.Duration {
|
||||||
d := b.ForAttempt(b.attempts)
|
d := b.ForAttempt(b.attempt)
|
||||||
b.attempts++
|
b.attempt++
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maxInt64 = float64(math.MaxInt64 - 512)
|
||||||
|
|
||||||
// ForAttempt returns the duration for a specific attempt. This is useful if
|
// ForAttempt returns the duration for a specific attempt. This is useful if
|
||||||
// you have a large number of independent Backoffs, but don't want use
|
// you have a large number of independent Backoffs, but don't want use
|
||||||
// unnecessary memory storing the Backoff parameters per Backoff. The first
|
// unnecessary memory storing the Backoff parameters per Backoff. The first
|
||||||
// attempt should be 0.
|
// attempt should be 0.
|
||||||
//
|
//
|
||||||
// ForAttempt is threadsafe iff non-zero values for Factor, Max, and Min
|
// ForAttempt is concurrent-safe.
|
||||||
// are set before any calls to ForAttempt are made.
|
|
||||||
func (b *Backoff) ForAttempt(attempt float64) time.Duration {
|
func (b *Backoff) ForAttempt(attempt float64) time.Duration {
|
||||||
//Zero-values are nonsensical, so we use
|
// Zero-values are nonsensical, so we use
|
||||||
//them to apply defaults
|
// them to apply defaults
|
||||||
if b.Min == 0 {
|
min := b.Min
|
||||||
b.Min = 100 * time.Millisecond
|
if min <= 0 {
|
||||||
|
min = 100 * time.Millisecond
|
||||||
}
|
}
|
||||||
if b.Max == 0 {
|
max := b.Max
|
||||||
b.Max = 10 * time.Second
|
if max <= 0 {
|
||||||
|
max = 10 * time.Second
|
||||||
}
|
}
|
||||||
if b.Factor == 0 {
|
if min >= max {
|
||||||
b.Factor = 2
|
// short-circuit
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
factor := b.Factor
|
||||||
|
if factor <= 0 {
|
||||||
|
factor = 2
|
||||||
}
|
}
|
||||||
//calculate this duration
|
//calculate this duration
|
||||||
dur := float64(b.Min) * math.Pow(b.Factor, attempt)
|
minf := float64(min)
|
||||||
if b.Jitter == true {
|
durf := minf * math.Pow(factor, attempt)
|
||||||
dur = rand.Float64()*(dur-float64(b.Min)) + float64(b.Min)
|
if b.Jitter {
|
||||||
|
durf = rand.Float64()*(durf-minf) + minf
|
||||||
}
|
}
|
||||||
//cap!
|
//ensure float64 wont overflow int64
|
||||||
if dur > float64(b.Max) {
|
if durf > maxInt64 {
|
||||||
return b.Max
|
return max
|
||||||
}
|
}
|
||||||
//return as a time.Duration
|
dur := time.Duration(durf)
|
||||||
return time.Duration(dur)
|
//keep within bounds
|
||||||
|
if dur < min {
|
||||||
|
return min
|
||||||
|
} else if dur > max {
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
return dur
|
||||||
}
|
}
|
||||||
|
|
||||||
//Resets the current value of the counter back to Min
|
// Reset restarts the current attempt counter at zero.
|
||||||
func (b *Backoff) Reset() {
|
func (b *Backoff) Reset() {
|
||||||
b.attempts = 0
|
b.attempt = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt returns the current attempt counter value.
|
||||||
|
func (b *Backoff) Attempt() float64 {
|
||||||
|
return b.attempt
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/mattn/go-xmpp/xmpp.go
generated
vendored
8
vendor/github.com/mattn/go-xmpp/xmpp.go
generated
vendored
@ -606,7 +606,8 @@ func (c *Client) Recv() (stanza interface{}, err error) {
|
|||||||
case *clientPresence:
|
case *clientPresence:
|
||||||
return Presence{v.From, v.To, v.Type, v.Show, v.Status}, nil
|
return Presence{v.From, v.To, v.Type, v.Show, v.Status}, nil
|
||||||
case *clientIQ:
|
case *clientIQ:
|
||||||
if bytes.Equal(v.Query, []byte(`<ping xmlns='urn:xmpp:ping'/>`)) {
|
// TODO check more strictly
|
||||||
|
if bytes.Equal(v.Query, []byte(`<ping xmlns='urn:xmpp:ping'/>`)) || bytes.Equal(v.Query, []byte(`<ping xmlns="urn:xmpp:ping"/>`)) {
|
||||||
err := c.SendResultPing(v.ID, v.From)
|
err := c.SendResultPing(v.ID, v.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Chat{}, err
|
return Chat{}, err
|
||||||
@ -632,6 +633,11 @@ func (c *Client) SendPresence(presence Presence) (n int, err error) {
|
|||||||
return fmt.Fprintf(c.conn, "<presence from='%s' to='%s'/>", xmlEscape(presence.From), xmlEscape(presence.To))
|
return fmt.Fprintf(c.conn, "<presence from='%s' to='%s'/>", xmlEscape(presence.From), xmlEscape(presence.To))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendKeepAlive sends a "whitespace keepalive" as described in chapter 4.6.1 of RFC6120.
|
||||||
|
func (c *Client) SendKeepAlive() (n int, err error) {
|
||||||
|
return fmt.Fprintf(c.conn," ")
|
||||||
|
}
|
||||||
|
|
||||||
// SendHtml sends the message as HTML as defined by XEP-0071
|
// SendHtml sends the message as HTML as defined by XEP-0071
|
||||||
func (c *Client) SendHtml(chat Chat) (n int, err error) {
|
func (c *Client) SendHtml(chat Chat) (n int, err error) {
|
||||||
return fmt.Fprintf(c.conn, "<message to='%s' type='%s' xml:lang='en'>"+
|
return fmt.Fprintf(c.conn, "<message to='%s' type='%s' xml:lang='en'>"+
|
||||||
|
5
vendor/github.com/nlopes/slack/chat.go
generated
vendored
5
vendor/github.com/nlopes/slack/chat.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
DEFAULT_MESSAGE_USERNAME = ""
|
DEFAULT_MESSAGE_USERNAME = ""
|
||||||
|
DEFAULT_MESSAGE_THREAD_TIMESTAMP = ""
|
||||||
DEFAULT_MESSAGE_ASUSER = false
|
DEFAULT_MESSAGE_ASUSER = false
|
||||||
DEFAULT_MESSAGE_PARSE = ""
|
DEFAULT_MESSAGE_PARSE = ""
|
||||||
DEFAULT_MESSAGE_LINK_NAMES = 0
|
DEFAULT_MESSAGE_LINK_NAMES = 0
|
||||||
@ -33,6 +34,7 @@ type PostMessageParameters struct {
|
|||||||
Username string `json:"user_name"`
|
Username string `json:"user_name"`
|
||||||
AsUser bool `json:"as_user"`
|
AsUser bool `json:"as_user"`
|
||||||
Parse string `json:"parse"`
|
Parse string `json:"parse"`
|
||||||
|
ThreadTimestamp string `json:"thread_ts"`
|
||||||
LinkNames int `json:"link_names"`
|
LinkNames int `json:"link_names"`
|
||||||
Attachments []Attachment `json:"attachments"`
|
Attachments []Attachment `json:"attachments"`
|
||||||
UnfurlLinks bool `json:"unfurl_links"`
|
UnfurlLinks bool `json:"unfurl_links"`
|
||||||
@ -142,6 +144,9 @@ func (api *Client) PostMessage(channel, text string, params PostMessageParameter
|
|||||||
if params.Markdown != DEFAULT_MESSAGE_MARKDOWN {
|
if params.Markdown != DEFAULT_MESSAGE_MARKDOWN {
|
||||||
values.Set("mrkdwn", "false")
|
values.Set("mrkdwn", "false")
|
||||||
}
|
}
|
||||||
|
if params.ThreadTimestamp != DEFAULT_MESSAGE_THREAD_TIMESTAMP {
|
||||||
|
values.Set("thread_ts", params.ThreadTimestamp)
|
||||||
|
}
|
||||||
|
|
||||||
response, err := chatRequest("chat.postMessage", values, api.debug)
|
response, err := chatRequest("chat.postMessage", values, api.debug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
25
vendor/github.com/nlopes/slack/examples/team/team.go
generated
vendored
Normal file
25
vendor/github.com/nlopes/slack/examples/team/team.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nlopes/slack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
api := slack.New("YOUR_TOKEN_HERE")
|
||||||
|
//Example for single user
|
||||||
|
billingActive, err := api.GetBillableInfo("U023BECGF")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("ID: U023BECGF, BillingActive: %v\n\n\n", billingActive["U023BECGF"])
|
||||||
|
|
||||||
|
//Example for team
|
||||||
|
billingActiveForTeam, err := api.GetBillableInfoForTeam()
|
||||||
|
for id, value := range billingActiveForTeam {
|
||||||
|
fmt.Printf("ID: %v, BillingActive: %v\n", id, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
vendor/github.com/satori/go.uuid/LICENSE
generated
vendored
Normal file
20
vendor/github.com/satori/go.uuid/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
481
vendor/github.com/satori/go.uuid/uuid.go
generated
vendored
Normal file
481
vendor/github.com/satori/go.uuid/uuid.go
generated
vendored
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// Package uuid provides implementation of Universally Unique Identifier (UUID).
|
||||||
|
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
|
||||||
|
// version 2 (as specified in DCE 1.1).
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha1"
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UUID layout variants.
|
||||||
|
const (
|
||||||
|
VariantNCS = iota
|
||||||
|
VariantRFC4122
|
||||||
|
VariantMicrosoft
|
||||||
|
VariantFuture
|
||||||
|
)
|
||||||
|
|
||||||
|
// UUID DCE domains.
|
||||||
|
const (
|
||||||
|
DomainPerson = iota
|
||||||
|
DomainGroup
|
||||||
|
DomainOrg
|
||||||
|
)
|
||||||
|
|
||||||
|
// Difference in 100-nanosecond intervals between
|
||||||
|
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
||||||
|
const epochStart = 122192928000000000
|
||||||
|
|
||||||
|
// Used in string method conversion
|
||||||
|
const dash byte = '-'
|
||||||
|
|
||||||
|
// UUID v1/v2 storage.
|
||||||
|
var (
|
||||||
|
storageMutex sync.Mutex
|
||||||
|
storageOnce sync.Once
|
||||||
|
epochFunc = unixTimeFunc
|
||||||
|
clockSequence uint16
|
||||||
|
lastTime uint64
|
||||||
|
hardwareAddr [6]byte
|
||||||
|
posixUID = uint32(os.Getuid())
|
||||||
|
posixGID = uint32(os.Getgid())
|
||||||
|
)
|
||||||
|
|
||||||
|
// String parse helpers.
|
||||||
|
var (
|
||||||
|
urnPrefix = []byte("urn:uuid:")
|
||||||
|
byteGroups = []int{8, 4, 4, 4, 12}
|
||||||
|
)
|
||||||
|
|
||||||
|
func initClockSequence() {
|
||||||
|
buf := make([]byte, 2)
|
||||||
|
safeRandom(buf)
|
||||||
|
clockSequence = binary.BigEndian.Uint16(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initHardwareAddr() {
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err == nil {
|
||||||
|
for _, iface := range interfaces {
|
||||||
|
if len(iface.HardwareAddr) >= 6 {
|
||||||
|
copy(hardwareAddr[:], iface.HardwareAddr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize hardwareAddr randomly in case
|
||||||
|
// of real network interfaces absence
|
||||||
|
safeRandom(hardwareAddr[:])
|
||||||
|
|
||||||
|
// Set multicast bit as recommended in RFC 4122
|
||||||
|
hardwareAddr[0] |= 0x01
|
||||||
|
}
|
||||||
|
|
||||||
|
func initStorage() {
|
||||||
|
initClockSequence()
|
||||||
|
initHardwareAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func safeRandom(dest []byte) {
|
||||||
|
if _, err := rand.Read(dest); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns difference in 100-nanosecond intervals between
|
||||||
|
// UUID epoch (October 15, 1582) and current time.
|
||||||
|
// This is default epoch calculation function.
|
||||||
|
func unixTimeFunc() uint64 {
|
||||||
|
return epochStart + uint64(time.Now().UnixNano()/100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UUID representation compliant with specification
|
||||||
|
// described in RFC 4122.
|
||||||
|
type UUID [16]byte
|
||||||
|
|
||||||
|
// NullUUID can be used with the standard sql package to represent a
|
||||||
|
// UUID value that can be NULL in the database
|
||||||
|
type NullUUID struct {
|
||||||
|
UUID UUID
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// The nil UUID is special form of UUID that is specified to have all
|
||||||
|
// 128 bits set to zero.
|
||||||
|
var Nil = UUID{}
|
||||||
|
|
||||||
|
// Predefined namespace UUIDs.
|
||||||
|
var (
|
||||||
|
NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
||||||
|
NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
|
||||||
|
NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
|
||||||
|
NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
|
||||||
|
)
|
||||||
|
|
||||||
|
// And returns result of binary AND of two UUIDs.
|
||||||
|
func And(u1 UUID, u2 UUID) UUID {
|
||||||
|
u := UUID{}
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
u[i] = u1[i] & u2[i]
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns result of binary OR of two UUIDs.
|
||||||
|
func Or(u1 UUID, u2 UUID) UUID {
|
||||||
|
u := UUID{}
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
u[i] = u1[i] | u2[i]
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if u1 and u2 equals, otherwise returns false.
|
||||||
|
func Equal(u1 UUID, u2 UUID) bool {
|
||||||
|
return bytes.Equal(u1[:], u2[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns algorithm version used to generate UUID.
|
||||||
|
func (u UUID) Version() uint {
|
||||||
|
return uint(u[6] >> 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant returns UUID layout variant.
|
||||||
|
func (u UUID) Variant() uint {
|
||||||
|
switch {
|
||||||
|
case (u[8] & 0x80) == 0x00:
|
||||||
|
return VariantNCS
|
||||||
|
case (u[8]&0xc0)|0x80 == 0x80:
|
||||||
|
return VariantRFC4122
|
||||||
|
case (u[8]&0xe0)|0xc0 == 0xc0:
|
||||||
|
return VariantMicrosoft
|
||||||
|
}
|
||||||
|
return VariantFuture
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns bytes slice representation of UUID.
|
||||||
|
func (u UUID) Bytes() []byte {
|
||||||
|
return u[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns canonical string representation of UUID:
|
||||||
|
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
||||||
|
func (u UUID) String() string {
|
||||||
|
buf := make([]byte, 36)
|
||||||
|
|
||||||
|
hex.Encode(buf[0:8], u[0:4])
|
||||||
|
buf[8] = dash
|
||||||
|
hex.Encode(buf[9:13], u[4:6])
|
||||||
|
buf[13] = dash
|
||||||
|
hex.Encode(buf[14:18], u[6:8])
|
||||||
|
buf[18] = dash
|
||||||
|
hex.Encode(buf[19:23], u[8:10])
|
||||||
|
buf[23] = dash
|
||||||
|
hex.Encode(buf[24:], u[10:])
|
||||||
|
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVersion sets version bits.
|
||||||
|
func (u *UUID) SetVersion(v byte) {
|
||||||
|
u[6] = (u[6] & 0x0f) | (v << 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVariant sets variant bits as described in RFC 4122.
|
||||||
|
func (u *UUID) SetVariant() {
|
||||||
|
u[8] = (u[8] & 0xbf) | 0x80
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText implements the encoding.TextMarshaler interface.
|
||||||
|
// The encoding is the same as returned by String.
|
||||||
|
func (u UUID) MarshalText() (text []byte, err error) {
|
||||||
|
text = []byte(u.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||||
|
// Following formats are supported:
|
||||||
|
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
||||||
|
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
|
||||||
|
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||||
|
func (u *UUID) UnmarshalText(text []byte) (err error) {
|
||||||
|
if len(text) < 32 {
|
||||||
|
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t := text[:]
|
||||||
|
braced := false
|
||||||
|
|
||||||
|
if bytes.Equal(t[:9], urnPrefix) {
|
||||||
|
t = t[9:]
|
||||||
|
} else if t[0] == '{' {
|
||||||
|
braced = true
|
||||||
|
t = t[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
b := u[:]
|
||||||
|
|
||||||
|
for i, byteGroup := range byteGroups {
|
||||||
|
if i > 0 {
|
||||||
|
if t[0] != '-' {
|
||||||
|
err = fmt.Errorf("uuid: invalid string format")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t = t[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(t) < byteGroup {
|
||||||
|
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == 4 && len(t) > byteGroup &&
|
||||||
|
((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
|
||||||
|
err = fmt.Errorf("uuid: UUID string too long: %s", text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t = t[byteGroup:]
|
||||||
|
b = b[byteGroup/2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
||||||
|
func (u UUID) MarshalBinary() (data []byte, err error) {
|
||||||
|
data = u.Bytes()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
||||||
|
// It will return error if the slice isn't 16 bytes long.
|
||||||
|
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
|
||||||
|
if len(data) != 16 {
|
||||||
|
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
copy(u[:], data)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver.Valuer interface.
|
||||||
|
func (u UUID) Value() (driver.Value, error) {
|
||||||
|
return u.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the sql.Scanner interface.
|
||||||
|
// A 16-byte slice is handled by UnmarshalBinary, while
|
||||||
|
// a longer byte slice or a string is handled by UnmarshalText.
|
||||||
|
func (u *UUID) Scan(src interface{}) error {
|
||||||
|
switch src := src.(type) {
|
||||||
|
case []byte:
|
||||||
|
if len(src) == 16 {
|
||||||
|
return u.UnmarshalBinary(src)
|
||||||
|
}
|
||||||
|
return u.UnmarshalText(src)
|
||||||
|
|
||||||
|
case string:
|
||||||
|
return u.UnmarshalText([]byte(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver.Valuer interface.
|
||||||
|
func (u NullUUID) Value() (driver.Value, error) {
|
||||||
|
if !u.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// Delegate to UUID Value function
|
||||||
|
return u.UUID.Value()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the sql.Scanner interface.
|
||||||
|
func (u *NullUUID) Scan(src interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
u.UUID, u.Valid = Nil, false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delegate to UUID Scan function
|
||||||
|
u.Valid = true
|
||||||
|
return u.UUID.Scan(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytes returns UUID converted from raw byte slice input.
|
||||||
|
// It will return error if the slice isn't 16 bytes long.
|
||||||
|
func FromBytes(input []byte) (u UUID, err error) {
|
||||||
|
err = u.UnmarshalBinary(input)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytesOrNil returns UUID converted from raw byte slice input.
|
||||||
|
// Same behavior as FromBytes, but returns a Nil UUID on error.
|
||||||
|
func FromBytesOrNil(input []byte) UUID {
|
||||||
|
uuid, err := FromBytes(input)
|
||||||
|
if err != nil {
|
||||||
|
return Nil
|
||||||
|
}
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString returns UUID parsed from string input.
|
||||||
|
// Input is expected in a form accepted by UnmarshalText.
|
||||||
|
func FromString(input string) (u UUID, err error) {
|
||||||
|
err = u.UnmarshalText([]byte(input))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStringOrNil returns UUID parsed from string input.
|
||||||
|
// Same behavior as FromString, but returns a Nil UUID on error.
|
||||||
|
func FromStringOrNil(input string) UUID {
|
||||||
|
uuid, err := FromString(input)
|
||||||
|
if err != nil {
|
||||||
|
return Nil
|
||||||
|
}
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns UUID v1/v2 storage state.
|
||||||
|
// Returns epoch timestamp, clock sequence, and hardware address.
|
||||||
|
func getStorage() (uint64, uint16, []byte) {
|
||||||
|
storageOnce.Do(initStorage)
|
||||||
|
|
||||||
|
storageMutex.Lock()
|
||||||
|
defer storageMutex.Unlock()
|
||||||
|
|
||||||
|
timeNow := epochFunc()
|
||||||
|
// Clock changed backwards since last UUID generation.
|
||||||
|
// Should increase clock sequence.
|
||||||
|
if timeNow <= lastTime {
|
||||||
|
clockSequence++
|
||||||
|
}
|
||||||
|
lastTime = timeNow
|
||||||
|
|
||||||
|
return timeNow, clockSequence, hardwareAddr[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV1 returns UUID based on current timestamp and MAC address.
|
||||||
|
func NewV1() UUID {
|
||||||
|
u := UUID{}
|
||||||
|
|
||||||
|
timeNow, clockSeq, hardwareAddr := getStorage()
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
|
||||||
|
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
||||||
|
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
||||||
|
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
||||||
|
|
||||||
|
copy(u[10:], hardwareAddr)
|
||||||
|
|
||||||
|
u.SetVersion(1)
|
||||||
|
u.SetVariant()
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
|
||||||
|
func NewV2(domain byte) UUID {
|
||||||
|
u := UUID{}
|
||||||
|
|
||||||
|
timeNow, clockSeq, hardwareAddr := getStorage()
|
||||||
|
|
||||||
|
switch domain {
|
||||||
|
case DomainPerson:
|
||||||
|
binary.BigEndian.PutUint32(u[0:], posixUID)
|
||||||
|
case DomainGroup:
|
||||||
|
binary.BigEndian.PutUint32(u[0:], posixGID)
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
||||||
|
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
||||||
|
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
||||||
|
u[9] = domain
|
||||||
|
|
||||||
|
copy(u[10:], hardwareAddr)
|
||||||
|
|
||||||
|
u.SetVersion(2)
|
||||||
|
u.SetVariant()
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
|
||||||
|
func NewV3(ns UUID, name string) UUID {
|
||||||
|
u := newFromHash(md5.New(), ns, name)
|
||||||
|
u.SetVersion(3)
|
||||||
|
u.SetVariant()
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV4 returns random generated UUID.
|
||||||
|
func NewV4() UUID {
|
||||||
|
u := UUID{}
|
||||||
|
safeRandom(u[:])
|
||||||
|
u.SetVersion(4)
|
||||||
|
u.SetVariant()
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
|
||||||
|
func NewV5(ns UUID, name string) UUID {
|
||||||
|
u := newFromHash(sha1.New(), ns, name)
|
||||||
|
u.SetVersion(5)
|
||||||
|
u.SetVariant()
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns UUID based on hashing of namespace UUID and name.
|
||||||
|
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
||||||
|
u := UUID{}
|
||||||
|
h.Write(ns[:])
|
||||||
|
h.Write([]byte(name))
|
||||||
|
copy(u[:], h.Sum(nil))
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
13
vendor/github.com/sromku/go-gitter/stream.go
generated
vendored
13
vendor/github.com/sromku/go-gitter/stream.go
generated
vendored
@ -112,6 +112,7 @@ type Stream struct {
|
|||||||
|
|
||||||
func (stream *Stream) destroy() {
|
func (stream *Stream) destroy() {
|
||||||
close(stream.Event)
|
close(stream.Event)
|
||||||
|
stream.streamConnection.currentRetries = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
@ -135,10 +136,8 @@ func (stream *Stream) connect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res, err := stream.gitter.getResponse(stream.url, stream)
|
res, err := stream.gitter.getResponse(stream.url, stream)
|
||||||
if stream.streamConnection.canceled {
|
if err != nil || res.StatusCode != 200 {
|
||||||
// do nothing
|
stream.gitter.log(fmt.Sprintf("Failed to get response, trying reconnect (Status code: %v)", res.StatusCode))
|
||||||
} else if err != nil || res.StatusCode != 200 {
|
|
||||||
stream.gitter.log("Failed to get response, trying reconnect ")
|
|
||||||
stream.gitter.log(err)
|
stream.gitter.log(err)
|
||||||
|
|
||||||
// sleep and wait
|
// sleep and wait
|
||||||
@ -161,9 +160,6 @@ type streamConnection struct {
|
|||||||
// connection was closed
|
// connection was closed
|
||||||
closed bool
|
closed bool
|
||||||
|
|
||||||
// canceled
|
|
||||||
canceled bool
|
|
||||||
|
|
||||||
// wait time till next try
|
// wait time till next try
|
||||||
wait time.Duration
|
wait time.Duration
|
||||||
|
|
||||||
@ -192,13 +188,10 @@ func (stream *Stream) Close() {
|
|||||||
stream.gitter.log("Stream connection close request")
|
stream.gitter.log("Stream connection close request")
|
||||||
switch transport := stream.gitter.config.client.Transport.(type) {
|
switch transport := stream.gitter.config.client.Transport.(type) {
|
||||||
case *httpclient.Transport:
|
case *httpclient.Transport:
|
||||||
stream.streamConnection.canceled = true
|
|
||||||
transport.CancelRequest(conn.request)
|
transport.CancelRequest(conn.request)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
conn.currentRetries = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stream *Stream) isClosed() bool {
|
func (stream *Stream) isClosed() bool {
|
||||||
|
15
vendor/golang.org/x/net/websocket/client.go
generated
vendored
15
vendor/golang.org/x/net/websocket/client.go
generated
vendored
@ -6,7 +6,6 @@ package websocket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -87,20 +86,14 @@ func DialConfig(config *Config) (ws *Conn, err error) {
|
|||||||
if config.Origin == nil {
|
if config.Origin == nil {
|
||||||
return nil, &DialError{config, ErrBadWebSocketOrigin}
|
return nil, &DialError{config, ErrBadWebSocketOrigin}
|
||||||
}
|
}
|
||||||
switch config.Location.Scheme {
|
dialer := config.Dialer
|
||||||
case "ws":
|
if dialer == nil {
|
||||||
client, err = net.Dial("tcp", parseAuthority(config.Location))
|
dialer = &net.Dialer{}
|
||||||
|
|
||||||
case "wss":
|
|
||||||
client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig)
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = ErrBadScheme
|
|
||||||
}
|
}
|
||||||
|
client, err = dialWithDialer(dialer, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
|
||||||
ws, err = NewClient(config, client)
|
ws, err = NewClient(config, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
client.Close()
|
client.Close()
|
||||||
|
24
vendor/golang.org/x/net/websocket/dial.go
generated
vendored
Normal file
24
vendor/golang.org/x/net/websocket/dial.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package websocket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dialWithDialer(dialer *net.Dialer, config *Config) (conn net.Conn, err error) {
|
||||||
|
switch config.Location.Scheme {
|
||||||
|
case "ws":
|
||||||
|
conn, err = dialer.Dial("tcp", parseAuthority(config.Location))
|
||||||
|
|
||||||
|
case "wss":
|
||||||
|
conn, err = tls.DialWithDialer(dialer, "tcp", parseAuthority(config.Location), config.TlsConfig)
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = ErrBadScheme
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
39
vendor/golang.org/x/net/websocket/websocket.go
generated
vendored
39
vendor/golang.org/x/net/websocket/websocket.go
generated
vendored
@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
// Package websocket implements a client and server for the WebSocket protocol
|
// Package websocket implements a client and server for the WebSocket protocol
|
||||||
// as specified in RFC 6455.
|
// as specified in RFC 6455.
|
||||||
|
//
|
||||||
|
// This package currently lacks some features found in an alternative
|
||||||
|
// and more actively maintained WebSocket package:
|
||||||
|
//
|
||||||
|
// https://godoc.org/github.com/gorilla/websocket
|
||||||
|
//
|
||||||
package websocket // import "golang.org/x/net/websocket"
|
package websocket // import "golang.org/x/net/websocket"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -32,6 +38,8 @@ const (
|
|||||||
PingFrame = 9
|
PingFrame = 9
|
||||||
PongFrame = 10
|
PongFrame = 10
|
||||||
UnknownFrame = 255
|
UnknownFrame = 255
|
||||||
|
|
||||||
|
DefaultMaxPayloadBytes = 32 << 20 // 32MB
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProtocolError represents WebSocket protocol errors.
|
// ProtocolError represents WebSocket protocol errors.
|
||||||
@ -58,6 +66,10 @@ var (
|
|||||||
ErrNotSupported = &ProtocolError{"not supported"}
|
ErrNotSupported = &ProtocolError{"not supported"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrFrameTooLarge is returned by Codec's Receive method if payload size
|
||||||
|
// exceeds limit set by Conn.MaxPayloadBytes
|
||||||
|
var ErrFrameTooLarge = errors.New("websocket: frame payload size exceeds limit")
|
||||||
|
|
||||||
// Addr is an implementation of net.Addr for WebSocket.
|
// Addr is an implementation of net.Addr for WebSocket.
|
||||||
type Addr struct {
|
type Addr struct {
|
||||||
*url.URL
|
*url.URL
|
||||||
@ -86,6 +98,9 @@ type Config struct {
|
|||||||
// Additional header fields to be sent in WebSocket opening handshake.
|
// Additional header fields to be sent in WebSocket opening handshake.
|
||||||
Header http.Header
|
Header http.Header
|
||||||
|
|
||||||
|
// Dialer used when opening websocket connections.
|
||||||
|
Dialer *net.Dialer
|
||||||
|
|
||||||
handshakeData map[string]string
|
handshakeData map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +178,10 @@ type Conn struct {
|
|||||||
frameHandler
|
frameHandler
|
||||||
PayloadType byte
|
PayloadType byte
|
||||||
defaultCloseStatus int
|
defaultCloseStatus int
|
||||||
|
|
||||||
|
// MaxPayloadBytes limits the size of frame payload received over Conn
|
||||||
|
// by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used.
|
||||||
|
MaxPayloadBytes int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read implements the io.Reader interface:
|
// Read implements the io.Reader interface:
|
||||||
@ -299,7 +318,12 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v.
|
// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores
|
||||||
|
// in v. The whole frame payload is read to an in-memory buffer; max size of
|
||||||
|
// payload is defined by ws.MaxPayloadBytes. If frame payload size exceeds
|
||||||
|
// limit, ErrFrameTooLarge is returned; in this case frame is not read off wire
|
||||||
|
// completely. The next call to Receive would read and discard leftover data of
|
||||||
|
// previous oversized frame before processing next frame.
|
||||||
func (cd Codec) Receive(ws *Conn, v interface{}) (err error) {
|
func (cd Codec) Receive(ws *Conn, v interface{}) (err error) {
|
||||||
ws.rio.Lock()
|
ws.rio.Lock()
|
||||||
defer ws.rio.Unlock()
|
defer ws.rio.Unlock()
|
||||||
@ -322,6 +346,19 @@ again:
|
|||||||
if frame == nil {
|
if frame == nil {
|
||||||
goto again
|
goto again
|
||||||
}
|
}
|
||||||
|
maxPayloadBytes := ws.MaxPayloadBytes
|
||||||
|
if maxPayloadBytes == 0 {
|
||||||
|
maxPayloadBytes = DefaultMaxPayloadBytes
|
||||||
|
}
|
||||||
|
if hf, ok := frame.(*hybiFrameReader); ok && hf.header.Length > int64(maxPayloadBytes) {
|
||||||
|
// payload size exceeds limit, no need to call Unmarshal
|
||||||
|
//
|
||||||
|
// set frameReader to current oversized frame so that
|
||||||
|
// the next call to this function can drain leftover
|
||||||
|
// data before processing the next frame
|
||||||
|
ws.frameReader = frame
|
||||||
|
return ErrFrameTooLarge
|
||||||
|
}
|
||||||
payloadType := frame.PayloadType()
|
payloadType := frame.PayloadType()
|
||||||
data, err := ioutil.ReadAll(frame)
|
data, err := ioutil.ReadAll(frame)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
27
vendor/golang.org/x/sys/unix/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/unix/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
// +build arm,darwin
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
// +build arm64,darwin
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, DragonFly
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-112
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
35
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
35
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for 386, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
||||||
|
JMP syscall·socketcall(SB)
|
||||||
|
|
||||||
|
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
||||||
|
JMP syscall·rawsocketcall(SB)
|
||||||
|
|
||||||
|
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·seek(SB)
|
29
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for AMD64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
||||||
|
JMP syscall·gettimeofday(SB)
|
29
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for arm, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·seek(SB),NOSPLIT,$0-32
|
||||||
|
B syscall·seek(SB)
|
24
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
24
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build arm64
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build mips64 mips64le
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for mips64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
31
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
31
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build mips mipsle
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for mips, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for ppc64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build s390x
|
||||||
|
// +build linux
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for s390x, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
||||||
|
//
|
||||||
|
|
||||||
|
TEXT ·sysvicall6(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·sysvicall6(SB)
|
||||||
|
|
||||||
|
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·rawSysvicall6(SB)
|
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Bluetooth sockets and messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
// Bluetooth Protocols
|
||||||
|
const (
|
||||||
|
BTPROTO_L2CAP = 0
|
||||||
|
BTPROTO_HCI = 1
|
||||||
|
BTPROTO_SCO = 2
|
||||||
|
BTPROTO_RFCOMM = 3
|
||||||
|
BTPROTO_BNEP = 4
|
||||||
|
BTPROTO_CMTP = 5
|
||||||
|
BTPROTO_HIDP = 6
|
||||||
|
BTPROTO_AVDTP = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HCI_CHANNEL_RAW = 0
|
||||||
|
HCI_CHANNEL_USER = 1
|
||||||
|
HCI_CHANNEL_MONITOR = 2
|
||||||
|
HCI_CHANNEL_CONTROL = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socketoption Level
|
||||||
|
const (
|
||||||
|
SOL_BLUETOOTH = 0x112
|
||||||
|
SOL_HCI = 0x0
|
||||||
|
SOL_L2CAP = 0x6
|
||||||
|
SOL_RFCOMM = 0x12
|
||||||
|
SOL_SCO = 0x11
|
||||||
|
)
|
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
const (
|
||||||
|
R_OK = 0x4
|
||||||
|
W_OK = 0x2
|
||||||
|
X_OK = 0x1
|
||||||
|
)
|
27
vendor/golang.org/x/sys/unix/env_unix.go
generated
vendored
Normal file
27
vendor/golang.org/x/sys/unix/env_unix.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Unix environment variables.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func Getenv(key string) (value string, found bool) {
|
||||||
|
return syscall.Getenv(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setenv(key, value string) error {
|
||||||
|
return syscall.Setenv(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clearenv() {
|
||||||
|
syscall.Clearenv()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Environ() []string {
|
||||||
|
return syscall.Environ()
|
||||||
|
}
|
14
vendor/golang.org/x/sys/unix/env_unset.go
generated
vendored
Normal file
14
vendor/golang.org/x/sys/unix/env_unset.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.4
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func Unsetenv(key string) error {
|
||||||
|
// This was added in Go 1.4.
|
||||||
|
return syscall.Unsetenv(key)
|
||||||
|
}
|
24
vendor/golang.org/x/sys/unix/flock.go
generated
vendored
Normal file
24
vendor/golang.org/x/sys/unix/flock.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||||
|
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
||||||
|
// systems by flock_linux_32bit.go to be SYS_FCNTL64.
|
||||||
|
var fcntl64Syscall uintptr = SYS_FCNTL
|
||||||
|
|
||||||
|
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||||
|
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||||
|
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
||||||
|
if errno == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errno
|
||||||
|
}
|
13
vendor/golang.org/x/sys/unix/flock_linux_32bit.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/flock_linux_32bit.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build linux,386 linux,arm linux,mips linux,mipsle
|
||||||
|
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// On 32-bit Linux systems, the fcntl syscall that matches Go's
|
||||||
|
// Flock_t type is SYS_FCNTL64, not SYS_FCNTL.
|
||||||
|
fcntl64Syscall = SYS_FCNTL64
|
||||||
|
}
|
46
vendor/golang.org/x/sys/unix/gccgo.go
generated
vendored
Normal file
46
vendor/golang.org/x/sys/unix/gccgo.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// We can't use the gc-syntax .s files for gccgo. On the plus side
|
||||||
|
// much of the functionality can be written directly in Go.
|
||||||
|
|
||||||
|
//extern gccgoRealSyscall
|
||||||
|
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
|
||||||
|
|
||||||
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
41
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
Normal file
41
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define _STRINGIFY2_(x) #x
|
||||||
|
#define _STRINGIFY_(x) _STRINGIFY2_(x)
|
||||||
|
#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
|
||||||
|
|
||||||
|
// Call syscall from C code because the gccgo support for calling from
|
||||||
|
// Go to C does not support varargs functions.
|
||||||
|
|
||||||
|
struct ret {
|
||||||
|
uintptr_t r;
|
||||||
|
uintptr_t err;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ret
|
||||||
|
gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
||||||
|
{
|
||||||
|
struct ret r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||||
|
r.err = errno;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the use function in C so that it is not inlined.
|
||||||
|
|
||||||
|
extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
|
||||||
|
|
||||||
|
void
|
||||||
|
use(void *p __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
}
|
20
vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
generated
vendored
Normal file
20
vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo,linux,amd64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
//extern gettimeofday
|
||||||
|
func realGettimeofday(*Timeval, *byte) int32
|
||||||
|
|
||||||
|
func gettimeofday(tv *Timeval) (err syscall.Errno) {
|
||||||
|
r := realGettimeofday(tv, nil)
|
||||||
|
if r < 0 {
|
||||||
|
return syscall.GetErrno()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
20
vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
generated
vendored
Normal file
20
vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo,linux,sparc64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
//extern sysconf
|
||||||
|
func realSysconf(name int) int64
|
||||||
|
|
||||||
|
func sysconf(name int) (n int64, err syscall.Errno) {
|
||||||
|
r := realSysconf(name)
|
||||||
|
if r < 0 {
|
||||||
|
return 0, syscall.GetErrno()
|
||||||
|
}
|
||||||
|
return r, 0
|
||||||
|
}
|
62
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
Normal file
62
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// mkpost processes the output of cgo -godefs to
|
||||||
|
// modify the generated types. It is used to clean up
|
||||||
|
// the sys API in an architecture specific manner.
|
||||||
|
//
|
||||||
|
// mkpost is run after cgo -godefs by mkall.sh.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b, err := ioutil.ReadAll(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
s := string(b)
|
||||||
|
|
||||||
|
goarch := os.Getenv("GOARCH")
|
||||||
|
goos := os.Getenv("GOOS")
|
||||||
|
if goarch == "s390x" && goos == "linux" {
|
||||||
|
// Export the types of PtraceRegs fields.
|
||||||
|
re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)")
|
||||||
|
s = re.ReplaceAllString(s, "Ptrace$1")
|
||||||
|
|
||||||
|
// Replace padding fields inserted by cgo with blank identifiers.
|
||||||
|
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
|
||||||
|
s = re.ReplaceAllString(s, "_")
|
||||||
|
|
||||||
|
// Replace other unwanted fields with blank identifiers.
|
||||||
|
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
|
||||||
|
s = re.ReplaceAllString(s, "_")
|
||||||
|
|
||||||
|
// Replace the control_regs union with a blank identifier for now.
|
||||||
|
re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64")
|
||||||
|
s = re.ReplaceAllString(s, "_ [0]uint64")
|
||||||
|
}
|
||||||
|
|
||||||
|
// gofmt
|
||||||
|
b, err = format.Source([]byte(s))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append this command to the header to show where the new file
|
||||||
|
// came from.
|
||||||
|
re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)")
|
||||||
|
b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go"))
|
||||||
|
|
||||||
|
fmt.Printf("%s", b)
|
||||||
|
}
|
38
vendor/golang.org/x/sys/unix/openbsd_pledge.go
generated
vendored
Normal file
38
vendor/golang.org/x/sys/unix/openbsd_pledge.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build openbsd
|
||||||
|
// +build 386 amd64 arm
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SYS_PLEDGE = 108
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pledge implements the pledge syscall. For more information see pledge(2).
|
||||||
|
func Pledge(promises string, paths []string) error {
|
||||||
|
promisesPtr, err := syscall.BytePtrFromString(promises)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil)
|
||||||
|
if paths != nil {
|
||||||
|
var pathsPtr []*byte
|
||||||
|
if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
|
||||||
|
}
|
||||||
|
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
|
||||||
|
if e != 0 {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
30
vendor/golang.org/x/sys/unix/race.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/race.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin,race linux,race freebsd,race
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = true
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceAcquire(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceReleaseMerge(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceReadRange(addr, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceWriteRange(addr, len)
|
||||||
|
}
|
25
vendor/golang.org/x/sys/unix/race0.go
generated
vendored
Normal file
25
vendor/golang.org/x/sys/unix/race0.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = false
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
36
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
Normal file
36
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Socket control messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// UnixCredentials encodes credentials into a socket control message
|
||||||
|
// for sending to another process. This can be used for
|
||||||
|
// authentication.
|
||||||
|
func UnixCredentials(ucred *Ucred) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofUcred))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_SOCKET
|
||||||
|
h.Type = SCM_CREDENTIALS
|
||||||
|
h.SetLen(CmsgLen(SizeofUcred))
|
||||||
|
*((*Ucred)(cmsgData(h))) = *ucred
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUnixCredentials decodes a socket control message that contains
|
||||||
|
// credentials in a Ucred structure. To receive such a message, the
|
||||||
|
// SO_PASSCRED option must be enabled on the socket.
|
||||||
|
func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
|
||||||
|
if m.Header.Level != SOL_SOCKET {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
if m.Header.Type != SCM_CREDENTIALS {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
return &ucred, nil
|
||||||
|
}
|
103
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
Normal file
103
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Socket control messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// Round the length of a raw sockaddr up to align it properly.
|
||||||
|
func cmsgAlignOf(salen int) int {
|
||||||
|
salign := sizeofPtr
|
||||||
|
// NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
|
||||||
|
// still require 32-bit aligned access to network subsystem.
|
||||||
|
if darwin64Bit || dragonfly64Bit {
|
||||||
|
salign = 4
|
||||||
|
}
|
||||||
|
return (salen + salign - 1) & ^(salign - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmsgLen returns the value to store in the Len field of the Cmsghdr
|
||||||
|
// structure, taking into account any necessary alignment.
|
||||||
|
func CmsgLen(datalen int) int {
|
||||||
|
return cmsgAlignOf(SizeofCmsghdr) + datalen
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmsgSpace returns the number of bytes an ancillary element with
|
||||||
|
// payload of the passed data length occupies.
|
||||||
|
func CmsgSpace(datalen int) int {
|
||||||
|
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmsgData(h *Cmsghdr) unsafe.Pointer {
|
||||||
|
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketControlMessage represents a socket control message.
|
||||||
|
type SocketControlMessage struct {
|
||||||
|
Header Cmsghdr
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSocketControlMessage parses b as an array of socket control
|
||||||
|
// messages.
|
||||||
|
func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
|
||||||
|
var msgs []SocketControlMessage
|
||||||
|
i := 0
|
||||||
|
for i+CmsgLen(0) <= len(b) {
|
||||||
|
h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m := SocketControlMessage{Header: *h, Data: dbuf}
|
||||||
|
msgs = append(msgs, m)
|
||||||
|
i += cmsgAlignOf(int(h.Len))
|
||||||
|
}
|
||||||
|
return msgs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
|
||||||
|
return nil, nil, EINVAL
|
||||||
|
}
|
||||||
|
return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnixRights encodes a set of open file descriptors into a socket
|
||||||
|
// control message for sending to another process.
|
||||||
|
func UnixRights(fds ...int) []byte {
|
||||||
|
datalen := len(fds) * 4
|
||||||
|
b := make([]byte, CmsgSpace(datalen))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_SOCKET
|
||||||
|
h.Type = SCM_RIGHTS
|
||||||
|
h.SetLen(CmsgLen(datalen))
|
||||||
|
data := cmsgData(h)
|
||||||
|
for _, fd := range fds {
|
||||||
|
*(*int32)(data) = int32(fd)
|
||||||
|
data = unsafe.Pointer(uintptr(data) + 4)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUnixRights decodes a socket control message that contains an
|
||||||
|
// integer array of open file descriptors from another process.
|
||||||
|
func ParseUnixRights(m *SocketControlMessage) ([]int, error) {
|
||||||
|
if m.Header.Level != SOL_SOCKET {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
if m.Header.Type != SCM_RIGHTS {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
fds := make([]int, len(m.Data)>>2)
|
||||||
|
for i, j := 0, 0; i < len(m.Data); i += 4 {
|
||||||
|
fds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i])))
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
return fds, nil
|
||||||
|
}
|
26
vendor/golang.org/x/sys/unix/str.go
generated
vendored
Normal file
26
vendor/golang.org/x/sys/unix/str.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||||
|
if val < 0 {
|
||||||
|
return "-" + uitoa(uint(-val))
|
||||||
|
}
|
||||||
|
return uitoa(uint(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
func uitoa(val uint) string {
|
||||||
|
var buf [32]byte // big enough for int64
|
||||||
|
i := len(buf) - 1
|
||||||
|
for val >= 10 {
|
||||||
|
buf[i] = byte(val%10 + '0')
|
||||||
|
i--
|
||||||
|
val /= 10
|
||||||
|
}
|
||||||
|
buf[i] = byte(val + '0')
|
||||||
|
return string(buf[i:])
|
||||||
|
}
|
69
vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
Normal file
69
vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Package unix contains an interface to the low-level operating system
|
||||||
|
// primitives. OS details vary depending on the underlying system, and
|
||||||
|
// by default, godoc will display OS-specific documentation for the current
|
||||||
|
// system. If you want godoc to display OS documentation for another
|
||||||
|
// system, set $GOOS and $GOARCH to the desired system. For example, if
|
||||||
|
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
|
||||||
|
// to freebsd and $GOARCH to arm.
|
||||||
|
// The primary use of this package is inside other packages that provide a more
|
||||||
|
// portable interface to the system, such as "os", "time" and "net". Use
|
||||||
|
// those packages rather than this one if you can.
|
||||||
|
// For details of the functions and data types in this package consult
|
||||||
|
// the manuals for the appropriate operating system.
|
||||||
|
// These calls return err == nil to indicate success; otherwise
|
||||||
|
// err represents an operating system error describing the failure and
|
||||||
|
// holds a value of type syscall.Errno.
|
||||||
|
package unix // import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||||
|
// containing the text of s. If s contains a NUL byte at any
|
||||||
|
// location, it returns (nil, EINVAL).
|
||||||
|
func ByteSliceFromString(s string) ([]byte, error) {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] == 0 {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a := make([]byte, len(s)+1)
|
||||||
|
copy(a, s)
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytePtrFromString returns a pointer to a NUL-terminated array of
|
||||||
|
// bytes containing the text of s. If s contains a NUL byte at any
|
||||||
|
// location, it returns (nil, EINVAL).
|
||||||
|
func BytePtrFromString(s string) (*byte, error) {
|
||||||
|
a, err := ByteSliceFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &a[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
// See mkunix.pl.
|
||||||
|
var _zero uintptr
|
||||||
|
|
||||||
|
func (ts *Timespec) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(ts.Sec), int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tv *Timeval) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(tv.Sec), int64(tv.Usec) * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *Timespec) Nano() int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tv *Timeval) Nano() int64 {
|
||||||
|
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
614
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
Normal file
614
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd netbsd openbsd
|
||||||
|
|
||||||
|
// BSD system call wrappers shared by *BSD based systems
|
||||||
|
// including OS X (Darwin) and FreeBSD. Like the other
|
||||||
|
// syscall_*.go files it is compiled as Go code but also
|
||||||
|
// used as input to mksyscall which parses the //sys
|
||||||
|
// lines and generates system call stubs.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
|
||||||
|
//sysnb setgroups(ngid int, gid *_Gid_t) (err error)
|
||||||
|
|
||||||
|
func Getgroups() (gids []int, err error) {
|
||||||
|
n, err := getgroups(0, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check group count. Max is 16 on BSD.
|
||||||
|
if n < 0 || n > 1000 {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, n)
|
||||||
|
n, err = getgroups(n, &a[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gids = make([]int, n)
|
||||||
|
for i, v := range a[0:n] {
|
||||||
|
gids[i] = int(v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setgroups(gids []int) (err error) {
|
||||||
|
if len(gids) == 0 {
|
||||||
|
return setgroups(0, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, len(gids))
|
||||||
|
for i, v := range gids {
|
||||||
|
a[i] = _Gid_t(v)
|
||||||
|
}
|
||||||
|
return setgroups(len(a), &a[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
||||||
|
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
|
||||||
|
// 64 bits should be enough. (32 bits isn't even on 386). Since the
|
||||||
|
// actual system call is getdirentries64, 64 is a good guess.
|
||||||
|
// TODO(rsc): Can we use a single global basep for all calls?
|
||||||
|
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
|
||||||
|
return Getdirentries(fd, buf, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||||
|
// 0x7F (stopped), or a signal number that caused an exit.
|
||||||
|
// The 0x80 bit is whether there was a core dump.
|
||||||
|
// An extra number (exit code, signal causing a stop)
|
||||||
|
// is in the high bits.
|
||||||
|
|
||||||
|
type WaitStatus uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
mask = 0x7F
|
||||||
|
core = 0x80
|
||||||
|
shift = 8
|
||||||
|
|
||||||
|
exited = 0
|
||||||
|
stopped = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||||
|
|
||||||
|
func (w WaitStatus) ExitStatus() int {
|
||||||
|
if w&mask != exited {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return int(w >> shift)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||||
|
|
||||||
|
func (w WaitStatus) Signal() syscall.Signal {
|
||||||
|
sig := syscall.Signal(w & mask)
|
||||||
|
if sig == stopped || sig == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return sig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
||||||
|
|
||||||
|
func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
|
||||||
|
|
||||||
|
func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
|
||||||
|
|
||||||
|
func (w WaitStatus) StopSignal() syscall.Signal {
|
||||||
|
if !w.Stopped() {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return syscall.Signal(w>>shift) & 0xFF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) TrapCause() int { return -1 }
|
||||||
|
|
||||||
|
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
|
||||||
|
|
||||||
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
|
||||||
|
var status _C_int
|
||||||
|
wpid, err = wait4(pid, &status, options, rusage)
|
||||||
|
if wstatus != nil {
|
||||||
|
*wstatus = WaitStatus(status)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||||
|
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||||
|
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||||
|
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||||
|
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sys Shutdown(s int, how int) (err error)
|
||||||
|
|
||||||
|
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet4
|
||||||
|
sa.raw.Family = AF_INET
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
|
p[0] = byte(sa.Port >> 8)
|
||||||
|
p[1] = byte(sa.Port)
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.raw.Addr[i] = sa.Addr[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet6
|
||||||
|
sa.raw.Family = AF_INET6
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
|
p[0] = byte(sa.Port >> 8)
|
||||||
|
p[1] = byte(sa.Port)
|
||||||
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.raw.Addr[i] = sa.Addr[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
name := sa.Name
|
||||||
|
n := len(name)
|
||||||
|
if n >= len(sa.raw.Path) || n == 0 {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
|
||||||
|
sa.raw.Family = AF_UNIX
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
sa.raw.Path[i] = int8(name[i])
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Index == 0 {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = sa.Len
|
||||||
|
sa.raw.Family = AF_LINK
|
||||||
|
sa.raw.Index = sa.Index
|
||||||
|
sa.raw.Type = sa.Type
|
||||||
|
sa.raw.Nlen = sa.Nlen
|
||||||
|
sa.raw.Alen = sa.Alen
|
||||||
|
sa.raw.Slen = sa.Slen
|
||||||
|
for i := 0; i < len(sa.raw.Data); i++ {
|
||||||
|
sa.raw.Data[i] = sa.Data[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
|
switch rsa.Addr.Family {
|
||||||
|
case AF_LINK:
|
||||||
|
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrDatalink)
|
||||||
|
sa.Len = pp.Len
|
||||||
|
sa.Family = pp.Family
|
||||||
|
sa.Index = pp.Index
|
||||||
|
sa.Type = pp.Type
|
||||||
|
sa.Nlen = pp.Nlen
|
||||||
|
sa.Alen = pp.Alen
|
||||||
|
sa.Slen = pp.Slen
|
||||||
|
for i := 0; i < len(sa.Data); i++ {
|
||||||
|
sa.Data[i] = pp.Data[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_UNIX:
|
||||||
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
||||||
|
if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
sa := new(SockaddrUnix)
|
||||||
|
|
||||||
|
// Some BSDs include the trailing NUL in the length, whereas
|
||||||
|
// others do not. Work around this by subtracting the leading
|
||||||
|
// family and len. The path is then scanned to see if a NUL
|
||||||
|
// terminator still exists within the length.
|
||||||
|
n := int(pp.Len) - 2 // subtract leading Family, Len
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if pp.Path[i] == 0 {
|
||||||
|
// found early NUL; assume Len included the NUL
|
||||||
|
// or was overestimating.
|
||||||
|
n = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
|
||||||
|
sa.Name = string(bytes)
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrInet4)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.Addr[i] = pp.Addr[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrInet6)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
sa.ZoneId = pp.Scope_id
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.Addr[i] = pp.Addr[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
}
|
||||||
|
return nil, EAFNOSUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
var len _Socklen = SizeofSockaddrAny
|
||||||
|
nfd, err = accept(fd, &rsa, &len)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "darwin" && len == 0 {
|
||||||
|
// Accepted socket has no address.
|
||||||
|
// This is likely due to a bug in xnu kernels,
|
||||||
|
// where instead of ECONNABORTED error socket
|
||||||
|
// is accepted, but has no address.
|
||||||
|
Close(nfd)
|
||||||
|
return 0, nil, ECONNABORTED
|
||||||
|
}
|
||||||
|
sa, err = anyToSockaddr(&rsa)
|
||||||
|
if err != nil {
|
||||||
|
Close(nfd)
|
||||||
|
nfd = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getsockname(fd int) (sa Sockaddr, err error) {
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
var len _Socklen = SizeofSockaddrAny
|
||||||
|
if err = getsockname(fd, &rsa, &len); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
|
||||||
|
// reported upstream.
|
||||||
|
if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
|
||||||
|
rsa.Addr.Family = AF_UNIX
|
||||||
|
rsa.Addr.Len = SizeofSockaddrUnix
|
||||||
|
}
|
||||||
|
return anyToSockaddr(&rsa)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||||
|
|
||||||
|
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
|
||||||
|
var n byte
|
||||||
|
vallen := _Socklen(1)
|
||||||
|
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
|
||||||
|
vallen := _Socklen(4)
|
||||||
|
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
|
||||||
|
return value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
|
||||||
|
var value IPMreq
|
||||||
|
vallen := _Socklen(SizeofIPMreq)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
|
||||||
|
var value IPv6Mreq
|
||||||
|
vallen := _Socklen(SizeofIPv6Mreq)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
|
||||||
|
var value IPv6MTUInfo
|
||||||
|
vallen := _Socklen(SizeofIPv6MTUInfo)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
|
||||||
|
var value ICMPv6Filter
|
||||||
|
vallen := _Socklen(SizeofICMPv6Filter)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||||
|
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
|
||||||
|
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||||
|
var msg Msghdr
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
msg.Name = (*byte)(unsafe.Pointer(&rsa))
|
||||||
|
msg.Namelen = uint32(SizeofSockaddrAny)
|
||||||
|
var iov Iovec
|
||||||
|
if len(p) > 0 {
|
||||||
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
||||||
|
iov.SetLen(len(p))
|
||||||
|
}
|
||||||
|
var dummy byte
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// receive at least one normal byte
|
||||||
|
if len(p) == 0 {
|
||||||
|
iov.Base = &dummy
|
||||||
|
iov.SetLen(1)
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
msg.Iov = &iov
|
||||||
|
msg.Iovlen = 1
|
||||||
|
if n, err = recvmsg(fd, &msg, flags); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oobn = int(msg.Controllen)
|
||||||
|
recvflags = int(msg.Flags)
|
||||||
|
// source address is only specified if the socket is unconnected
|
||||||
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
|
from, err = anyToSockaddr(&rsa)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
|
||||||
|
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
||||||
|
_, err = SendmsgN(fd, p, oob, to, flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
|
||||||
|
var ptr unsafe.Pointer
|
||||||
|
var salen _Socklen
|
||||||
|
if to != nil {
|
||||||
|
ptr, salen, err = to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var msg Msghdr
|
||||||
|
msg.Name = (*byte)(unsafe.Pointer(ptr))
|
||||||
|
msg.Namelen = uint32(salen)
|
||||||
|
var iov Iovec
|
||||||
|
if len(p) > 0 {
|
||||||
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
||||||
|
iov.SetLen(len(p))
|
||||||
|
}
|
||||||
|
var dummy byte
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// send at least one normal byte
|
||||||
|
if len(p) == 0 {
|
||||||
|
iov.Base = &dummy
|
||||||
|
iov.SetLen(1)
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
msg.Iov = &iov
|
||||||
|
msg.Iovlen = 1
|
||||||
|
if n, err = sendmsg(fd, &msg, flags); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if len(oob) > 0 && len(p) == 0 {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
|
||||||
|
|
||||||
|
func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
|
||||||
|
var change, event unsafe.Pointer
|
||||||
|
if len(changes) > 0 {
|
||||||
|
change = unsafe.Pointer(&changes[0])
|
||||||
|
}
|
||||||
|
if len(events) > 0 {
|
||||||
|
event = unsafe.Pointer(&events[0])
|
||||||
|
}
|
||||||
|
return kevent(kq, change, len(changes), event, len(events), timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||||
|
|
||||||
|
// sysctlmib translates name to mib number and appends any additional args.
|
||||||
|
func sysctlmib(name string, args ...int) ([]_C_int, error) {
|
||||||
|
// Translate name to mib number.
|
||||||
|
mib, err := nametomib(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range args {
|
||||||
|
mib = append(mib, _C_int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
return mib, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sysctl(name string) (string, error) {
|
||||||
|
return SysctlArgs(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlArgs(name string, args ...int) (string, error) {
|
||||||
|
buf, err := SysctlRaw(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
n := len(buf)
|
||||||
|
|
||||||
|
// Throw away terminating NUL.
|
||||||
|
if n > 0 && buf[n-1] == '\x00' {
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
return string(buf[0:n]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint32(name string) (uint32, error) {
|
||||||
|
return SysctlUint32Args(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint32Args(name string, args ...int) (uint32, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n := uintptr(4)
|
||||||
|
buf := make([]byte, 4)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if n != 4 {
|
||||||
|
return 0, EIO
|
||||||
|
}
|
||||||
|
return *(*uint32)(unsafe.Pointer(&buf[0])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint64(name string, args ...int) (uint64, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n := uintptr(8)
|
||||||
|
buf := make([]byte, 8)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if n != 8 {
|
||||||
|
return 0, EIO
|
||||||
|
}
|
||||||
|
return *(*uint64)(unsafe.Pointer(&buf[0])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlRaw(name string, args ...int) ([]byte, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find size.
|
||||||
|
n := uintptr(0)
|
||||||
|
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read into buffer of that size.
|
||||||
|
buf := make([]byte, n)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The actual call may return less than the original reported required
|
||||||
|
// size so ensure we deal with that.
|
||||||
|
return buf[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys utimes(path string, timeval *[2]Timeval) (err error)
|
||||||
|
|
||||||
|
func Utimes(path string, tv []Timeval) error {
|
||||||
|
if tv == nil {
|
||||||
|
return utimes(path, nil)
|
||||||
|
}
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
func UtimesNano(path string, ts []Timespec) error {
|
||||||
|
if ts == nil {
|
||||||
|
return utimes(path, nil)
|
||||||
|
}
|
||||||
|
// TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it
|
||||||
|
// isn't supported by darwin so this uses utimes instead
|
||||||
|
if len(ts) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
// Not as efficient as it could be because Timespec and
|
||||||
|
// Timeval have different types in the different OSes
|
||||||
|
tv := [2]Timeval{
|
||||||
|
NsecToTimeval(TimespecToNsec(ts[0])),
|
||||||
|
NsecToTimeval(TimespecToNsec(ts[1])),
|
||||||
|
}
|
||||||
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys futimes(fd int, timeval *[2]Timeval) (err error)
|
||||||
|
|
||||||
|
func Futimes(fd int, tv []Timeval) error {
|
||||||
|
if tv == nil {
|
||||||
|
return futimes(fd, nil)
|
||||||
|
}
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||||
|
|
||||||
|
// TODO: wrap
|
||||||
|
// Acct(name nil-string) (err error)
|
||||||
|
// Gethostuuid(uuid *byte, timeout *Timespec) (err error)
|
||||||
|
// Madvise(addr *byte, len int, behav int) (err error)
|
||||||
|
// Mprotect(addr *byte, len int, prot int) (err error)
|
||||||
|
// Msync(addr *byte, len int, flags int) (err error)
|
||||||
|
// Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
|
||||||
|
|
||||||
|
var mapper = &mmapper{
|
||||||
|
active: make(map[*byte][]byte),
|
||||||
|
mmap: mmap,
|
||||||
|
munmap: munmap,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||||
|
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Munmap(b []byte) (err error) {
|
||||||
|
return mapper.Munmap(b)
|
||||||
|
}
|
509
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
Normal file
509
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
// Copyright 2009,2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Darwin system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and wrap
|
||||||
|
// it in our own nicer implementation, either here or in
|
||||||
|
// syscall_bsd.go or syscall_unix.go.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
errorspkg "errors"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ImplementsGetwd = true
|
||||||
|
|
||||||
|
func Getwd() (string, error) {
|
||||||
|
buf := make([]byte, 2048)
|
||||||
|
attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
|
||||||
|
if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
|
||||||
|
wd := string(attrs[0])
|
||||||
|
// Sanity check that it's an absolute path and ends
|
||||||
|
// in a null byte, which we then strip.
|
||||||
|
if wd[0] == '/' && wd[len(wd)-1] == 0 {
|
||||||
|
return wd[:len(wd)-1], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
|
||||||
|
// slow algorithm.
|
||||||
|
return "", ENOTSUP
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrDatalink struct {
|
||||||
|
Len uint8
|
||||||
|
Family uint8
|
||||||
|
Index uint16
|
||||||
|
Type uint8
|
||||||
|
Nlen uint8
|
||||||
|
Alen uint8
|
||||||
|
Slen uint8
|
||||||
|
Data [12]int8
|
||||||
|
raw RawSockaddrDatalink
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||||
|
func nametomib(name string) (mib []_C_int, err error) {
|
||||||
|
const siz = unsafe.Sizeof(mib[0])
|
||||||
|
|
||||||
|
// NOTE(rsc): It seems strange to set the buffer to have
|
||||||
|
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
|
||||||
|
// as the size. I don't know why the +2 is here, but the
|
||||||
|
// kernel uses +2 for its own implementation of this function.
|
||||||
|
// I am scared that if we don't include the +2 here, the kernel
|
||||||
|
// will silently write 2 words farther than we specify
|
||||||
|
// and we'll get memory corruption.
|
||||||
|
var buf [CTL_MAXNAME + 2]_C_int
|
||||||
|
n := uintptr(CTL_MAXNAME) * siz
|
||||||
|
|
||||||
|
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||||
|
bytes, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic sysctl: "setting" 0.3 to a string name
|
||||||
|
// lets you read back the array of integers form.
|
||||||
|
if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf[0 : n/siz], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDirent parses up to max directory entries in buf,
|
||||||
|
// appending the names to names. It returns the number
|
||||||
|
// bytes consumed from buf, the number of entries added
|
||||||
|
// to names, and the new names slice.
|
||||||
|
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
||||||
|
origlen := len(buf)
|
||||||
|
for max != 0 && len(buf) > 0 {
|
||||||
|
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
|
||||||
|
if dirent.Reclen == 0 {
|
||||||
|
buf = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buf = buf[dirent.Reclen:]
|
||||||
|
if dirent.Ino == 0 { // File absent in directory.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||||
|
var name = string(bytes[0:dirent.Namlen])
|
||||||
|
if name == "." || name == ".." { // Useless names
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
max--
|
||||||
|
count++
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
return origlen - len(buf), count, names
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
|
||||||
|
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
|
||||||
|
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
|
||||||
|
|
||||||
|
const (
|
||||||
|
attrBitMapCount = 5
|
||||||
|
attrCmnFullpath = 0x08000000
|
||||||
|
)
|
||||||
|
|
||||||
|
type attrList struct {
|
||||||
|
bitmapCount uint16
|
||||||
|
_ uint16
|
||||||
|
CommonAttr uint32
|
||||||
|
VolAttr uint32
|
||||||
|
DirAttr uint32
|
||||||
|
FileAttr uint32
|
||||||
|
Forkattr uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
|
||||||
|
if len(attrBuf) < 4 {
|
||||||
|
return nil, errorspkg.New("attrBuf too small")
|
||||||
|
}
|
||||||
|
attrList.bitmapCount = attrBitMapCount
|
||||||
|
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(
|
||||||
|
SYS_GETATTRLIST,
|
||||||
|
uintptr(unsafe.Pointer(_p0)),
|
||||||
|
uintptr(unsafe.Pointer(&attrList)),
|
||||||
|
uintptr(unsafe.Pointer(&attrBuf[0])),
|
||||||
|
uintptr(len(attrBuf)),
|
||||||
|
uintptr(options),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
if e1 != 0 {
|
||||||
|
return nil, e1
|
||||||
|
}
|
||||||
|
size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
|
||||||
|
|
||||||
|
// dat is the section of attrBuf that contains valid data,
|
||||||
|
// without the 4 byte length header. All attribute offsets
|
||||||
|
// are relative to dat.
|
||||||
|
dat := attrBuf
|
||||||
|
if int(size) < len(attrBuf) {
|
||||||
|
dat = dat[:size]
|
||||||
|
}
|
||||||
|
dat = dat[4:] // remove length prefix
|
||||||
|
|
||||||
|
for i := uint32(0); int(i) < len(dat); {
|
||||||
|
header := dat[i:]
|
||||||
|
if len(header) < 8 {
|
||||||
|
return attrs, errorspkg.New("truncated attribute header")
|
||||||
|
}
|
||||||
|
datOff := *(*int32)(unsafe.Pointer(&header[0]))
|
||||||
|
attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
|
||||||
|
if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
|
||||||
|
return attrs, errorspkg.New("truncated results; attrBuf too small")
|
||||||
|
}
|
||||||
|
end := uint32(datOff) + attrLen
|
||||||
|
attrs = append(attrs, dat[datOff:end])
|
||||||
|
i = end
|
||||||
|
if r := i % 4; r != 0 {
|
||||||
|
i += (4 - r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe() (r int, w int, err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
p[0], p[1], err = pipe()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
var bufsize uintptr
|
||||||
|
if len(buf) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&buf[0])
|
||||||
|
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
|
||||||
|
}
|
||||||
|
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sys kill(pid int, signum int, posix int) (err error)
|
||||||
|
|
||||||
|
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed directly
|
||||||
|
*/
|
||||||
|
//sys Access(path string, mode uint32) (err error)
|
||||||
|
//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
|
||||||
|
//sys Chdir(path string) (err error)
|
||||||
|
//sys Chflags(path string, flags int) (err error)
|
||||||
|
//sys Chmod(path string, mode uint32) (err error)
|
||||||
|
//sys Chown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Chroot(path string) (err error)
|
||||||
|
//sys Close(fd int) (err error)
|
||||||
|
//sys Dup(fd int) (nfd int, err error)
|
||||||
|
//sys Dup2(from int, to int) (err error)
|
||||||
|
//sys Exchangedata(path1 string, path2 string, options int) (err error)
|
||||||
|
//sys Exit(code int)
|
||||||
|
//sys Fchdir(fd int) (err error)
|
||||||
|
//sys Fchflags(fd int, flags int) (err error)
|
||||||
|
//sys Fchmod(fd int, mode uint32) (err error)
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
//sys Flock(fd int, how int) (err error)
|
||||||
|
//sys Fpathconf(fd int, name int) (val int, err error)
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||||
|
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||||
|
//sys Fsync(fd int) (err error)
|
||||||
|
//sys Ftruncate(fd int, length int64) (err error)
|
||||||
|
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||||
|
//sys Getdtablesize() (size int)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (uid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
//sysnb Getpgrp() (pgrp int)
|
||||||
|
//sysnb Getpid() (pid int)
|
||||||
|
//sysnb Getppid() (ppid int)
|
||||||
|
//sys Getpriority(which int, who int) (prio int, err error)
|
||||||
|
//sysnb Getrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||||
|
//sysnb Getsid(pid int) (sid int, err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sysnb Issetugid() (tainted bool)
|
||||||
|
//sys Kqueue() (fd int, err error)
|
||||||
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Link(path string, link string) (err error)
|
||||||
|
//sys Listen(s int, backlog int) (err error)
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||||
|
//sys Mkdir(path string, mode uint32) (err error)
|
||||||
|
//sys Mkfifo(path string, mode uint32) (err error)
|
||||||
|
//sys Mknod(path string, mode uint32, dev int) (err error)
|
||||||
|
//sys Mlock(b []byte) (err error)
|
||||||
|
//sys Mlockall(flags int) (err error)
|
||||||
|
//sys Mprotect(b []byte, prot int) (err error)
|
||||||
|
//sys Munlock(b []byte) (err error)
|
||||||
|
//sys Munlockall() (err error)
|
||||||
|
//sys Open(path string, mode int, perm uint32) (fd int, err error)
|
||||||
|
//sys Pathconf(path string, name int) (val int, err error)
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||||
|
//sys read(fd int, p []byte) (n int, err error)
|
||||||
|
//sys Readlink(path string, buf []byte) (n int, err error)
|
||||||
|
//sys Rename(from string, to string) (err error)
|
||||||
|
//sys Revoke(path string) (err error)
|
||||||
|
//sys Rmdir(path string) (err error)
|
||||||
|
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
|
||||||
|
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
|
||||||
|
//sys Setegid(egid int) (err error)
|
||||||
|
//sysnb Seteuid(euid int) (err error)
|
||||||
|
//sysnb Setgid(gid int) (err error)
|
||||||
|
//sys Setlogin(name string) (err error)
|
||||||
|
//sysnb Setpgid(pid int, pgid int) (err error)
|
||||||
|
//sys Setpriority(which int, who int, prio int) (err error)
|
||||||
|
//sys Setprivexec(flag int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Setsid() (pid int, err error)
|
||||||
|
//sysnb Settimeofday(tp *Timeval) (err error)
|
||||||
|
//sysnb Setuid(uid int) (err error)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||||
|
//sys Symlink(path string, link string) (err error)
|
||||||
|
//sys Sync() (err error)
|
||||||
|
//sys Truncate(path string, length int64) (err error)
|
||||||
|
//sys Umask(newmask int) (oldmask int)
|
||||||
|
//sys Undelete(path string) (err error)
|
||||||
|
//sys Unlink(path string) (err error)
|
||||||
|
//sys Unmount(path string, flags int) (err error)
|
||||||
|
//sys write(fd int, p []byte) (n int, err error)
|
||||||
|
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
|
||||||
|
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||||
|
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
|
||||||
|
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
*/
|
||||||
|
// Profil
|
||||||
|
// Sigaction
|
||||||
|
// Sigprocmask
|
||||||
|
// Getlogin
|
||||||
|
// Sigpending
|
||||||
|
// Sigaltstack
|
||||||
|
// Ioctl
|
||||||
|
// Reboot
|
||||||
|
// Execve
|
||||||
|
// Vfork
|
||||||
|
// Sbrk
|
||||||
|
// Sstk
|
||||||
|
// Ovadvise
|
||||||
|
// Mincore
|
||||||
|
// Setitimer
|
||||||
|
// Swapon
|
||||||
|
// Select
|
||||||
|
// Sigsuspend
|
||||||
|
// Readv
|
||||||
|
// Writev
|
||||||
|
// Nfssvc
|
||||||
|
// Getfh
|
||||||
|
// Quotactl
|
||||||
|
// Mount
|
||||||
|
// Csops
|
||||||
|
// Waitid
|
||||||
|
// Add_profil
|
||||||
|
// Kdebug_trace
|
||||||
|
// Sigreturn
|
||||||
|
// Mmap
|
||||||
|
// Mlock
|
||||||
|
// Munlock
|
||||||
|
// Atsocket
|
||||||
|
// Kqueue_from_portset_np
|
||||||
|
// Kqueue_portset
|
||||||
|
// Getattrlist
|
||||||
|
// Setattrlist
|
||||||
|
// Getdirentriesattr
|
||||||
|
// Searchfs
|
||||||
|
// Delete
|
||||||
|
// Copyfile
|
||||||
|
// Poll
|
||||||
|
// Watchevent
|
||||||
|
// Waitevent
|
||||||
|
// Modwatch
|
||||||
|
// Getxattr
|
||||||
|
// Fgetxattr
|
||||||
|
// Setxattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Removexattr
|
||||||
|
// Fremovexattr
|
||||||
|
// Listxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Fsctl
|
||||||
|
// Initgroups
|
||||||
|
// Posix_spawn
|
||||||
|
// Nfsclnt
|
||||||
|
// Fhopen
|
||||||
|
// Minherit
|
||||||
|
// Semsys
|
||||||
|
// Msgsys
|
||||||
|
// Shmsys
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgsnd
|
||||||
|
// Msgrcv
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Shm_open
|
||||||
|
// Shm_unlink
|
||||||
|
// Sem_open
|
||||||
|
// Sem_close
|
||||||
|
// Sem_unlink
|
||||||
|
// Sem_wait
|
||||||
|
// Sem_trywait
|
||||||
|
// Sem_post
|
||||||
|
// Sem_getvalue
|
||||||
|
// Sem_init
|
||||||
|
// Sem_destroy
|
||||||
|
// Open_extended
|
||||||
|
// Umask_extended
|
||||||
|
// Stat_extended
|
||||||
|
// Lstat_extended
|
||||||
|
// Fstat_extended
|
||||||
|
// Chmod_extended
|
||||||
|
// Fchmod_extended
|
||||||
|
// Access_extended
|
||||||
|
// Settid
|
||||||
|
// Gettid
|
||||||
|
// Setsgroups
|
||||||
|
// Getsgroups
|
||||||
|
// Setwgroups
|
||||||
|
// Getwgroups
|
||||||
|
// Mkfifo_extended
|
||||||
|
// Mkdir_extended
|
||||||
|
// Identitysvc
|
||||||
|
// Shared_region_check_np
|
||||||
|
// Shared_region_map_np
|
||||||
|
// __pthread_mutex_destroy
|
||||||
|
// __pthread_mutex_init
|
||||||
|
// __pthread_mutex_lock
|
||||||
|
// __pthread_mutex_trylock
|
||||||
|
// __pthread_mutex_unlock
|
||||||
|
// __pthread_cond_init
|
||||||
|
// __pthread_cond_destroy
|
||||||
|
// __pthread_cond_broadcast
|
||||||
|
// __pthread_cond_signal
|
||||||
|
// Setsid_with_pid
|
||||||
|
// __pthread_cond_timedwait
|
||||||
|
// Aio_fsync
|
||||||
|
// Aio_return
|
||||||
|
// Aio_suspend
|
||||||
|
// Aio_cancel
|
||||||
|
// Aio_error
|
||||||
|
// Aio_read
|
||||||
|
// Aio_write
|
||||||
|
// Lio_listio
|
||||||
|
// __pthread_cond_wait
|
||||||
|
// Iopolicysys
|
||||||
|
// Mlockall
|
||||||
|
// Munlockall
|
||||||
|
// __pthread_kill
|
||||||
|
// __pthread_sigmask
|
||||||
|
// __sigwait
|
||||||
|
// __disable_threadsignal
|
||||||
|
// __pthread_markcancel
|
||||||
|
// __pthread_canceled
|
||||||
|
// __semwait_signal
|
||||||
|
// Proc_info
|
||||||
|
// sendfile
|
||||||
|
// Stat64_extended
|
||||||
|
// Lstat64_extended
|
||||||
|
// Fstat64_extended
|
||||||
|
// __pthread_chdir
|
||||||
|
// __pthread_fchdir
|
||||||
|
// Audit
|
||||||
|
// Auditon
|
||||||
|
// Getauid
|
||||||
|
// Setauid
|
||||||
|
// Getaudit
|
||||||
|
// Setaudit
|
||||||
|
// Getaudit_addr
|
||||||
|
// Setaudit_addr
|
||||||
|
// Auditctl
|
||||||
|
// Bsdthread_create
|
||||||
|
// Bsdthread_terminate
|
||||||
|
// Stack_snapshot
|
||||||
|
// Bsdthread_register
|
||||||
|
// Workq_open
|
||||||
|
// Workq_ops
|
||||||
|
// __mac_execve
|
||||||
|
// __mac_syscall
|
||||||
|
// __mac_get_file
|
||||||
|
// __mac_set_file
|
||||||
|
// __mac_get_link
|
||||||
|
// __mac_set_link
|
||||||
|
// __mac_get_proc
|
||||||
|
// __mac_set_proc
|
||||||
|
// __mac_get_fd
|
||||||
|
// __mac_set_fd
|
||||||
|
// __mac_get_pid
|
||||||
|
// __mac_get_lcid
|
||||||
|
// __mac_get_lctx
|
||||||
|
// __mac_set_lctx
|
||||||
|
// Setlcid
|
||||||
|
// Read_nocancel
|
||||||
|
// Write_nocancel
|
||||||
|
// Open_nocancel
|
||||||
|
// Close_nocancel
|
||||||
|
// Wait4_nocancel
|
||||||
|
// Recvmsg_nocancel
|
||||||
|
// Sendmsg_nocancel
|
||||||
|
// Recvfrom_nocancel
|
||||||
|
// Accept_nocancel
|
||||||
|
// Msync_nocancel
|
||||||
|
// Fcntl_nocancel
|
||||||
|
// Select_nocancel
|
||||||
|
// Fsync_nocancel
|
||||||
|
// Connect_nocancel
|
||||||
|
// Sigsuspend_nocancel
|
||||||
|
// Readv_nocancel
|
||||||
|
// Writev_nocancel
|
||||||
|
// Sendto_nocancel
|
||||||
|
// Pread_nocancel
|
||||||
|
// Pwrite_nocancel
|
||||||
|
// Waitid_nocancel
|
||||||
|
// Poll_nocancel
|
||||||
|
// Msgsnd_nocancel
|
||||||
|
// Msgrcv_nocancel
|
||||||
|
// Sem_wait_nocancel
|
||||||
|
// Aio_suspend_nocancel
|
||||||
|
// __sigwait_nocancel
|
||||||
|
// __semwait_signal_nocancel
|
||||||
|
// __mac_mount
|
||||||
|
// __mac_get_mount
|
||||||
|
// __mac_getfsstat
|
77
vendor/golang.org/x/sys/unix/syscall_darwin_386.go
generated
vendored
Normal file
77
vendor/golang.org/x/sys/unix/syscall_darwin_386.go
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
|
||||||
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
|
// The tv passed to gettimeofday must be non-nil
|
||||||
|
// but is otherwise unused. The answers come back
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = int32(sec)
|
||||||
|
tv.Usec = int32(usec)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/386 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
79
vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
generated
vendored
Normal file
79
vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
|
||||||
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
|
// The tv passed to gettimeofday must be non-nil
|
||||||
|
// but is otherwise unused. The answers come back
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = sec
|
||||||
|
tv.Usec = usec
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/amd64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
71
vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
generated
vendored
Normal file
71
vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
|
||||||
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
|
// The tv passed to gettimeofday must be non-nil
|
||||||
|
// but is otherwise unused. The answers come back
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = int32(sec)
|
||||||
|
tv.Usec = int32(usec)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
|
77
vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
generated
vendored
Normal file
77
vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm64,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 16384 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
|
||||||
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
|
// The tv passed to gettimeofday must be non-nil
|
||||||
|
// but is otherwise unused. The answers come back
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = sec
|
||||||
|
tv.Usec = usec
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/arm64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user