go vendor
This commit is contained in:
11
vendor/github.com/revel/modules/server-engine/fasthttp/README.md
generated
vendored
Normal file
11
vendor/github.com/revel/modules/server-engine/fasthttp/README.md
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# FastHTTP
|
||||
This module is the for [FastHTTP](https://github.com/valyala/fasthttp) server engine.
|
||||
It does not support WebSockets.
|
||||
|
||||
### app.conf
|
||||
- **server.engine** You must set this to `fasthttp` in order to use this server engine
|
||||
|
||||
### Other Notes
|
||||
All features from that the go HTTP engine is supported by this server engine.
|
||||
Memory usage is decreased by avoiding memory allocations. This should
|
||||
increase overall runtime performance and throughput.
|
423
vendor/github.com/revel/modules/server-engine/fasthttp/app/server-fasthttp.go
generated
vendored
Normal file
423
vendor/github.com/revel/modules/server-engine/fasthttp/app/server-fasthttp.go
generated
vendored
Normal file
@ -0,0 +1,423 @@
|
||||
package fasthttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
"github.com/valyala/fasthttp"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FastHTTPServer struct {
|
||||
Server *fasthttp.Server
|
||||
ServerInit *revel.EngineInit
|
||||
MaxMultipartSize int64
|
||||
}
|
||||
|
||||
var serverLog = revel.AppLog
|
||||
|
||||
func init() {
|
||||
revel.RegisterServerEngine("fasthttp", func() revel.ServerEngine {
|
||||
return &FastHTTPServer{}
|
||||
})
|
||||
revel.RegisterModuleInit(func(m *revel.Module) {
|
||||
serverLog = m.Log
|
||||
})
|
||||
}
|
||||
|
||||
func (f *FastHTTPServer) Init(init *revel.EngineInit) {
|
||||
f.MaxMultipartSize = int64(revel.Config.IntDefault("server.request.max.multipart.filesize", 32)) << 20 /* 32 MB */
|
||||
fastHttpContextStack = revel.NewStackLock(revel.Config.IntDefault("server.context.stack", 100),
|
||||
revel.Config.IntDefault("server.context.maxstack", 200),
|
||||
func() interface{} { return NewFastHttpContext(f) })
|
||||
fastHttpMultipartFormStack = revel.NewStackLock(revel.Config.IntDefault("server.form.stack", 100),
|
||||
revel.Config.IntDefault("server.form.maxstack", 200),
|
||||
func() interface{} { return &FastHttpMultipartForm{} })
|
||||
|
||||
requestHandler := func(ctx *fasthttp.RequestCtx) {
|
||||
f.RequestHandler(ctx)
|
||||
}
|
||||
f.ServerInit = init
|
||||
f.Server = &fasthttp.Server{
|
||||
ReadTimeout: time.Duration(revel.Config.IntDefault("http.timeout.read", 0)) * time.Second,
|
||||
WriteTimeout: time.Duration(revel.Config.IntDefault("http.timeout.write", 0)) * time.Second,
|
||||
Handler: requestHandler,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handler is assigned in the Init
|
||||
func (f *FastHTTPServer) Start() {
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Printf("\nListening on fasthttp %s...\n", f.ServerInit.Address)
|
||||
}()
|
||||
if revel.HTTPSsl {
|
||||
if f.ServerInit.Network != "tcp" {
|
||||
// This limitation is just to reduce complexity, since it is standard
|
||||
// to terminate SSL upstream when using unix domain sockets.
|
||||
serverLog.Fatal("SSL is only supported for TCP sockets. Specify a port to listen on.")
|
||||
}
|
||||
serverLog.Fatal("Failed to listen https:", "error",
|
||||
f.Server.ListenAndServeTLS(f.ServerInit.Address, revel.HTTPSslCert, revel.HTTPSslKey))
|
||||
} else {
|
||||
listener, err := net.Listen(f.ServerInit.Network, f.ServerInit.Address)
|
||||
if err != nil {
|
||||
serverLog.Fatal("Failed to listen http:", "error", err)
|
||||
}
|
||||
serverLog.Info("Listening fasthttp ", f.ServerInit.Network, f.ServerInit.Address)
|
||||
// revel.ERROR.Fatalln("Failed to serve:", f.Server.ListenAndServe(f.ServerInit.Address))
|
||||
serverLog.Fatal("Server exited", "error", f.Server.Serve(listener))
|
||||
println("***ENDING ***")
|
||||
}
|
||||
|
||||
}
|
||||
func (f *FastHTTPServer) RequestHandler(ctx *fasthttp.RequestCtx) {
|
||||
// TODO this
|
||||
//if maxRequestSize := int64(revel.Config.IntDefault("http.maxrequestsize", 0)); maxRequestSize > 0 {
|
||||
// buffer := &bytes.Buffer{}
|
||||
// err := ctx.Request.ReadLimitBody(buffer,maxRequestSize)
|
||||
// if err!=nil {
|
||||
// // Send the error back to the client
|
||||
// ctx.SetStatusCode(http.StatusRequestEntityTooLarge)
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
context := fastHttpContextStack.Pop().(*FastHttpContext)
|
||||
defer func() {
|
||||
fastHttpContextStack.Push(context)
|
||||
}()
|
||||
context.SetContext(ctx)
|
||||
f.ServerInit.Callback(context)
|
||||
}
|
||||
|
||||
func (f *FastHTTPServer) Event(event int, args interface{}) {
|
||||
|
||||
switch event {
|
||||
case revel.ENGINE_BEFORE_INITIALIZED:
|
||||
case revel.ENGINE_STARTED:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
func (f *FastHTTPServer) Name() string {
|
||||
return "fasthttp"
|
||||
}
|
||||
func (f *FastHTTPServer) Engine() interface{} {
|
||||
return f
|
||||
}
|
||||
func (g *FastHTTPServer) Stats() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"FastHTTP Engine Context": fastHttpContextStack.String(),
|
||||
"FastHTTP Engine Forms": fastHttpMultipartFormStack.String(),
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
FastHttpContext struct {
|
||||
Request *FastHttpRequest
|
||||
Response *FastHttpResponse
|
||||
}
|
||||
|
||||
FastHttpRequest struct {
|
||||
toQuery bool
|
||||
url *url.URL
|
||||
query url.Values
|
||||
Original *fasthttp.RequestCtx
|
||||
FormParsed bool
|
||||
form url.Values
|
||||
MultiFormParsed bool
|
||||
// WebSocket *websocket.Conn
|
||||
ParsedForm *FastHttpMultipartForm
|
||||
header *FastHttpHeader
|
||||
Engine *FastHTTPServer
|
||||
}
|
||||
|
||||
FastHttpResponse struct {
|
||||
Original *fasthttp.RequestCtx
|
||||
header *FastHttpHeader
|
||||
Writer io.Writer
|
||||
Engine *FastHTTPServer
|
||||
}
|
||||
FastHttpMultipartForm struct {
|
||||
Form *multipart.Form
|
||||
}
|
||||
FastHttpHeader struct {
|
||||
Source interface{}
|
||||
isResponse bool
|
||||
}
|
||||
FastHttpCookie []byte
|
||||
)
|
||||
|
||||
var (
|
||||
fastHttpContextStack *revel.SimpleLockStack
|
||||
fastHttpMultipartFormStack *revel.SimpleLockStack
|
||||
)
|
||||
|
||||
func NewFastHttpContext(instance *FastHTTPServer) *FastHttpContext {
|
||||
if instance == nil {
|
||||
instance = &FastHTTPServer{MaxMultipartSize: 32 << 20}
|
||||
}
|
||||
c := &FastHttpContext{
|
||||
Request: &FastHttpRequest{header: &FastHttpHeader{isResponse: false},
|
||||
Engine: instance},
|
||||
Response: &FastHttpResponse{header: &FastHttpHeader{isResponse: true},
|
||||
Engine: instance},
|
||||
}
|
||||
c.Response.header.Source = c.Response
|
||||
c.Request.header.Source = c.Request
|
||||
return c
|
||||
}
|
||||
func (c *FastHttpContext) GetRequest() revel.ServerRequest {
|
||||
return c.Request
|
||||
}
|
||||
func (c *FastHttpContext) GetResponse() revel.ServerResponse {
|
||||
return c.Response
|
||||
}
|
||||
func (c *FastHttpContext) SetContext(context *fasthttp.RequestCtx) {
|
||||
c.Response.SetContext(context)
|
||||
c.Request.SetContext(context)
|
||||
}
|
||||
func (c *FastHttpContext) Destroy() {
|
||||
c.Response.Destroy()
|
||||
c.Request.Destroy()
|
||||
}
|
||||
|
||||
func (r *FastHttpRequest) Get(key int) (value interface{}, err error) {
|
||||
switch key {
|
||||
case revel.HTTP_SERVER_HEADER:
|
||||
value = r.GetHeader()
|
||||
case revel.HTTP_MULTIPART_FORM:
|
||||
value, err = r.GetMultipartForm()
|
||||
case revel.HTTP_QUERY:
|
||||
value = r.GetQuery()
|
||||
case revel.HTTP_FORM:
|
||||
value, err = r.GetForm()
|
||||
case revel.HTTP_REQUEST_URI:
|
||||
value = string(r.Original.RequestURI())
|
||||
case revel.HTTP_REMOTE_ADDR:
|
||||
value = r.Original.RemoteAddr().String()
|
||||
case revel.HTTP_METHOD:
|
||||
value = string(r.Original.Method())
|
||||
case revel.HTTP_PATH:
|
||||
value = string(r.Original.Path())
|
||||
case revel.HTTP_HOST:
|
||||
value = string(r.Original.Request.Host())
|
||||
case revel.HTTP_URL:
|
||||
if r.url == nil {
|
||||
r.url, _ = url.Parse(string(r.Original.Request.URI().FullURI()))
|
||||
}
|
||||
value = r.url
|
||||
case revel.HTTP_BODY:
|
||||
value = bytes.NewBuffer(r.Original.Request.Body())
|
||||
default:
|
||||
err = revel.ENGINE_UNKNOWN_GET
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
func (r *FastHttpRequest) Set(key int, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *FastHttpRequest) GetQuery() url.Values {
|
||||
if !r.toQuery {
|
||||
// Attempt to convert to query
|
||||
r.query = url.Values{}
|
||||
r.Original.QueryArgs().VisitAll(func(key, value []byte) {
|
||||
r.query.Set(string(key), string(value))
|
||||
})
|
||||
r.toQuery = true
|
||||
}
|
||||
return r.query
|
||||
}
|
||||
func (r *FastHttpRequest) GetForm() (url.Values, error) {
|
||||
if !r.FormParsed {
|
||||
r.form = url.Values{}
|
||||
r.Original.PostArgs().VisitAll(func(key, value []byte) {
|
||||
println("Set value", string(key), string(value))
|
||||
r.query.Set(string(key), string(value))
|
||||
})
|
||||
r.FormParsed = true
|
||||
}
|
||||
return r.form, nil
|
||||
}
|
||||
func (r *FastHttpRequest) GetMultipartForm() (revel.ServerMultipartForm, error) {
|
||||
if !r.MultiFormParsed {
|
||||
// TODO Limit size r.Engine.MaxMultipartSize
|
||||
form, err := r.Original.MultipartForm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.ParsedForm = fastHttpMultipartFormStack.Pop().(*FastHttpMultipartForm)
|
||||
r.ParsedForm.Form = form
|
||||
}
|
||||
|
||||
return r.ParsedForm, nil
|
||||
}
|
||||
func (r *FastHttpRequest) GetHeader() revel.ServerHeader {
|
||||
return r.header
|
||||
}
|
||||
func (r *FastHttpRequest) GetRaw() interface{} {
|
||||
return r.Original
|
||||
}
|
||||
func (r *FastHttpRequest) SetContext(req *fasthttp.RequestCtx) {
|
||||
r.Original = req
|
||||
|
||||
}
|
||||
func (r *FastHttpRequest) Destroy() {
|
||||
r.Original = nil
|
||||
r.FormParsed = false
|
||||
r.MultiFormParsed = false
|
||||
r.ParsedForm = nil
|
||||
r.toQuery = false
|
||||
|
||||
}
|
||||
|
||||
func (r *FastHttpResponse) Get(key int) (value interface{}, err error) {
|
||||
switch key {
|
||||
case revel.HTTP_SERVER_HEADER:
|
||||
value = r.Header()
|
||||
case revel.HTTP_STREAM_WRITER:
|
||||
value = r
|
||||
case revel.HTTP_WRITER:
|
||||
value = r.Writer
|
||||
default:
|
||||
err = revel.ENGINE_UNKNOWN_GET
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *FastHttpResponse) Set(key int, value interface{}) (set bool) {
|
||||
switch key {
|
||||
case revel.ENGINE_RESPONSE_STATUS:
|
||||
r.Header().SetStatus(value.(int))
|
||||
set = true
|
||||
case revel.HTTP_WRITER:
|
||||
r.SetWriter(value.(io.Writer))
|
||||
set = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *FastHttpResponse) GetWriter() io.Writer {
|
||||
return r.Writer
|
||||
}
|
||||
func (r *FastHttpResponse) Header() revel.ServerHeader {
|
||||
return r.header
|
||||
}
|
||||
func (r *FastHttpResponse) GetRaw() interface{} {
|
||||
return r.Original
|
||||
}
|
||||
func (r *FastHttpResponse) WriteStream(name string, contentlen int64, modtime time.Time, reader io.Reader) error {
|
||||
|
||||
// do a simple io.Copy, we do it directly into the writer which may be configured to be a compressed
|
||||
// writer
|
||||
ius := r.Original.Request.Header.Peek("If-Unmodified-Since")
|
||||
if t, err := http.ParseTime(string(ius)); ius != nil && err == nil && !modtime.IsZero() {
|
||||
// The Date-Modified header truncates sub-second precision, so
|
||||
// use mtime < t+1s instead of mtime <= t to check for unmodified.
|
||||
if modtime.Before(t.Add(1 * time.Second)) {
|
||||
h := r.Original.Response.Header
|
||||
h.Del("Content-Type")
|
||||
h.Del("Content-Length")
|
||||
if h.Peek("Etag") != nil {
|
||||
h.Del("Last-Modified")
|
||||
}
|
||||
h.SetStatusCode(http.StatusNotModified)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if contentlen != -1 {
|
||||
r.Original.Response.Header.Set("Content-Length", strconv.FormatInt(contentlen, 10))
|
||||
}
|
||||
if _, err := io.Copy(r.Writer, reader); err != nil {
|
||||
r.Original.Response.Header.SetStatusCode(http.StatusInternalServerError)
|
||||
return err
|
||||
} else {
|
||||
r.Original.Response.Header.SetStatusCode(http.StatusOK)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (r *FastHttpResponse) Destroy() {
|
||||
if c, ok := r.Writer.(io.Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
r.Original = nil
|
||||
r.Writer = nil
|
||||
|
||||
}
|
||||
func (r *FastHttpResponse) SetContext(w *fasthttp.RequestCtx) {
|
||||
r.Original = w
|
||||
r.Writer = w.Response.BodyWriter()
|
||||
}
|
||||
func (r *FastHttpResponse) SetWriter(writer io.Writer) {
|
||||
r.Writer = writer
|
||||
}
|
||||
func (r *FastHttpHeader) SetCookie(cookie string) {
|
||||
if r.isResponse {
|
||||
r.Source.(*FastHttpResponse).Original.Response.Header.Add("Set-Cookie", cookie)
|
||||
}
|
||||
}
|
||||
func (r *FastHttpHeader) GetCookie(key string) (value revel.ServerCookie, err error) {
|
||||
if !r.isResponse {
|
||||
var cookie []byte
|
||||
if cookie = r.Source.(*FastHttpRequest).Original.Request.Header.Cookie(key); cookie != nil {
|
||||
value = FastHttpCookie(cookie)
|
||||
} else {
|
||||
err = http.ErrNoCookie
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
func (r *FastHttpHeader) Set(key string, value string) {
|
||||
if r.isResponse {
|
||||
r.Source.(*FastHttpResponse).Original.Response.Header.Set(key, value)
|
||||
}
|
||||
}
|
||||
func (r *FastHttpHeader) Add(key string, value string) {
|
||||
if r.isResponse {
|
||||
r.Source.(*FastHttpResponse).Original.Response.Header.Add(key, value)
|
||||
}
|
||||
}
|
||||
func (r *FastHttpHeader) Del(key string) {
|
||||
if r.isResponse {
|
||||
r.Source.(*FastHttpResponse).Original.Response.Header.Del(key)
|
||||
}
|
||||
}
|
||||
func (r *FastHttpHeader) Get(key string) (value []string) {
|
||||
if !r.isResponse {
|
||||
value = strings.Split(string(r.Source.(*FastHttpRequest).Original.Request.Header.Peek(key)), ",")
|
||||
} else {
|
||||
value = strings.Split(string(r.Source.(*FastHttpResponse).Original.Response.Header.Peek(key)), ",")
|
||||
}
|
||||
return
|
||||
}
|
||||
func (r *FastHttpHeader) SetStatus(statusCode int) {
|
||||
if r.isResponse {
|
||||
r.Source.(*FastHttpResponse).Original.Response.SetStatusCode(statusCode)
|
||||
}
|
||||
}
|
||||
func (r FastHttpCookie) GetValue() string {
|
||||
return string(r)
|
||||
}
|
||||
func (f *FastHttpMultipartForm) GetFiles() map[string][]*multipart.FileHeader {
|
||||
return f.Form.File
|
||||
}
|
||||
func (f *FastHttpMultipartForm) GetValues() url.Values {
|
||||
return url.Values(f.Form.Value)
|
||||
}
|
||||
func (f *FastHttpMultipartForm) RemoveAll() error {
|
||||
return f.Form.RemoveAll()
|
||||
}
|
3
vendor/github.com/revel/modules/server-engine/fasthttp/fasthttp.go
generated
vendored
Normal file
3
vendor/github.com/revel/modules/server-engine/fasthttp/fasthttp.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package fasthttp
|
||||
|
||||
// Required for vendoring see golang.org/issue/13832
|
Reference in New Issue
Block a user