context修改

This commit is contained in:
Liujian
2021-11-11 20:23:52 +08:00
parent b296406448
commit c223628ef9
17 changed files with 625 additions and 373 deletions

View File

@@ -428,11 +428,11 @@ func TestCreateChecker(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
checker, err := http_service.Parse(tt.args.pattern)
if (err != nil) != tt.wantErr {
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("parse() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(checker, tt.want) {
t.Errorf("Parse() got = %v, want %v", checker, tt.want)
t.Errorf("parse() got = %v, want %v", checker, tt.want)
}
//验证check
if checker != nil {

View File

@@ -52,10 +52,10 @@ func createTestContext() {
// http-service
//request1, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
//request1.Header.SetDriver("Authorization-Type", "ak/sk")
//request1.Header.SetDriver("Content-Type", "application/json")
//request1.Header.SetDriver("x-gateway-date", "20200605T104456Z")
//request1.Header.SetDriver("Authorization", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
//request1.IHeader.SetDriver("Authorization-Type", "ak/sk")
//request1.IHeader.SetDriver("Content-Type", "application/json")
//request1.IHeader.SetDriver("x-gateway-date", "20200605T104456Z")
//request1.IHeader.SetDriver("Authorization", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
//Context1 := http_context.NewContext(request1, &writer{})
// fast http-service
@@ -80,10 +80,10 @@ func createTestContext() {
// http-service
//request2, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
//request2.Header.SetDriver("Authorization-Type", "ak/sk")
//request2.Header.SetDriver("Content-Type", "application/json")
//request2.Header.SetDriver("x-gateway-date", "20200605T104456Z")
//request2.Header.SetDriver("Authorization", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=bb18110ddf327a9c1222a551527896d59cb854ca9084078cfa3a6eb23de3ddb8")
//request2.IHeader.SetDriver("Authorization-Type", "ak/sk")
//request2.IHeader.SetDriver("Content-Type", "application/json")
//request2.IHeader.SetDriver("x-gateway-date", "20200605T104456Z")
//request2.IHeader.SetDriver("Authorization", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=bb18110ddf327a9c1222a551527896d59cb854ca9084078cfa3a6eb23de3ddb8")
//Context2 := http_context.NewContext(request2, &writer{})
// https
@@ -106,10 +106,10 @@ func createTestContext() {
//传输了不存在的ak
// http-service
//request3, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
//request3.Header.SetDriver("Authorization-Type", "ak/sk")
//request3.Header.SetDriver("Content-Type", "application/json")
//request3.Header.SetDriver("x-gateway-date", "20200605T104456Z")
//request3.Header.SetDriver("Authorization", "HMAC-SHA256 Access=dsaasdasda, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
//request3.IHeader.SetDriver("Authorization-Type", "ak/sk")
//request3.IHeader.SetDriver("Content-Type", "application/json")
//request3.IHeader.SetDriver("x-gateway-date", "20200605T104456Z")
//request3.IHeader.SetDriver("Authorization", "HMAC-SHA256 Access=dsaasdasda, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
//Context3 := http_context.NewContext(request3, &writer{})
//testContexts = append(testContexts, Context3)

View File

@@ -81,7 +81,7 @@ func (a *apikey) getAuthValue(ctx http_service.IHttpContext) (string, error) {
// 判断鉴权值是否在query
if authorization := ctx.Request().URL().Query().Get("Apikey"); authorization != "" {
if a.hideCredential {
ctx.Proxy().Querys().Del("Apikey")
ctx.Proxy().Queries().Del("Apikey")
}
return authorization, nil
}

View File

@@ -231,7 +231,7 @@ func TestFormAuthorization(t *testing.T) {
"Content-Type": "application/x-www-form-urlencoded",
}
// http-service
//req, err := buildRequest(headers, nil, formBody.Encode())
//req, err := buildRequest(headers, nil, formBody.encode())
//if err != nil {
// t.Error(err)
// return

View File

@@ -293,22 +293,22 @@ func decodeSegment(seg string) ([]byte, error) {
return base64.URLEncoding.DecodeString(seg)
}
// Encode JWT specific base64url encoding with padding stripped
// encode JWT specific base64url encoding with padding stripped
func encodeSegment(seg []byte) string {
return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
}
//ParseRSAPublicKeyFromPEM Parse PEM encoded PKCS1 or PKCS8 public key
//ParseRSAPublicKeyFromPEM parse PEM encoded PKCS1 or PKCS8 public key
func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
var err error
// Parse PEM block
// parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, errKeyMustBePEMEncoded
}
// Parse the key
// parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
@@ -327,17 +327,17 @@ func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
return pkey, nil
}
//ParseECPublicKeyFromPEM Parse PEM encoded PKCS1 or PKCS8 public key
//ParseECPublicKeyFromPEM parse PEM encoded PKCS1 or PKCS8 public key
func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
var err error
// Parse PEM block
// parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, errKeyMustBePEMEncoded
}
// Parse the key
// parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
@@ -520,7 +520,7 @@ func (j *jwt) retrieveJWTToken(context http_service.IHttpContext) (string, error
if value := context.Request().URL().Query().Get(tokenName); value != "" {
if j.hideCredentials {
context.Proxy().Querys().Del(tokenName)
context.Proxy().Queries().Del(tokenName)
}
return value, nil
}

View File

@@ -120,7 +120,7 @@ func (s *serviceWorker) ProxyAddr() string {
}
//Handle 将服务发送到负载
func (s *serviceWorker) Handle(ctx *http_context.Context, router service.IRouterEndpoint) error {
func (s *serviceWorker) Handle(ctx http_service.IHttpContext) error {
// 构造context
defer func() {
if e := recover(); e != nil {

View File

@@ -117,11 +117,11 @@ func (t *TestContext) DelHeader(key string) {
panic("implement me")
}
func (t *TestContext) Set() http_service.Header {
func (t *TestContext) Set() http_service.IHeader {
panic("implement me")
}
func (t *TestContext) Append() http_service.Header {
func (t *TestContext) Append() http_service.IHeader {
panic("implement me")
}
@@ -161,11 +161,11 @@ func (t *TestContext) RequestId() string {
panic("implement me")
}
func (t *TestContext) Request() http_service.RequestReader {
func (t *TestContext) Request() http_service.IRequestReader {
panic("implement me")
}
func (t *TestContext) Proxy() http_service.Request {
func (t *TestContext) Proxy() http_service.IRequest {
panic("implement me")
}
@@ -173,7 +173,7 @@ func (t *TestContext) Labels() map[string]string {
panic("implement me")
}
func (t *TestContext) ProxyResponse() http_service.ResponseReader {
func (t *TestContext) ProxyResponse() http_service.IResponseReader {
panic("implement me")
}

1
go.mod
View File

@@ -4,7 +4,6 @@ go 1.15
require (
github.com/eolinker/eosc v0.2.3
github.com/eolinker/goku-standard-plugin v0.1.5
github.com/ghodss/yaml v1.0.0
github.com/go-basic/uuid v1.0.0
github.com/hashicorp/consul/api v1.9.1

View File

@@ -6,7 +6,7 @@ import (
"encoding/xml"
"errors"
goku_plugin "github.com/eolinker/goku-standard-plugin"
http_service "github.com/eolinker/eosc/http-service"
"io/ioutil"
"net/http"
@@ -23,13 +23,24 @@ var (
errorNotAllowRaw = errors.New("contentType is not allow Raw")
)
const (
MultipartForm = "multipart/form-data"
FormData = "application/x-www-form-urlencoded"
TEXT = "text/plain"
JSON = "application/json"
JavaScript = "application/javascript"
AppLicationXML = "application/xml"
TextXML = "text/xml"
Html = "text/html"
)
//BodyRequestHandler body请求处理器
type BodyRequestHandler struct {
form url.Values
rawBody []byte
orgContentParam map[string]string
contentType string
files map[string]*goku_plugin.FileHeader
files map[string]*http_service.FileHeader
isInit bool
isWriteRaw bool
@@ -37,33 +48,83 @@ type BodyRequestHandler struct {
object interface{}
}
//Files 获取文件参数
func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) {
//GetForm 获取表单参数
func (b *BodyRequestHandler) GetForm(key string) string {
err := b.Parse()
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != FormData && contentType != MultipartForm {
return ""
}
b.parse()
if !b.isInit || b.form == nil {
return ""
}
return b.form.Get(key)
}
//ContentType 获取contentType
func (b *BodyRequestHandler) ContentType() string {
return b.contentType
}
//BodyForm 获取表单参数
func (b *BodyRequestHandler) BodyForm() (url.Values, error) {
err := b.parse()
if err != nil {
return nil, err
}
return b.form, nil
}
//RawBody 获取raw数据
func (b *BodyRequestHandler) RawBody() ([]byte, error) {
err := b.encode()
if err != nil {
return nil, err
}
return b.rawBody, nil
}
//Files 获取文件参数
func (b *BodyRequestHandler) Files() (map[string]*http_service.FileHeader, error) {
err := b.parse()
if err != nil {
return nil, err
}
return b.files, nil
}
//Parse 解析
func (b *BodyRequestHandler) Parse() error {
func (b *BodyRequestHandler) GetFile(key string) (file *http_service.FileHeader, has bool) {
err := b.parse()
if err != nil {
return nil, false
}
file, has = b.files[key]
return file, has
}
//parse 解析
func (b *BodyRequestHandler) parse() error {
if b.isInit {
return nil
}
contentType, _, _ := mime.ParseMediaType(b.contentType)
switch contentType {
case goku_plugin.JSON:
case JSON:
{
e := json.Unmarshal(b.rawBody, &b.object)
if e != nil {
return e
}
}
case goku_plugin.AppLicationXML, goku_plugin.TextXML:
case AppLicationXML, TextXML:
{
e := xml.Unmarshal(b.rawBody, &b.object)
if e != nil {
@@ -72,7 +133,7 @@ func (b *BodyRequestHandler) Parse() error {
}
case goku_plugin.MultipartForm:
case MultipartForm:
{
r, err := multipartReader(b.contentType, false, b.rawBody)
if err != nil {
@@ -90,7 +151,7 @@ func (b *BodyRequestHandler) Parse() error {
b.form[k] = append(b.form[k], v...)
}
b.files = make(map[string]*goku_plugin.FileHeader)
b.files = make(map[string]*http_service.FileHeader)
for k, fs := range form.File {
if len(fs) > 0 {
@@ -103,7 +164,7 @@ func (b *BodyRequestHandler) Parse() error {
return err
}
b.files[k] = &goku_plugin.FileHeader{
b.files[k] = &http_service.FileHeader{
FileName: fs[0].Filename,
Data: fileData,
Header: fs[0].Header,
@@ -113,7 +174,7 @@ func (b *BodyRequestHandler) Parse() error {
b.object = b.form
}
case goku_plugin.FormData:
case FormData:
{
form, err := url.ParseQuery(string(b.rawBody))
if err != nil {
@@ -135,50 +196,15 @@ func (b *BodyRequestHandler) Parse() error {
return nil
}
//GetForm 获取表单参数
func (b *BodyRequestHandler) GetForm(key string) string {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
return ""
}
b.Parse()
if !b.isInit || b.form == nil {
return ""
}
return b.form.Get(key)
}
//GetFile 获取文件参数
func (b *BodyRequestHandler) GetFile(key string) (file *goku_plugin.FileHeader, has bool) {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
return nil, false
}
err := b.Parse()
if err != nil {
return nil, false
}
if !b.isInit || b.files == nil {
return nil, false
}
f, has := b.files[key]
return f, has
}
//SetToForm 设置表单参数
func (b *BodyRequestHandler) SetToForm(key, value string) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
return errorNotForm
}
err := b.Parse()
err := b.parse()
if err != nil {
return err
}
@@ -196,10 +222,10 @@ func (b *BodyRequestHandler) SetToForm(key, value string) error {
//AddForm 新增表单参数
func (b *BodyRequestHandler) AddForm(key, value string) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
return errorNotForm
}
err := b.Parse()
err := b.parse()
if err != nil {
return err
}
@@ -213,13 +239,13 @@ func (b *BodyRequestHandler) AddForm(key, value string) error {
}
//AddFile 新增文件参数
func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) error {
func (b *BodyRequestHandler) AddFile(key string, file *http_service.FileHeader) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
return errorNotMultipart
}
err := b.Parse()
err := b.parse()
if err != nil {
return err
}
@@ -229,7 +255,7 @@ func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) e
return nil
}
if b.files == nil {
b.files = make(map[string]*goku_plugin.FileHeader)
b.files = make(map[string]*http_service.FileHeader)
}
b.files[key] = file
@@ -238,29 +264,14 @@ func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) e
//Clone 克隆body
func (b *BodyRequestHandler) Clone() *BodyRequestHandler {
rawbody, _ := b.RawBody()
return newBodyRequestHandler(b.contentType, rawbody)
rawBody, _ := b.RawBody()
return newBodyRequestHandler(b.contentType, rawBody)
}
//ContentType 获取contentType
func (b *BodyRequestHandler) ContentType() string {
return b.contentType
}
//BodyForm 获取表单参数
func (b *BodyRequestHandler) BodyForm() (url.Values, error) {
err := b.Parse()
if err != nil {
return nil, err
}
return b.form, nil
}
//BodyInterface 获取请求体对象
func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
err := b.Parse()
err := b.parse()
if err != nil {
return nil, err
}
@@ -268,25 +279,14 @@ func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
return b.object, nil
}
//RawBody 获取raw数据
func (b *BodyRequestHandler) RawBody() ([]byte, error) {
err := b.Encode()
if err != nil {
return nil, err
}
return b.rawBody, nil
}
//Encode encode
func (b *BodyRequestHandler) Encode() error {
//encode encode
func (b *BodyRequestHandler) encode() error {
if b.isWriteRaw {
return nil
}
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
b.isWriteRaw = true
return nil
}
@@ -336,10 +336,10 @@ func (b *BodyRequestHandler) Encode() error {
func (b *BodyRequestHandler) SetForm(values url.Values) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
return errorNotForm
}
b.Parse()
b.parse()
b.form = values
b.isWriteRaw = false
@@ -347,13 +347,13 @@ func (b *BodyRequestHandler) SetForm(values url.Values) error {
}
//SetFile 设置文件参数
func (b *BodyRequestHandler) SetFile(files map[string]*goku_plugin.FileHeader) error {
func (b *BodyRequestHandler) SetFile(files map[string]*http_service.FileHeader) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
if contentType != FormData && contentType != MultipartForm {
return errorNotForm
}
b.Parse()
b.parse()
b.files = files
// b.form = values
b.isWriteRaw = false

View File

@@ -3,206 +3,105 @@ package http_context
import (
"context"
"encoding/json"
"net/http"
"github.com/valyala/fasthttp"
http_service "github.com/eolinker/eosc/http-service"
access_field "github.com/eolinker/goku/node/common/access-field"
uuid "github.com/satori/go.uuid"
)
//Context context
var _ http_service.IHttpContext = (*Context)(nil)
//Context requestCtx
type Context struct {
context *fasthttp.RequestCtx
requestOrg *fasthttp.Request
proxyRequest *fasthttp.Request
requestCtx *fasthttp.RequestCtx
requestOrg *fasthttp.Request
proxyRequest *ProxyRequest
proxyResponse *fasthttp.Response
Body []byte
body []byte
requestID string
RestfulParam map[string]string
LogFields *access_field.Fields
request IRequest
labels map[string]string
bodyHandler *BodyRequestHandler
}
func (ctx *Context) SetStatus(code int, status string) {
panic("implement me")
}
func (ctx *Context) Request() http_service.RequestReader {
panic("implement me")
}
func (ctx *Context) ProxyResponse() http_service.ResponseReader {
panic("implement me")
code int
status string
response *Response
requestReader *RequestReader
ctx context.Context
}
func (ctx *Context) Context() context.Context {
panic("implement me")
if ctx.ctx == nil {
ctx.ctx = context.Background()
}
return ctx.ctx
}
func (ctx *Context) Value(key interface{}) interface{} {
panic("implement me")
return ctx.Context().Value(key)
}
func (ctx *Context) WithValue(key, val interface{}) {
panic("implement me")
ctx.ctx = context.WithValue(ctx.Context(), key, val)
}
func (ctx *Context) GetHeader(name string) string {
panic("implement me")
func (ctx *Context) Response() http_service.IResponse {
if ctx.response == nil {
ctx.response = NewResponse(ctx.proxyResponse)
}
return ctx.response
}
func (ctx *Context) Headers() http.Header {
panic("implement me")
func (ctx *Context) Proxy() http_service.IRequest {
return ctx.proxyRequest
}
func (ctx *Context) SetHeader(key, value string) {
panic("implement me")
func (ctx *Context) SetStatus(code int, status string) {
ctx.code, ctx.status = code, status
}
func (ctx *Context) AddHeader(key, value string) {
panic("implement me")
}
func (ctx *Context) DelHeader(key string) {
panic("implement me")
}
func (ctx *Context) Set() http_service.Header {
panic("implement me")
}
func (ctx *Context) Append() http_service.Header {
panic("implement me")
}
func (ctx *Context) Cookie(name string) (*http.Cookie, error) {
panic("implement me")
}
func (ctx *Context) Cookies() []*http.Cookie {
panic("implement me")
}
func (ctx *Context) AddCookie(c *http.Cookie) {
panic("implement me")
}
func (ctx *Context) StatusCode() int {
panic("implement me")
}
func (ctx *Context) Status() string {
panic("implement me")
}
func (ctx *Context) GetBody() []byte {
panic("implement me")
}
func (ctx *Context) Proxy() http_service.Request {
panic("implement me")
}
func (ctx *Context) SetStoreValue(key string, value interface{}) error {
panic("implement me")
}
func (ctx *Context) GetStoreValue(key string) (interface{}, bool) {
panic("implement me")
func (ctx *Context) Request() http_service.IRequestReader {
if ctx.requestReader == nil {
ctx.requestReader = NewRequestReader(ctx.requestOrg, ctx.requestCtx.RemoteAddr().String())
}
return ctx.requestReader
}
//NewContext 创建Context
func NewContext(ctx *fasthttp.RequestCtx) http_service.IHttpContext {
func NewContext(ctx *fasthttp.RequestCtx) *Context {
id := uuid.NewV4()
requestID := id.String()
newRequest := &ctx.Request
newCtx := &Context{
context: ctx,
requestOrg: fasthttp.AcquireRequest(),
proxyRequest: fasthttp.AcquireRequest(),
requestID: requestID,
LogFields: access_field.NewFields(),
requestCtx: ctx,
requestOrg: fasthttp.AcquireRequest(),
requestID: requestID,
}
proxyRequest := fasthttp.AcquireRequest()
newRequest.CopyTo(newCtx.requestOrg)
newRequest.CopyTo(newCtx.proxyRequest)
newRequest.CopyTo(proxyRequest)
newCtx.LogFields.RequestHeader = newCtx.requestOrg.Header.String()
newCtx.LogFields.RequestMsg = string(newCtx.Body)
newCtx.LogFields.RequestMsgSize = len(newCtx.Body)
newCtx.LogFields.RequestUri = string(newCtx.requestOrg.RequestURI())
newCtx.LogFields.RequestID = requestID
newCtx.proxyRequest = NewProxyRequest(NewRequestReader(proxyRequest, ""))
return newCtx
}
func (ctx *Context) Labels() map[string]string {
if ctx.labels == nil {
ctx.labels = map[string]string{}
}
return ctx.labels
}
func (ctx *Context) SetLabels(labels map[string]string) {
if ctx.labels == nil {
ctx.labels = make(map[string]string)
}
if labels != nil {
for k, v := range labels {
ctx.labels[k] = v
}
}
}
//RequestId 请求ID
func (ctx *Context) RequestId() string {
return ctx.requestID
}
//func (ctx *Context) Request() IRequest {
// if ctx.request == nil {
// ctx.request = newRequest(ctx.requestOrg)
// }
// return ctx.request
//}
func (ctx *Context) RequestOrg() *fasthttp.Request {
return ctx.requestOrg
}
func (ctx *Context) ProxyRequest() *fasthttp.Request {
return ctx.proxyRequest
}
//func (ctx *Context) ProxyResponse() *fasthttp.Response {
// return ctx.proxyResponse
//}
func (ctx *Context) BodyHandler() *BodyRequestHandler {
if ctx.bodyHandler == nil {
r := ctx.Request()
body, _ := r.RawBody()
ctx.bodyHandler = newBodyRequestHandler(r.ContentType(), body)
}
return ctx.bodyHandler
}
func (ctx *Context) SetBody(body []byte) {
ctx.context.SetBody(body)
ctx.requestCtx.SetBody(body)
}
func (ctx *Context) SetResponse(response *fasthttp.Response) {
ctx.Body = response.Body()
ctx.body = response.Body()
ctx.proxyResponse = response
}
//Finish finish
func (ctx *Context) Finish() {
ctx.LogFields.ResponseMsg = string(ctx.Body)
ctx.LogFields.ResponseMsgSize = len(ctx.Body)
ctx.proxyResponse.CopyTo(&ctx.context.Response)
ctx.proxyResponse.CopyTo(&ctx.requestCtx.Response)
return
}
@@ -212,10 +111,10 @@ func (ctx *Context) SetError(err error) {
"msg": err.Error(),
}
errByte, _ := json.Marshal(result)
ctx.Body = errByte
ctx.body = errByte
}
func NotFound(ctx *Context) {
ctx.context.SetStatusCode(404)
ctx.context.SetBody([]byte("404 Not Found"))
ctx.requestCtx.SetStatusCode(404)
ctx.requestCtx.SetBody([]byte("404 Not Found"))
}

115
node/http-context/proxy.go Normal file
View File

@@ -0,0 +1,115 @@
package http_context
import (
"net/http"
"net/url"
http_service "github.com/eolinker/eosc/http-service"
)
var _ http_service.IRequest = (*ProxyRequest)(nil)
type ProxyRequest struct {
*RequestReader
headers http.Header
form url.Values
file map[string]*http_service.FileHeader
contentType string
body []byte
uri *url.URL
method string
}
func NewProxyRequest(requestReader *RequestReader) *ProxyRequest {
return &ProxyRequest{RequestReader: requestReader}
}
func (r *ProxyRequest) SetHeader(key, value string) {
if r.headers == nil {
r.headers = r.Headers()
}
r.headers.Set(key, value)
}
func (r *ProxyRequest) AddHeader(key, value string) {
if r.headers == nil {
r.headers = r.Headers()
}
r.headers.Add(key, value)
}
func (r *ProxyRequest) DelHeader(key string) {
if r.headers == nil {
r.headers = r.Headers()
}
r.headers.Del(key)
}
func (r *ProxyRequest) SetForm(values url.Values) error {
r.form = values
return nil
}
func (r *ProxyRequest) SetToForm(key, value string) error {
if r.form == nil {
form, err := r.BodyForm()
if err != nil {
return err
}
r.form = form
}
r.form.Set(key, value)
return nil
}
func (r *ProxyRequest) AddForm(key, value string) error {
if r.form == nil {
form, err := r.BodyForm()
if err != nil {
return err
}
r.form = form
}
r.form.Set(key, value)
return nil
}
func (r *ProxyRequest) AddFile(key string, file *http_service.FileHeader) error {
if r.form == nil {
file, err := r.Files()
if err != nil {
return err
}
r.file = file
}
r.file[key] = file
return nil
}
func (r *ProxyRequest) SetRaw(contentType string, body []byte) {
r.contentType, r.body = contentType, body
}
func (r *ProxyRequest) TargetServer() string {
if r.uri == nil {
uri := r.URL()
r.uri = &uri
}
return r.uri.Host
}
func (r *ProxyRequest) TargetURL() string {
if r.uri == nil {
uri := r.URL()
r.uri = &uri
}
return r.uri.Path
}
func (r *ProxyRequest) SetMethod(s string) {
r.method = s
}
func (r *ProxyRequest) SetURL(url url.URL) {
r.uri = &url
}

View File

@@ -0,0 +1,122 @@
package http_context
//type Value map[string]string
//
//func (h Value) Get(key string) (string, bool) {
// v, ok := h[key]
// return v, ok
//}
//
//type IRequest interface {
// Host() string
// Method() string
// Path() string
// ContentType() string
// Header() Value
// Query() Value
// RawQuery() string
// RawBody() []byte
//}
//
//type ProxyRequest struct {
// req *fasthttp.ProxyRequest
// path string
// host string
// method string
// header Value
// query Value
// rawQuery string
// rawBody []byte
// contentType string
//}
//
//func (r *ProxyRequest) Host() string {
// if r.host == "" {
// r.host = strings.Split(string(r.req.Header.Host()), ":")[0]
// }
// return r.host
//}
//
//func (r *ProxyRequest) Method() string {
// if r.method == "" {
// r.method = string(r.req.Header.Method())
// }
// return r.method
//}
//
//func (r *ProxyRequest) Path() string {
// if r.path == "" {
// r.path = string(r.req.URI().Path())
// }
// return r.path
//}
//
//func (r *ProxyRequest) Header() Value {
// if r.header == nil {
// r.header = make(Value)
// hs := strings.Split(r.req.Header.String(), "\r\n")
// for _, h := range hs {
// vs := strings.Split(h, ":")
// if len(vs) < 2 {
// if vs[0] == "" {
// continue
// }
// r.header[vs[0]] = ""
// continue
// }
// r.header[vs[0]] = strings.TrimSpace(vs[1])
//
// }
// }
// return r.header
//}
//
//func (r *ProxyRequest) Query() Value {
// if r.rawQuery == "" {
// r.rawQuery = string(r.req.URI().QueryString())
// }
// if r.query == nil {
// r.query = make(Value)
// qs := strings.Split(r.rawQuery, "&")
// for _, q := range qs {
// vs := strings.Split(q, "=")
// if len(vs) < 2 {
// if vs[0] == "" {
// continue
// }
// r.query[vs[0]] = ""
// continue
// }
// r.query[vs[0]] = strings.TrimSpace(vs[1])
// }
// }
// return r.query
//}
//
//func (r *ProxyRequest) RawQuery() string {
// if r.rawQuery == "" {
// r.rawQuery = string(r.req.URI().QueryString())
// }
// return r.rawQuery
//}
//
//func (r *ProxyRequest) RawBody() []byte {
// if r.rawBody == nil {
// r.rawBody = r.req.Body()
// }
// return r.rawBody
//}
//
//func (r *ProxyRequest) ContentType() string {
// if r.contentType == "" {
// r.contentType = string(r.req.Header.ContentType())
// }
// return r.contentType
//}
//
//func newRequest(req *fasthttp.ProxyRequest) IRequest {
// newReq := &ProxyRequest{
// req: req,
// }
// return newReq
//}

View File

@@ -1,65 +1,84 @@
package http_context
import (
"net/http"
"net/url"
"strings"
http_service "github.com/eolinker/eosc/http-service"
"github.com/valyala/fasthttp"
)
type Value map[string]string
var _ http_service.IRequestReader = (*RequestReader)(nil)
func (h Value) Get(key string) (string, bool) {
v, ok := h[key]
return v, ok
}
type IRequest interface {
Host() string
Method() string
Path() string
ContentType() string
Header() Value
Query() Value
RawQuery() string
RawBody() []byte
}
type Request struct {
type RequestReader struct {
req *fasthttp.Request
path string
bodyHandler *BodyRequestHandler
remoteAddr string
clientIP string
host string
method string
header Value
query Value
rawQuery string
rawBody []byte
headers http.Header
scheme string
uri *url.URL
contentType string
}
func (r *Request) Host() string {
if r.host == "" {
r.host = strings.Split(string(r.req.Header.Host()), ":")[0]
}
return r.host
func NewRequestReader(req *fasthttp.Request, remoteAddr string) *RequestReader {
return &RequestReader{req: req, remoteAddr: remoteAddr}
}
func (r *Request) Method() string {
if r.method == "" {
r.method = string(r.req.Header.Method())
func (r *RequestReader) ContentType() string {
if r.contentType == "" {
r.contentType = string(r.req.Header.ContentType())
}
return r.method
return r.contentType
}
func (r *Request) Path() string {
if r.path == "" {
r.path = string(r.req.URI().Path())
func (r *RequestReader) BodyForm() (url.Values, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.path
return r.bodyHandler.BodyForm()
}
func (r *Request) Header() Value {
if r.header == nil {
r.header = make(Value)
func (r *RequestReader) Files() (map[string]*http_service.FileHeader, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.Files()
}
func (r *RequestReader) GetForm(key string) string {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.GetForm(key)
}
func (r *RequestReader) GetFile(key string) (file *http_service.FileHeader, has bool) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.GetFile(key)
}
func (r *RequestReader) RawBody() ([]byte, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.RawBody()
}
func (r *RequestReader) GetHeader(name string) string {
return r.Headers().Get(name)
}
func (r *RequestReader) Headers() http.Header {
if r.headers == nil {
r.headers = make(http.Header)
hs := strings.Split(r.req.Header.String(), "\r\n")
for _, h := range hs {
vs := strings.Split(h, ":")
@@ -67,62 +86,66 @@ func (r *Request) Header() Value {
if vs[0] == "" {
continue
}
r.header[vs[0]] = ""
r.headers[vs[0]] = []string{""}
continue
}
r.header[vs[0]] = strings.TrimSpace(vs[1])
r.headers[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
}
return r.header
return r.headers
}
func (r *Request) Query() Value {
if r.rawQuery == "" {
r.rawQuery = string(r.req.URI().QueryString())
func (r *RequestReader) Method() string {
if r.method == "" {
r.method = string(r.req.Header.Method())
}
if r.query == nil {
r.query = make(Value)
qs := strings.Split(r.rawQuery, "&")
for _, q := range qs {
vs := strings.Split(q, "=")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
r.query[vs[0]] = ""
continue
}
r.query[vs[0]] = strings.TrimSpace(vs[1])
return r.method
}
func (r *RequestReader) URL() url.URL {
if r.uri == nil {
r.uri, _ = url.Parse(r.req.URI().String())
}
return *r.uri
}
func (r *RequestReader) RequestURI() string {
return string(r.req.RequestURI())
}
func (r *RequestReader) Host() string {
if r.host == "" {
r.host = strings.Split(string(r.req.Header.Host()), ":")[0]
}
return r.host
}
func (r *RequestReader) RemoteAddr() string {
if r.clientIP == "" {
clientIP := string(r.req.Header.Peek("X-Forwarded-For"))
if index := strings.IndexByte(clientIP, ','); index >= 0 {
clientIP = clientIP[0:index]
}
clientIP = strings.TrimSpace(clientIP)
if len(clientIP) < 1 {
clientIP = strings.TrimSpace(string(r.req.Header.Peek("X-Real-Ip")))
if len(clientIP) < 1 {
clientIP = r.remoteAddr
}
}
r.clientIP = clientIP
}
return r.query
return r.clientIP
}
func (r *Request) RawQuery() string {
if r.rawQuery == "" {
r.rawQuery = string(r.req.URI().QueryString())
func (r *RequestReader) Scheme() string {
if r.scheme == "" {
r.scheme = string(r.req.URI().Scheme())
}
return r.rawQuery
return r.scheme
}
func (r *Request) RawBody() []byte {
if r.rawBody == nil {
r.rawBody = r.req.Body()
}
return r.rawBody
}
func (r *Request) ContentType() string {
if r.contentType == "" {
r.contentType = string(r.req.Header.ContentType())
}
return r.contentType
}
func newRequest(req *fasthttp.Request) IRequest {
newReq := &Request{
req: req,
}
return newReq
func (r *RequestReader) Request() *fasthttp.Request {
return r.req
}

View File

@@ -0,0 +1,110 @@
package http_context
import (
"net/http"
"strconv"
"strings"
http_service "github.com/eolinker/eosc/http-service"
"github.com/valyala/fasthttp"
)
var _ http_service.IResponse = (*Response)(nil)
type Response struct {
response *fasthttp.Response
headers http.Header
code int
status string
}
func (r *Response) Headers() http.Header {
if r.headers == nil {
r.headers = make(http.Header)
hs := strings.Split(r.response.Header.String(), "\r\n")
for _, h := range hs {
vs := strings.Split(h, ":")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
r.headers[vs[0]] = []string{""}
continue
}
r.headers[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
}
return r.headers
}
func NewResponse(response *fasthttp.Response) *Response {
return &Response{response: response}
}
func (r *Response) initHeader() {
r.headers = make(http.Header)
hs := strings.Split(r.response.Header.String(), "\r\n")
for _, h := range hs {
vs := strings.Split(h, ":")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
r.headers[vs[0]] = []string{""}
continue
}
r.headers[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
}
func (r *Response) GetHeader(name string) string {
if r.headers == nil {
r.initHeader()
}
return r.headers.Get(name)
}
func (r *Response) GetBody() []byte {
return r.response.Body()
}
func (r *Response) StatusCode() int {
return r.response.StatusCode()
}
func (r *Response) Status() string {
return strconv.Itoa(r.response.StatusCode())
}
func (r *Response) SetHeader(key, value string) {
if r.headers == nil {
r.response.Header.Set(key, value)
return
}
r.headers.Set(key, value)
}
func (r *Response) AddHeader(key, value string) {
if r.headers == nil {
r.response.Header.Add(key, value)
return
}
r.headers.Add(key, value)
}
func (r *Response) DelHeader(key string) {
if r.headers == nil {
r.response.Header.Del(key)
return
}
r.headers.Del(key)
}
func (r *Response) SetStatus(code int, status string) {
r.code, r.status = code, status
}
func (r *Response) SetBody(bytes []byte) {
r.response.SetBody(bytes)
}

View File

@@ -1,14 +0,0 @@
package http_context
//type IStatus interface {
// SetStatus(statusCode int)
// GetStatus() int
//}
//
//func (ctx *Context) SetStatus(statusCode int) {
// ctx.context.SetStatusCode(statusCode)
//}
//
//func (ctx *Context) GetStatus() int {
// return ctx.context.Response.StatusCode()
//}

View File

@@ -42,7 +42,7 @@ type Config struct {
Rules []Rule
}
//toPath 根据路由指标Location、Header、Query生成相应Checker并封装成RulePath切片返回
//toPath 根据路由指标Location、IHeader、Query生成相应Checker并封装成RulePath切片返回
func (r *Rule) toPath() ([]router.RulePath, error) {
path := make([]router.RulePath, 0, len(r.Header)+len(r.Query)+1)

View File

@@ -4,8 +4,6 @@ import (
"time"
http_service "github.com/eolinker/eosc/http-service"
http_context "github.com/eolinker/goku/node/http-context"
)
//CheckSkill 检查目标技能是否符合
@@ -15,10 +13,10 @@ func CheckSkill(skill string) bool {
//IService github.com/eolinker/goku/service.service.IService
type IService interface {
Handle(ctx *http_context.Context, router IRouterEndpoint) error
Handle(ctx http_service.IHttpContext) error
}
//IRouterEndpoint 实现了返回路由规则信息方法的接口如返回location、Host、Header、Query
//IRouterEndpoint 实现了返回路由规则信息方法的接口如返回location、Host、IHeader、Query
type IRouterEndpoint interface {
Location() (http_service.Checker, bool)
Header(name string) (http_service.Checker, bool)