mirror of
https://github.com/eolinker/apinto
synced 2025-10-05 08:47:04 +08:00
context修改
This commit is contained in:
@@ -428,11 +428,11 @@ func TestCreateChecker(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
checker, err := http_service.Parse(tt.args.pattern)
|
checker, err := http_service.Parse(tt.args.pattern)
|
||||||
if (err != nil) != tt.wantErr {
|
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
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(checker, tt.want) {
|
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
|
//验证check
|
||||||
if checker != nil {
|
if checker != nil {
|
||||||
|
@@ -52,10 +52,10 @@ func createTestContext() {
|
|||||||
|
|
||||||
// http-service
|
// http-service
|
||||||
//request1, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
//request1, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
||||||
//request1.Header.SetDriver("Authorization-Type", "ak/sk")
|
//request1.IHeader.SetDriver("Authorization-Type", "ak/sk")
|
||||||
//request1.Header.SetDriver("Content-Type", "application/json")
|
//request1.IHeader.SetDriver("Content-Type", "application/json")
|
||||||
//request1.Header.SetDriver("x-gateway-date", "20200605T104456Z")
|
//request1.IHeader.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", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
|
||||||
//Context1 := http_context.NewContext(request1, &writer{})
|
//Context1 := http_context.NewContext(request1, &writer{})
|
||||||
|
|
||||||
// fast http-service
|
// fast http-service
|
||||||
@@ -80,10 +80,10 @@ func createTestContext() {
|
|||||||
|
|
||||||
// http-service
|
// http-service
|
||||||
//request2, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
//request2, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
||||||
//request2.Header.SetDriver("Authorization-Type", "ak/sk")
|
//request2.IHeader.SetDriver("Authorization-Type", "ak/sk")
|
||||||
//request2.Header.SetDriver("Content-Type", "application/json")
|
//request2.IHeader.SetDriver("Content-Type", "application/json")
|
||||||
//request2.Header.SetDriver("x-gateway-date", "20200605T104456Z")
|
//request2.IHeader.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", "HMAC-SHA256 Access=4c897cfdfca60a59983adc2627942e7e, SignedHeaders=content-type;host;x-gateway-date, Signature=bb18110ddf327a9c1222a551527896d59cb854ca9084078cfa3a6eb23de3ddb8")
|
||||||
//Context2 := http_context.NewContext(request2, &writer{})
|
//Context2 := http_context.NewContext(request2, &writer{})
|
||||||
|
|
||||||
// https
|
// https
|
||||||
@@ -106,10 +106,10 @@ func createTestContext() {
|
|||||||
//传输了不存在的ak
|
//传输了不存在的ak
|
||||||
// http-service
|
// http-service
|
||||||
//request3, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
//request3, _ := http-service.NewRequest("GET", "http://www.demo.com/demo/login?parm1=value1&parm2=", &body{})
|
||||||
//request3.Header.SetDriver("Authorization-Type", "ak/sk")
|
//request3.IHeader.SetDriver("Authorization-Type", "ak/sk")
|
||||||
//request3.Header.SetDriver("Content-Type", "application/json")
|
//request3.IHeader.SetDriver("Content-Type", "application/json")
|
||||||
//request3.Header.SetDriver("x-gateway-date", "20200605T104456Z")
|
//request3.IHeader.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", "HMAC-SHA256 Access=dsaasdasda, SignedHeaders=content-type;host;x-gateway-date, Signature=0c3d2598d931f36ca7d261d52dcd29f09d6573671bd593b7cbc55f73eb942758")
|
||||||
//Context3 := http_context.NewContext(request3, &writer{})
|
//Context3 := http_context.NewContext(request3, &writer{})
|
||||||
//testContexts = append(testContexts, Context3)
|
//testContexts = append(testContexts, Context3)
|
||||||
|
|
||||||
|
@@ -81,7 +81,7 @@ func (a *apikey) getAuthValue(ctx http_service.IHttpContext) (string, error) {
|
|||||||
// 判断鉴权值是否在query
|
// 判断鉴权值是否在query
|
||||||
if authorization := ctx.Request().URL().Query().Get("Apikey"); authorization != "" {
|
if authorization := ctx.Request().URL().Query().Get("Apikey"); authorization != "" {
|
||||||
if a.hideCredential {
|
if a.hideCredential {
|
||||||
ctx.Proxy().Querys().Del("Apikey")
|
ctx.Proxy().Queries().Del("Apikey")
|
||||||
}
|
}
|
||||||
return authorization, nil
|
return authorization, nil
|
||||||
}
|
}
|
||||||
|
@@ -231,7 +231,7 @@ func TestFormAuthorization(t *testing.T) {
|
|||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
// http-service
|
// http-service
|
||||||
//req, err := buildRequest(headers, nil, formBody.Encode())
|
//req, err := buildRequest(headers, nil, formBody.encode())
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
// t.Error(err)
|
// t.Error(err)
|
||||||
// return
|
// return
|
||||||
|
@@ -293,22 +293,22 @@ func decodeSegment(seg string) ([]byte, error) {
|
|||||||
return base64.URLEncoding.DecodeString(seg)
|
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 {
|
func encodeSegment(seg []byte) string {
|
||||||
return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
|
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) {
|
func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Parse PEM block
|
// parse PEM block
|
||||||
var block *pem.Block
|
var block *pem.Block
|
||||||
if block, _ = pem.Decode(key); block == nil {
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
return nil, errKeyMustBePEMEncoded
|
return nil, errKeyMustBePEMEncoded
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the key
|
// parse the key
|
||||||
var parsedKey interface{}
|
var parsedKey interface{}
|
||||||
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||||
if cert, err := x509.ParseCertificate(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
|
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) {
|
func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Parse PEM block
|
// parse PEM block
|
||||||
var block *pem.Block
|
var block *pem.Block
|
||||||
if block, _ = pem.Decode(key); block == nil {
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
return nil, errKeyMustBePEMEncoded
|
return nil, errKeyMustBePEMEncoded
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the key
|
// parse the key
|
||||||
var parsedKey interface{}
|
var parsedKey interface{}
|
||||||
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||||
if cert, err := x509.ParseCertificate(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 value := context.Request().URL().Query().Get(tokenName); value != "" {
|
||||||
if j.hideCredentials {
|
if j.hideCredentials {
|
||||||
context.Proxy().Querys().Del(tokenName)
|
context.Proxy().Queries().Del(tokenName)
|
||||||
}
|
}
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
@@ -120,7 +120,7 @@ func (s *serviceWorker) ProxyAddr() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Handle 将服务发送到负载
|
//Handle 将服务发送到负载
|
||||||
func (s *serviceWorker) Handle(ctx *http_context.Context, router service.IRouterEndpoint) error {
|
func (s *serviceWorker) Handle(ctx http_service.IHttpContext) error {
|
||||||
// 构造context
|
// 构造context
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
|
@@ -117,11 +117,11 @@ func (t *TestContext) DelHeader(key string) {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestContext) Set() http_service.Header {
|
func (t *TestContext) Set() http_service.IHeader {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestContext) Append() http_service.Header {
|
func (t *TestContext) Append() http_service.IHeader {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,11 +161,11 @@ func (t *TestContext) RequestId() string {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestContext) Request() http_service.RequestReader {
|
func (t *TestContext) Request() http_service.IRequestReader {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestContext) Proxy() http_service.Request {
|
func (t *TestContext) Proxy() http_service.IRequest {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ func (t *TestContext) Labels() map[string]string {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestContext) ProxyResponse() http_service.ResponseReader {
|
func (t *TestContext) ProxyResponse() http_service.IResponseReader {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@@ -4,7 +4,6 @@ go 1.15
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/eolinker/eosc v0.2.3
|
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/ghodss/yaml v1.0.0
|
||||||
github.com/go-basic/uuid v1.0.0
|
github.com/go-basic/uuid v1.0.0
|
||||||
github.com/hashicorp/consul/api v1.9.1
|
github.com/hashicorp/consul/api v1.9.1
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
goku_plugin "github.com/eolinker/goku-standard-plugin"
|
http_service "github.com/eolinker/eosc/http-service"
|
||||||
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -23,13 +23,24 @@ var (
|
|||||||
errorNotAllowRaw = errors.New("contentType is not allow Raw")
|
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请求处理器
|
//BodyRequestHandler body请求处理器
|
||||||
type BodyRequestHandler struct {
|
type BodyRequestHandler struct {
|
||||||
form url.Values
|
form url.Values
|
||||||
rawBody []byte
|
rawBody []byte
|
||||||
orgContentParam map[string]string
|
orgContentParam map[string]string
|
||||||
contentType string
|
contentType string
|
||||||
files map[string]*goku_plugin.FileHeader
|
files map[string]*http_service.FileHeader
|
||||||
|
|
||||||
isInit bool
|
isInit bool
|
||||||
isWriteRaw bool
|
isWriteRaw bool
|
||||||
@@ -37,33 +48,83 @@ type BodyRequestHandler struct {
|
|||||||
object interface{}
|
object interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Files 获取文件参数
|
//GetForm 获取表单参数
|
||||||
func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b.files, nil
|
return b.files, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse 解析
|
func (b *BodyRequestHandler) GetFile(key string) (file *http_service.FileHeader, has bool) {
|
||||||
func (b *BodyRequestHandler) Parse() error {
|
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 {
|
if b.isInit {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
switch contentType {
|
switch contentType {
|
||||||
case goku_plugin.JSON:
|
case JSON:
|
||||||
{
|
{
|
||||||
e := json.Unmarshal(b.rawBody, &b.object)
|
e := json.Unmarshal(b.rawBody, &b.object)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case goku_plugin.AppLicationXML, goku_plugin.TextXML:
|
case AppLicationXML, TextXML:
|
||||||
{
|
{
|
||||||
e := xml.Unmarshal(b.rawBody, &b.object)
|
e := xml.Unmarshal(b.rawBody, &b.object)
|
||||||
if e != nil {
|
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)
|
r, err := multipartReader(b.contentType, false, b.rawBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,7 +151,7 @@ func (b *BodyRequestHandler) Parse() error {
|
|||||||
b.form[k] = append(b.form[k], v...)
|
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 {
|
for k, fs := range form.File {
|
||||||
|
|
||||||
if len(fs) > 0 {
|
if len(fs) > 0 {
|
||||||
@@ -103,7 +164,7 @@ func (b *BodyRequestHandler) Parse() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.files[k] = &goku_plugin.FileHeader{
|
b.files[k] = &http_service.FileHeader{
|
||||||
FileName: fs[0].Filename,
|
FileName: fs[0].Filename,
|
||||||
Data: fileData,
|
Data: fileData,
|
||||||
Header: fs[0].Header,
|
Header: fs[0].Header,
|
||||||
@@ -113,7 +174,7 @@ func (b *BodyRequestHandler) Parse() error {
|
|||||||
|
|
||||||
b.object = b.form
|
b.object = b.form
|
||||||
}
|
}
|
||||||
case goku_plugin.FormData:
|
case FormData:
|
||||||
{
|
{
|
||||||
form, err := url.ParseQuery(string(b.rawBody))
|
form, err := url.ParseQuery(string(b.rawBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -135,50 +196,15 @@ func (b *BodyRequestHandler) Parse() error {
|
|||||||
return nil
|
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 设置表单参数
|
//SetToForm 设置表单参数
|
||||||
func (b *BodyRequestHandler) SetToForm(key, value string) error {
|
func (b *BodyRequestHandler) SetToForm(key, value string) error {
|
||||||
|
|
||||||
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
return errorNotForm
|
return errorNotForm
|
||||||
}
|
}
|
||||||
|
|
||||||
err := b.Parse()
|
err := b.parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -196,10 +222,10 @@ func (b *BodyRequestHandler) SetToForm(key, value string) error {
|
|||||||
//AddForm 新增表单参数
|
//AddForm 新增表单参数
|
||||||
func (b *BodyRequestHandler) AddForm(key, value string) error {
|
func (b *BodyRequestHandler) AddForm(key, value string) error {
|
||||||
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
return errorNotForm
|
return errorNotForm
|
||||||
}
|
}
|
||||||
err := b.Parse()
|
err := b.parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -213,13 +239,13 @@ func (b *BodyRequestHandler) AddForm(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//AddFile 新增文件参数
|
//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)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
return errorNotMultipart
|
return errorNotMultipart
|
||||||
}
|
}
|
||||||
err := b.Parse()
|
err := b.parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -229,7 +255,7 @@ func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if b.files == 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
|
b.files[key] = file
|
||||||
|
|
||||||
@@ -238,29 +264,14 @@ func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) e
|
|||||||
|
|
||||||
//Clone 克隆body
|
//Clone 克隆body
|
||||||
func (b *BodyRequestHandler) Clone() *BodyRequestHandler {
|
func (b *BodyRequestHandler) Clone() *BodyRequestHandler {
|
||||||
rawbody, _ := b.RawBody()
|
rawBody, _ := b.RawBody()
|
||||||
return newBodyRequestHandler(b.contentType, 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 获取请求体对象
|
//BodyInterface 获取请求体对象
|
||||||
func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
|
func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
|
||||||
err := b.Parse()
|
err := b.parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -268,25 +279,14 @@ func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
|
|||||||
return b.object, nil
|
return b.object, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//RawBody 获取raw数据
|
//encode encode
|
||||||
func (b *BodyRequestHandler) RawBody() ([]byte, error) {
|
func (b *BodyRequestHandler) encode() error {
|
||||||
|
|
||||||
err := b.Encode()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return b.rawBody, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Encode encode
|
|
||||||
func (b *BodyRequestHandler) Encode() error {
|
|
||||||
if b.isWriteRaw {
|
if b.isWriteRaw {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
b.isWriteRaw = true
|
b.isWriteRaw = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -336,10 +336,10 @@ func (b *BodyRequestHandler) Encode() error {
|
|||||||
func (b *BodyRequestHandler) SetForm(values url.Values) error {
|
func (b *BodyRequestHandler) SetForm(values url.Values) error {
|
||||||
|
|
||||||
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
return errorNotForm
|
return errorNotForm
|
||||||
}
|
}
|
||||||
b.Parse()
|
b.parse()
|
||||||
b.form = values
|
b.form = values
|
||||||
b.isWriteRaw = false
|
b.isWriteRaw = false
|
||||||
|
|
||||||
@@ -347,13 +347,13 @@ func (b *BodyRequestHandler) SetForm(values url.Values) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//SetFile 设置文件参数
|
//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)
|
contentType, _, _ := mime.ParseMediaType(b.contentType)
|
||||||
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
|
if contentType != FormData && contentType != MultipartForm {
|
||||||
return errorNotForm
|
return errorNotForm
|
||||||
}
|
}
|
||||||
b.Parse()
|
b.parse()
|
||||||
b.files = files
|
b.files = files
|
||||||
// b.form = values
|
// b.form = values
|
||||||
b.isWriteRaw = false
|
b.isWriteRaw = false
|
||||||
|
@@ -3,206 +3,105 @@ package http_context
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
http_service "github.com/eolinker/eosc/http-service"
|
http_service "github.com/eolinker/eosc/http-service"
|
||||||
access_field "github.com/eolinker/goku/node/common/access-field"
|
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Context context
|
var _ http_service.IHttpContext = (*Context)(nil)
|
||||||
|
|
||||||
|
//Context requestCtx
|
||||||
type Context struct {
|
type Context struct {
|
||||||
context *fasthttp.RequestCtx
|
requestCtx *fasthttp.RequestCtx
|
||||||
requestOrg *fasthttp.Request
|
requestOrg *fasthttp.Request
|
||||||
proxyRequest *fasthttp.Request
|
|
||||||
|
proxyRequest *ProxyRequest
|
||||||
|
|
||||||
proxyResponse *fasthttp.Response
|
proxyResponse *fasthttp.Response
|
||||||
Body []byte
|
body []byte
|
||||||
requestID string
|
requestID string
|
||||||
RestfulParam map[string]string
|
RestfulParam map[string]string
|
||||||
LogFields *access_field.Fields
|
code int
|
||||||
request IRequest
|
status string
|
||||||
labels map[string]string
|
response *Response
|
||||||
bodyHandler *BodyRequestHandler
|
requestReader *RequestReader
|
||||||
}
|
ctx context.Context
|
||||||
|
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) Context() 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{} {
|
func (ctx *Context) Value(key interface{}) interface{} {
|
||||||
panic("implement me")
|
return ctx.Context().Value(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) WithValue(key, val interface{}) {
|
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 {
|
func (ctx *Context) Response() http_service.IResponse {
|
||||||
panic("implement me")
|
if ctx.response == nil {
|
||||||
|
ctx.response = NewResponse(ctx.proxyResponse)
|
||||||
|
}
|
||||||
|
return ctx.response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) Headers() http.Header {
|
func (ctx *Context) Proxy() http_service.IRequest {
|
||||||
panic("implement me")
|
return ctx.proxyRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) SetHeader(key, value string) {
|
func (ctx *Context) SetStatus(code int, status string) {
|
||||||
panic("implement me")
|
ctx.code, ctx.status = code, status
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) AddHeader(key, value string) {
|
func (ctx *Context) Request() http_service.IRequestReader {
|
||||||
panic("implement me")
|
if ctx.requestReader == nil {
|
||||||
}
|
ctx.requestReader = NewRequestReader(ctx.requestOrg, ctx.requestCtx.RemoteAddr().String())
|
||||||
|
}
|
||||||
func (ctx *Context) DelHeader(key string) {
|
return ctx.requestReader
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewContext 创建Context
|
//NewContext 创建Context
|
||||||
func NewContext(ctx *fasthttp.RequestCtx) http_service.IHttpContext {
|
func NewContext(ctx *fasthttp.RequestCtx) *Context {
|
||||||
id := uuid.NewV4()
|
id := uuid.NewV4()
|
||||||
requestID := id.String()
|
requestID := id.String()
|
||||||
newRequest := &ctx.Request
|
newRequest := &ctx.Request
|
||||||
newCtx := &Context{
|
newCtx := &Context{
|
||||||
context: ctx,
|
requestCtx: ctx,
|
||||||
requestOrg: fasthttp.AcquireRequest(),
|
requestOrg: fasthttp.AcquireRequest(),
|
||||||
proxyRequest: fasthttp.AcquireRequest(),
|
requestID: requestID,
|
||||||
requestID: requestID,
|
|
||||||
LogFields: access_field.NewFields(),
|
|
||||||
}
|
}
|
||||||
|
proxyRequest := fasthttp.AcquireRequest()
|
||||||
newRequest.CopyTo(newCtx.requestOrg)
|
newRequest.CopyTo(newCtx.requestOrg)
|
||||||
newRequest.CopyTo(newCtx.proxyRequest)
|
newRequest.CopyTo(proxyRequest)
|
||||||
|
|
||||||
newCtx.LogFields.RequestHeader = newCtx.requestOrg.Header.String()
|
newCtx.proxyRequest = NewProxyRequest(NewRequestReader(proxyRequest, ""))
|
||||||
newCtx.LogFields.RequestMsg = string(newCtx.Body)
|
|
||||||
newCtx.LogFields.RequestMsgSize = len(newCtx.Body)
|
|
||||||
newCtx.LogFields.RequestUri = string(newCtx.requestOrg.RequestURI())
|
|
||||||
newCtx.LogFields.RequestID = requestID
|
|
||||||
return newCtx
|
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
|
//RequestId 请求ID
|
||||||
func (ctx *Context) RequestId() string {
|
func (ctx *Context) RequestId() string {
|
||||||
return ctx.requestID
|
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) {
|
func (ctx *Context) SetBody(body []byte) {
|
||||||
ctx.context.SetBody(body)
|
ctx.requestCtx.SetBody(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) SetResponse(response *fasthttp.Response) {
|
func (ctx *Context) SetResponse(response *fasthttp.Response) {
|
||||||
ctx.Body = response.Body()
|
ctx.body = response.Body()
|
||||||
ctx.proxyResponse = response
|
ctx.proxyResponse = response
|
||||||
}
|
}
|
||||||
|
|
||||||
//Finish finish
|
//Finish finish
|
||||||
func (ctx *Context) Finish() {
|
func (ctx *Context) Finish() {
|
||||||
ctx.LogFields.ResponseMsg = string(ctx.Body)
|
ctx.proxyResponse.CopyTo(&ctx.requestCtx.Response)
|
||||||
ctx.LogFields.ResponseMsgSize = len(ctx.Body)
|
|
||||||
ctx.proxyResponse.CopyTo(&ctx.context.Response)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,10 +111,10 @@ func (ctx *Context) SetError(err error) {
|
|||||||
"msg": err.Error(),
|
"msg": err.Error(),
|
||||||
}
|
}
|
||||||
errByte, _ := json.Marshal(result)
|
errByte, _ := json.Marshal(result)
|
||||||
ctx.Body = errByte
|
ctx.body = errByte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NotFound(ctx *Context) {
|
func NotFound(ctx *Context) {
|
||||||
ctx.context.SetStatusCode(404)
|
ctx.requestCtx.SetStatusCode(404)
|
||||||
ctx.context.SetBody([]byte("404 Not Found"))
|
ctx.requestCtx.SetBody([]byte("404 Not Found"))
|
||||||
}
|
}
|
||||||
|
115
node/http-context/proxy.go
Normal file
115
node/http-context/proxy.go
Normal 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
|
||||||
|
}
|
122
node/http-context/request-reader-old.go
Normal file
122
node/http-context/request-reader-old.go
Normal 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
|
||||||
|
//}
|
@@ -1,65 +1,84 @@
|
|||||||
package http_context
|
package http_context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
http_service "github.com/eolinker/eosc/http-service"
|
||||||
|
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Value map[string]string
|
var _ http_service.IRequestReader = (*RequestReader)(nil)
|
||||||
|
|
||||||
func (h Value) Get(key string) (string, bool) {
|
type RequestReader struct {
|
||||||
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 {
|
|
||||||
req *fasthttp.Request
|
req *fasthttp.Request
|
||||||
path string
|
bodyHandler *BodyRequestHandler
|
||||||
|
remoteAddr string
|
||||||
|
clientIP string
|
||||||
host string
|
host string
|
||||||
method string
|
method string
|
||||||
header Value
|
|
||||||
query Value
|
|
||||||
rawQuery string
|
|
||||||
rawBody []byte
|
rawBody []byte
|
||||||
|
headers http.Header
|
||||||
|
scheme string
|
||||||
|
uri *url.URL
|
||||||
contentType string
|
contentType string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) Host() string {
|
func NewRequestReader(req *fasthttp.Request, remoteAddr string) *RequestReader {
|
||||||
if r.host == "" {
|
return &RequestReader{req: req, remoteAddr: remoteAddr}
|
||||||
r.host = strings.Split(string(r.req.Header.Host()), ":")[0]
|
|
||||||
}
|
|
||||||
return r.host
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) Method() string {
|
func (r *RequestReader) ContentType() string {
|
||||||
if r.method == "" {
|
if r.contentType == "" {
|
||||||
r.method = string(r.req.Header.Method())
|
r.contentType = string(r.req.Header.ContentType())
|
||||||
}
|
}
|
||||||
return r.method
|
return r.contentType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) Path() string {
|
func (r *RequestReader) BodyForm() (url.Values, error) {
|
||||||
if r.path == "" {
|
if r.bodyHandler == nil {
|
||||||
r.path = string(r.req.URI().Path())
|
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
|
||||||
}
|
}
|
||||||
return r.path
|
return r.bodyHandler.BodyForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) Header() Value {
|
func (r *RequestReader) Files() (map[string]*http_service.FileHeader, error) {
|
||||||
if r.header == nil {
|
if r.bodyHandler == nil {
|
||||||
r.header = make(Value)
|
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")
|
hs := strings.Split(r.req.Header.String(), "\r\n")
|
||||||
for _, h := range hs {
|
for _, h := range hs {
|
||||||
vs := strings.Split(h, ":")
|
vs := strings.Split(h, ":")
|
||||||
@@ -67,62 +86,66 @@ func (r *Request) Header() Value {
|
|||||||
if vs[0] == "" {
|
if vs[0] == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.header[vs[0]] = ""
|
r.headers[vs[0]] = []string{""}
|
||||||
continue
|
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 {
|
func (r *RequestReader) Method() string {
|
||||||
if r.rawQuery == "" {
|
if r.method == "" {
|
||||||
r.rawQuery = string(r.req.URI().QueryString())
|
r.method = string(r.req.Header.Method())
|
||||||
}
|
}
|
||||||
if r.query == nil {
|
return r.method
|
||||||
r.query = make(Value)
|
}
|
||||||
qs := strings.Split(r.rawQuery, "&")
|
|
||||||
for _, q := range qs {
|
func (r *RequestReader) URL() url.URL {
|
||||||
vs := strings.Split(q, "=")
|
if r.uri == nil {
|
||||||
if len(vs) < 2 {
|
r.uri, _ = url.Parse(r.req.URI().String())
|
||||||
if vs[0] == "" {
|
}
|
||||||
continue
|
return *r.uri
|
||||||
}
|
}
|
||||||
r.query[vs[0]] = ""
|
|
||||||
continue
|
func (r *RequestReader) RequestURI() string {
|
||||||
}
|
return string(r.req.RequestURI())
|
||||||
r.query[vs[0]] = strings.TrimSpace(vs[1])
|
}
|
||||||
|
|
||||||
|
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 {
|
func (r *RequestReader) Scheme() string {
|
||||||
if r.rawQuery == "" {
|
if r.scheme == "" {
|
||||||
r.rawQuery = string(r.req.URI().QueryString())
|
r.scheme = string(r.req.URI().Scheme())
|
||||||
}
|
}
|
||||||
return r.rawQuery
|
return r.scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) RawBody() []byte {
|
func (r *RequestReader) Request() *fasthttp.Request {
|
||||||
if r.rawBody == nil {
|
return r.req
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
110
node/http-context/response.go
Normal file
110
node/http-context/response.go
Normal 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)
|
||||||
|
}
|
@@ -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()
|
|
||||||
//}
|
|
@@ -42,7 +42,7 @@ type Config struct {
|
|||||||
Rules []Rule
|
Rules []Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
//toPath 根据路由指标Location、Header、Query生成相应Checker并封装成RulePath切片返回
|
//toPath 根据路由指标Location、IHeader、Query生成相应Checker并封装成RulePath切片返回
|
||||||
func (r *Rule) toPath() ([]router.RulePath, error) {
|
func (r *Rule) toPath() ([]router.RulePath, error) {
|
||||||
|
|
||||||
path := make([]router.RulePath, 0, len(r.Header)+len(r.Query)+1)
|
path := make([]router.RulePath, 0, len(r.Header)+len(r.Query)+1)
|
||||||
|
@@ -4,8 +4,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
http_service "github.com/eolinker/eosc/http-service"
|
http_service "github.com/eolinker/eosc/http-service"
|
||||||
|
|
||||||
http_context "github.com/eolinker/goku/node/http-context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//CheckSkill 检查目标技能是否符合
|
//CheckSkill 检查目标技能是否符合
|
||||||
@@ -15,10 +13,10 @@ func CheckSkill(skill string) bool {
|
|||||||
|
|
||||||
//IService github.com/eolinker/goku/service.service.IService
|
//IService github.com/eolinker/goku/service.service.IService
|
||||||
type IService interface {
|
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 {
|
type IRouterEndpoint interface {
|
||||||
Location() (http_service.Checker, bool)
|
Location() (http_service.Checker, bool)
|
||||||
Header(name string) (http_service.Checker, bool)
|
Header(name string) (http_service.Checker, bool)
|
||||||
|
Reference in New Issue
Block a user