コード例 #1
0
ファイル: xsrf.go プロジェクト: jacobzheng/zerver
func (x *Xsrf) VerifyFor(req zerver.Request) bool {
	m := req.ReqMethod()
	if !x.FilterGet && (m == zerver.METHOD_GET || m == zerver.METHOD_HEAD || m == zerver.METHOD_OPTIONS) {
		return true
	}

	token := req.GetHeader(_HEADER_XSRFTOKEN)
	if token == "" {
		token = req.GetHeader(_HEADER_CSRFTOKEN)
		if token == "" {
			token = req.Vars().QueryVar(_XSRF_PARAM_NAME)
			if token == "" {
				return false
			}
		}
	}

	data := x.verify(unsafe2.Bytes(token))
	if data != nil {
		x.Pool.Put(data)
		t, ip := x.TokenInfo.Unmarshal(data)
		return t != -1 &&
			t+x.Timeout >= time2.Now().Unix() &&
			ip == http2.IpOfAddr(req.RemoteAddr())
	}

	return false
}
コード例 #2
0
ファイル: cors.go プロジェクト: jacobzheng/zerver
func (c *CORS) filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	headers := resp.Headers()
	origin := "*"
	if !c.allowAll {
		origin = req.GetHeader(_CORS_ORIGIN)
		if !c.allow(origin) {
			resp.StatusCode(http.StatusForbidden)
			return
		}
	}
	headers.Set(_CORS_ALLOWORIGIN, origin)

	headers.Set(_CORS_ALLOWMETHODS, c.methods)
	headers.Set(_CORS_ALLOWHEADERS, c.headers)

	headers.Set(_CORS_ALLOWCREDENTIALS, c.allowCredentials)
	if c.exposeHeaders != "" {
		headers.Set(_CORS_EXPOSEHEADERS, c.exposeHeaders)
	}
	if c.preflightMaxage != "" {
		headers.Set(_CORS_MAXAGE, c.preflightMaxage)
	}

	chain(req, resp)
}
コード例 #3
0
ファイル: xsrf.go プロジェクト: jacobzheng/zerver
func (x *Xsrf) CreateFor(req zerver.Request) ([]byte, error) {
	bs, err := x.TokenInfo.Marshal(time2.Now().Unix(), http2.IpOfAddr(req.RemoteAddr()))
	if err == nil {
		return x.sign(bs), nil
	}

	return nil, err
}
コード例 #4
0
ファイル: xsrf.go プロジェクト: snowsnail/zerver
func (x *Xsrf) CreateFor(req zerver.Request) ([]byte, error) {
	bs, err := x.TokenInfo.Marshal(time2.Now().Unix(), req.RemoteIP(), req.UserAgent())
	if err == nil {
		return x.sign(bs), nil
	}

	return nil, err
}
コード例 #5
0
ファイル: monitoring.go プロジェクト: jacobzheng/zerver
func globalFilter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	status := resp.StatusCode(0)
	if status == http.StatusNotFound {
		resp.Headers().Set("Location", path+"/options?from="+url.QueryEscape(req.URL().Path))
		resp.StatusCode(http.StatusMovedPermanently)
	} else if status == http.StatusMethodNotAllowed {
		io2.WriteString(resp, "The pprof interface only support GET request\n")
	} else {
		chain(req, resp)
	}
}
コード例 #6
0
ファイル: auth_jwt.go プロジェクト: VicentLiu/zerver
func (j *JWTAuth) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if tokstr, basic := req.Authorization(); !basic && tokstr != "" {
		if tok, err := j.JWT.Parse(tokstr); err == nil {
			req.SetAttr(j.AuthTokenAttrName, tok)
			chain(req, resp)
			return
		}
	}

	resp.ReportUnauthorized()
}
コード例 #7
0
ファイル: monitoring.go プロジェクト: fanbuchi/zerver
func globalFilter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	resp.SetContentType("text/plain", nil)

	if resp.Status() == http.StatusNotFound {
		resp.SetHeader("Location", path+"/options?from="+url.QueryEscape(req.URL().Path))
		resp.ReportMovedPermanently()
	} else if resp.Status() == http.StatusMethodNotAllowed {
		resp.WriteString("The pprof interface only support GET request\n")
	} else {
		chain(req, resp)
	}
}
コード例 #8
0
ファイル: xsrf.go プロジェクト: snowsnail/zerver
// Create xsrf token, used as zerver.HandleFunc
func (x *Xsrf) Create(req zerver.Request, resp zerver.Response) {
	tokBytes, err := x.CreateFor(req)
	if err == nil {
		resp.ReportServiceUnavailable()
		return
	}

	if req.Method() == "POST" {
		resp.ReportCreated()
	}

	defer x.Pool.Put(tokBytes)
	x.logger.Warnln(resp.Send("tokBytes", tokBytes))
}
コード例 #9
0
ファイル: image.go プロジェクト: winiceo/zerver
func (h *Handler) Handle(req zerver.Request, resp zerver.Response) {
	req.Wrap(func(req *http.Request, shouldClose bool) (r *http.Request, c bool) {
		r, c = req, shouldClose

		err := req.ParseMultipartForm(h.MaxMemory)
		if err != nil {
			handle.SendErr(resp, handle.BadRequest(err))
			return
		}

		if req.MultipartForm == nil || req.MultipartForm.File == nil {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		files, has := req.MultipartForm.File[h.FileKey]
		if !has || len(files) == 0 {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		file := convertFileHandler(files[0])
		if !h.isSuffixSupported(filepath.Ext(file.Filename)) {
			handle.SendErr(resp, h.ErrNonImage)
			return
		}

		if file.Size() > h.MaxSize {
			handle.SendErr(resp, h.ErrTooLarge)
			return
		}

		fd, err := file.Open()
		if err != nil {
			handle.SendErr(resp, handle.BadRequest(err))
			return
		}

		defer fd.Close()
		path, err := h.SaveImage(fd)
		if err != nil {
			handle.SendErr(resp, err)
			return
		}

		resp.Send(h.PathKey, path)
		return
	})
}
コード例 #10
0
ファイル: xsrf.go プロジェクト: jacobzheng/zerver
// Create xsrf token, used as zerver.HandleFunc
func (x *Xsrf) Create(req zerver.Request, resp zerver.Response) {
	tokBytes, err := x.CreateFor(req)
	if err == nil {
		resp.StatusCode(http.StatusServiceUnavailable)
		return
	}

	if req.ReqMethod() == "POST" {
		resp.StatusCode(http.StatusCreated)
	}

	defer x.Pool.Put(tokBytes)
	err = resp.Send(Token{string(tokBytes)})
	if err != nil {
		x.log.Error(log.M{"msg": "send xsrf token", "err": err.Error()})
	}
}
コード例 #11
0
ファイル: compress.go プロジェクト: fanbuchi/zerver
func Compress(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	encoding := req.AcceptEncodings()

	if strings.Contains(encoding, zerver.ENCODING_GZIP) {
		resp.SetContentEncoding(zerver.ENCODING_GZIP)
		resp.Wrap(gzipWrapper)
	} else if strings.Contains(encoding, zerver.ENCODING_DEFLATE) {
		resp.SetContentEncoding(zerver.ENCODING_DEFLATE)
		resp.Wrap(flateWrapper)
	} else {
		chain(req, resp)
		return
	}

	chain(req, resp)
	resp.RemoveHeader("Content-Length")
}
コード例 #12
0
ファイル: compress.go プロジェクト: jacobzheng/zerver
func Compress(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	encoding := req.GetHeader(zerver.HEADER_ACCEPTENCODING)

	respHeaders := resp.Headers()
	if strings.Contains(encoding, zerver.ENCODING_GZIP) {
		respHeaders.Set(zerver.HEADER_CONTENTENCODING, zerver.ENCODING_GZIP)
		resp.Wrap(gzipWrapper)
	} else if strings.Contains(encoding, zerver.ENCODING_DEFLATE) {
		respHeaders.Set(zerver.HEADER_CONTENTENCODING, zerver.ENCODING_DEFLATE)
		resp.Wrap(flateWrapper)
	} else {
		chain(req, resp)
		return
	}

	chain(req, resp)
	respHeaders.Del(zerver.HEADER_CONTENTLENGTH)
}
コード例 #13
0
ファイル: recovery.go プロジェクト: fanbuchi/zerver
func (r *Recovery) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	defer func() {
		e := recover()
		if e == nil || r.NoStack {
			return
		}

		resp.ReportInternalServerError()

		buffer := bytes.NewBuffer(make([]byte, 0, r.Bufsize))
		fmt.Fprint(buffer, e)
		buf := buffer.Bytes()

		runtime.Stack(buf[len(buf):cap(buf)], false)

		req.Logger().Errorln(unsafe2.String(buf[:cap(buf)]))
	}()

	chain(req, resp)
}
コード例 #14
0
ファイル: cors.go プロジェクト: jacobzheng/zerver
func (c *CORS) preflight(req zerver.Request, resp zerver.Response, method, headers string) {
	origin := "*"
	if !c.allowAll {
		origin = req.GetHeader(_CORS_ORIGIN)
		if !c.allow(origin) {
			resp.StatusCode(http.StatusOK)
			return
		}
	}

	respHeaders := resp.Headers()
	respHeaders.Set(_CORS_ALLOWORIGIN, origin)
	upperMethod := strings.ToUpper(method)

	for _, m := range c.Methods {
		if m == upperMethod {
			respHeaders.Add(_CORS_ALLOWMETHODS, method)
			break
		}
	}

	for _, h := range strings2.SplitAndTrim(headers, ",") {
		for _, ch := range c.Headers {
			if strings.ToLower(h) == ch { // c.Headers already ToLowered when Init
				respHeaders.Add(_CORS_ALLOWHEADERS, ch)
				break
			}
		}
	}

	respHeaders.Set(_CORS_ALLOWCREDENTIALS, c.allowCredentials)
	if c.exposeHeaders != "" {
		respHeaders.Set(_CORS_EXPOSEHEADERS, c.exposeHeaders)
	}

	if c.preflightMaxage != "" {
		respHeaders.Set(_CORS_MAXAGE, c.preflightMaxage)
	}

	resp.StatusCode(http.StatusOK)
}
コード例 #15
0
ファイル: request_id.go プロジェクト: jacobzheng/zerver
func (ri *RequestId) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if req.ReqMethod() == zerver.METHOD_GET {
		chain(req, resp)
		return
	}

	reqId := req.GetHeader(ri.HeaderName)
	if reqId == "" {
		if ri.PassingOnNoId {
			chain(req, resp)
		} else {
			resp.StatusCode(http.StatusBadRequest)
		}
	} else {
		ip := http2.IpOfAddr(req.RemoteAddr())
		id := ip + ":" + reqId
		if err := ri.Store.Save(id); err == ErrRequestIDExist {
			resp.StatusCode(http.StatusForbidden)
		} else if err != nil {
			ri.log.Warn(log.M{"msg": "save request id failed", "err": err.Error()})
		} else {
			chain(req, resp)
			ri.Store.Remove(id)
		}
	}
}
コード例 #16
0
ファイル: cors.go プロジェクト: VicentLiu/zerver
func (c *CORS) preflight(req zerver.Request, resp zerver.Response, method, headers string) {
	origin := "*"
	if !c.allowAll {
		origin = req.Header(_CORS_ORIGIN)
		if !c.allow(origin) {
			goto END
		}
	}

	resp.SetHeader(_CORS_ALLOWORIGIN, origin)
	method = strings.ToUpper(method)

	for _, m := range c.Methods {
		if m == method {
			resp.AddHeader(_CORS_ALLOWMETHODS, m)
			break
		}
	}

	for _, h := range strings2.SplitAndTrim(headers, ",") {
		for _, ch := range c.Headers {
			if strings.ToLower(h) == ch { // c.Headers already ToLowered when Init
				resp.AddHeader(_CORS_ALLOWHEADERS, ch)
				break
			}
		}
	}

	resp.SetHeader(_CORS_ALLOWCREDENTIALS, c.allowCredentials)
	if c.exposeHeaders != "" {
		resp.SetHeader(_CORS_EXPOSEHEADERS, c.exposeHeaders)
	}

	if c.preflightMaxage != "" {
		resp.SetHeader(_CORS_MAXAGE, c.preflightMaxage)
	}

END:
	resp.ReportOK()
}
コード例 #17
0
ファイル: log.go プロジェクト: jacobzheng/zerver
func (l *Log) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	now := time2.Now()
	chain(req, resp)
	cost := time2.Now().Sub(now)

	l.log.Info(log.M{
		"method":     req.ReqMethod(),
		"url":        req.URL().String(),
		"remote":     req.RemoteAddr(),
		"userAgent":  req.GetHeader(zerver.HEADER_USERAGENT),
		"cost":       cost.String(),
		"statusCode": resp.StatusCode(0),
	})
}
コード例 #18
0
ファイル: request_id.go プロジェクト: snowsnail/zerver
func (ri *RequestId) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if req.Method() == "GET" {
		chain(req, resp)
		return
	}

	reqId := req.Header(ri.HeaderName)
	if reqId == "" {
		if ri.PassingOnNoId {
			chain(req, resp)
		} else {
			resp.ReportBadRequest()
			resp.Send("error", ri.Error)
		}
	} else {
		id := req.RemoteIP() + ":" + reqId
		if err := ri.Store.Save(id); err == ErrRequestIDExist {
			resp.ReportForbidden()
			resp.Send("error", ri.ErrorOverlap)
		} else if err != nil {
			ri.logger.Warnln(err)
		} else {
			chain(req, resp)
			ri.Store.Remove(id)
		}
	}
}
コード例 #19
0
ファイル: jsonp.go プロジェクト: jacobzheng/zerver
func (j *JSONP) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if req.ReqMethod() != zerver.METHOD_GET {
		chain(req, resp)
		return
	}

	callback := req.Vars().QueryVar(j.CallbackVar)
	if callback == "" {
		chain(req, resp)
		return
	}

	buffer := bytes.NewBuffer(make([]byte, 0, 256))
	bw := wrap.BuffRespWriter{ // to avoid write header 200 first when write callback name
		Buffer: buffer,
	}
	resp.Wrap(func(w http.ResponseWriter, shouldClose bool) (http.ResponseWriter, bool) {
		bw.ResponseWriter = w
		bw.ShouldClose = shouldClose
		return &bw, shouldClose
	})
	chain(req, resp)
	bw.Buffer = nil

	_, err := io2.WriteString(resp, callback)
	if err == nil {
		_, err = io2.WriteString(resp, "(")
		if err == nil {
			_, err = resp.Write(buffer.Bytes())
			if err == nil {
				_, err = io2.WriteString(resp, ")")
			}
		}
	}
	if err != nil {
		j.log.Warn(log.M{"msg": "write jsonp response failed", "err": err.Error()})
	}
}
コード例 #20
0
ファイル: cors.go プロジェクト: snowsnail/zerver
func (c *CORS) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	reqMethod := req.Header(_CORS_REQUESTMETHOD)
	reqHeaders := req.Header(_CORS_REQUESTHEADERS)

	if req.Method() == "OPTIONS" && (reqMethod != "" || reqHeaders != "") {
		c.preflight(req, resp, reqMethod, reqHeaders)
	} else {
		c.filter(req, resp, chain)
	}
}
コード例 #21
0
ファイル: jsonp.go プロジェクト: fanbuchi/zerver
func (j JSONP) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if req.Method() != "GET" {
		chain(req, resp)
		return
	}

	res, _ := req.ResourceMaster().Resource(resource.RES_JSON)
	if res == nil {
		resp.ReportNotAcceptable()
		return
	}

	callback := req.Param(string(j))
	if callback == "" {
		resp.ReportBadRequest()
		resp.Send("error", "no callback function")
		return
	}

	resp.SetContentType(resource.RES_JSON, res)
	_, err := resp.WriteString(callback)
	if err != nil {
		goto ERROR
	}
	_, err = resp.WriteString("(")
	if err != nil {
		goto ERROR
	}
	chain(req, resp)
	_, err = resp.WriteString(")")
	if err == nil {
		return
	}
ERROR:
	req.Logger().Warnln(err)
}
コード例 #22
0
ファイル: image.go プロジェクト: snowsnail/zerver
func (h *Handler) Handle(req zerver.Request, resp zerver.Response) {
	req.Wrap(func(requ *http.Request, shouldClose bool) (r *http.Request, c bool) {
		r, c = requ, shouldClose

		err := requ.ParseMultipartForm(h.MaxMemory)
		if err != nil {
			handle.SendBadRequest(resp, err)
			return
		}

		if requ.MultipartForm == nil || requ.MultipartForm.File == nil {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		files, has := requ.MultipartForm.File[h.FileKey]
		if !has || len(files) == 0 {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		if len(h.Params) > 0 {
			for _, param := range h.Params {
				if vals := requ.MultipartForm.Value[param]; len(vals) != 0 {
					req.SetAttr(param, vals[0])
				}
			}
		}
		if h.PreChecker != nil {
			if err = h.PreChecker(req); err != nil {
				handle.SendErr(resp, err)
				return
			}
		}

		file := convertFileHandler(files[0])
		if !h.isSuffixSupported(filepath.Ext(file.Filename)) {
			handle.SendErr(resp, h.ErrNonImage)
			return
		}

		if file.Size() > h.MaxSize {
			handle.SendErr(resp, h.ErrTooLarge)
			return
		}

		fd, err := file.Open()
		if err != nil {
			handle.SendBadRequest(resp, err)
			return
		}

		defer fd.Close()

		h.logger.Debugf("upload file: %s, size: %s\n", fd.Filename(), bytesize.ToHuman(uint64(fd.Size())))
		path, err := h.SaveImage(fd, req)
		if err != nil {
			handle.SendErr(resp, err)
			return
		}

		if h.PostDo != nil {
			err := h.PostDo(req)
			if err != nil {
				h.logger.Warnln("PostDo", err)
			}
		}

		resp.SetContentType(resource.RES_JSON, nil)
		resp.Send(h.PathKey, path)
		return
	})
}
コード例 #23
0
ファイル: log.go プロジェクト: snowsnail/zerver
func (l *Log) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if l.CountTime {
		now := time2.Now()

		chain(req, resp)
		cost := time2.Now().Sub(now)
		l.logger.Infoln(
			cost.String(),
			resp.Status(),
			req.Method(),
			req.URL().Path,
			req.RemoteIP(),
			req.UserAgent())
	} else {
		chain(req, resp)
		l.logger.Infoln(
			resp.Status(),
			req.Method(),
			req.URL().Path,
			req.RemoteIP(),
			req.UserAgent())
	}
}
コード例 #24
0
ファイル: xsrf.go プロジェクト: snowsnail/zerver
func (x *Xsrf) VerifyFor(req zerver.Request) bool {
	m := req.Method()
	if !x.FilterGet && (m == "GET" || m == "HEAD" || m == "OPTIONS") {
		return true
	}

	token := req.Header(_HEADER_XSRFTOKEN)
	if token == "" {
		token = req.Header(_HEADER_CSRFTOKEN)
		if token == "" {
			token = req.Param(_XSRF_PARAM_NAME)
			if token == "" {
				return false
			}
		}
	}

	data := x.verify(unsafe2.Bytes(token))
	if data != nil {
		x.Pool.Put(data)
		t, ip, agent := x.TokenInfo.Unmarshal(data)
		return t != -1 &&
			t+x.Timeout >= time2.Now().Unix() &&
			ip == req.RemoteIP() &&
			agent == req.UserAgent()
	}

	return false
}
コード例 #25
0
ファイル: image.go プロジェクト: jacobzheng/zerver
func (h *Handler) Handle(req zerver.Request, resp zerver.Response) {
	req.Wrap(func(requ *http.Request, shouldClose bool) (r *http.Request, c bool) {
		r, c = requ, shouldClose

		err := requ.ParseMultipartForm(h.MaxMemory)
		if err != nil {
			handle.SendBadRequest(resp, err)
			return
		}

		if requ.MultipartForm == nil || requ.MultipartForm.File == nil {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		files, has := requ.MultipartForm.File[h.FileKey]
		if !has || len(files) == 0 {
			handle.SendErr(resp, h.ErrNoFile)
			return
		}

		if len(h.Params) > 0 {
			for _, param := range h.Params {
				if vals := requ.MultipartForm.Value[param]; len(vals) != 0 {
					req.SetAttr(param, vals[0])
				}
			}
		}
		if h.PreChecker != nil {
			if err = h.PreChecker(req); err != nil {
				handle.SendErr(resp, err)
				return
			}
		}

		file := convertFileHandler(files[0])
		if !h.isSuffixSupported(filepath.Ext(file.Filename)) {
			handle.SendErr(resp, h.ErrNonImage)
			return
		}

		if file.Size() > h.MaxSize {
			handle.SendErr(resp, h.ErrTooLarge)
			return
		}

		fd, err := file.Open()
		if err != nil {
			handle.SendBadRequest(resp, err)
			return
		}
		defer fd.Close()

		if h.log.IsDebugEnable() {
			h.log.Debug(log.M{"msg": "file upload", "filename": fd.Filename(), "bytes": fd.Size()})
		}

		path, err := h.SaveImage(fd, req)
		if err != nil {
			handle.SendErr(resp, err)
			return
		}

		if h.PostDo != nil {
			err := h.PostDo(req)
			if err != nil {
				h.log.Warn(log.M{"msg": "call post do failed", "err": err.Error()})
			}
		}

		resp.Send(Path{path})
		return
	})
}
コード例 #26
0
ファイル: log.go プロジェクト: VicentLiu/zerver
func (l *Log) Filter(req zerver.Request, resp zerver.Response, chain zerver.FilterChain) {
	if l.CountTime {
		nano := time.Now().UnixNano()

		chain(req, resp)
		nano = time.Now().UnixNano() - nano
		l.logger.Infoln(
			time2.ToHuman(nano),
			resp.Status(),
			req.Method(),
			req.URL().Path,
			req.RemoteIP(),
			req.UserAgent())
	} else {
		chain(req, resp)
		l.logger.Infoln(
			resp.Status(),
			req.Method(),
			req.URL().Path,
			req.RemoteIP(),
			req.UserAgent())
	}
}