@@ -1,49 +1,31 @@
package sysservice
import (
"encoding/json"
"errors"
"fmt"
"io "
"io/ioutil"
"net/http"
"os"
"reflect"
"runtime"
"strings"
"time"
"github.com/duanhf2012/origin/sysmodule"
"github.com/duanhf2012/origin/rpc"
"github.com/duanhf2012/origin/cluster"
"github.com/duanhf2012/origin/event "
"github.com/duanhf2012/origin/network"
"github.com/duanhf2012/origin/service"
"github.com/duanhf2012/origin/util/uuid"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
var Default_ReadTimeout time . Duration = time . Second * 10
var Default_WriteTimeout time . Duration = time . Second * 10
var Default_ProcessTimeout time . Duration = time . Second * 10
var Default_HttpRouter * HttpRouter = & HttpRouter { }
//http redirect
type HttpRedirectData struct {
Url string
CookieList [ ] * http . Cookie
}
type HttpRequest struct {
URL string
Header http . Header
Body string
paramStr string //http://127.0.0.1:7001/aaa/bbb?aa=1 paramStr is:aa=1
mapParam map [ string ] string
}
type HttpRespone struct {
Respone [ ] byte
RedirectData HttpRedirectData
}
type HTTP_METHOD int
const (
@@ -52,67 +34,95 @@ const (
METHOD_POST
METHOD_INVALID
//METHOD_PUT HTTP_METHOD = 2
)
type ControllerMapsType map [ string ] reflect . Value
type RouterType int
const (
FuncCall RouterType = iota + 1
StaticResource
)
type HttpHandle func ( session * HttpSession )
type routerMatchData struct {
callpath string
matchURL string
routerType int8 //0表示函数调用 1表示静态资源
httpHandle HttpHandle
}
type serveHTTPRouterMux struct {
httpFiltrateList [ ] HttpFiltrate
allowOrigin bool
type routerServeFileData struct {
matchUrl string
localPath string
method HTTP_METHOD
}
type IHttpRouter interface {
RegRouter ( method HTTP_METHOD , url string , handle HttpHandle ) bool
Router ( session * HttpSession )
PutHttpSession ( httpSession * HttpSession )
SetServeFile ( method HTTP_METHOD , urlpath string , dirname string ) error
SetFormFileKey ( formFileKey string )
GetFormFileKey ( ) string
}
type HttpRouter struct {
pathRouter map [ HTTP_METHOD ] map [ string ] routerMatchData //url地址, 对应本service地址
serveFileData map [ string ] * routerServeFileData
eventReciver event . IEventProcessor
httpFiltrateList [ ] HttpFiltrate
formFileKey string
}
type HttpSession struct {
httpRouter IHttpRouter
r * http . Request
w http . ResponseWriter
//parse result
mapParam map [ string ] string
body [ ] byte
//processor result
statusCode int
msg [ ] byte
fileData * routerServeFileData
redirectData * HttpRedirectData
sessionDone chan * HttpSession
}
type HttpService struct {
service . Service
httpServer network . HttpServer
controllerMaps ControllerMapsType
serverHTTPMux serveHTTPRouterMux
postAliasUrl map [ HTTP_METHOD ] map [ string ] routerMatchData //url地址, 对应本service地址
staticRouterResource map [ HTTP_METHOD ] routerStaticResoutceData
httpProcessor IHttpProcessor
}
type routerStaticResoutceData struct {
localPath string
method HTTP_METHOD
httpRouter IHttpRouter
listenAddr string
allowOrigin bool
processTimeout time . Duration
}
type HttpHandle func ( request * HttpRequest , resp * HttpRespone ) error
func Analysis RouterUrl ( url string ) ( string , error ) {
//替换所有空格
url = strings . ReplaceAll ( url , " " , "" )
if len ( url ) < = 1 || url [ 0 ] != '/' {
return "" , fmt . Errorf ( "url %s format is error!" , url )
func NewHttpHttp Router( eventReciver event . IEventProcessor ) IHttpRouter {
httpRouter := & HttpRouter { }
httpRouter . eventReciver = eventReciver
httpRouter . pathRouter = map [ HTTP_METHOD ] map [ string ] routerMatchData { }
httpRouter . serveFileData = map [ string ] * routerServeFileData { }
httpRouter . formFileKey = "file"
for i := METHOD_NONE + 1 ; i < METHOD_INVALID ; i ++ {
httpRouter . pathRouter [ i ] = map [ string ] routerMatchData { }
}
//去掉尾部的/
return strings . Trim ( url , "/" ) , nil
return httpRouter
}
func ( slf * HttpRequest ) Query ( key string ) ( string , bool ) {
func ( slf * HttpSession ) Query ( key string ) ( string , bool ) {
if slf . mapParam == nil {
slf . mapParam = make ( map [ string ] string )
//分析字符串
slf . paramStr = strings . Trim ( slf . paramStr , "/" )
paramStrList := strings . Split ( slf . paramStr, "&" )
paramStr : = strings . Trim ( slf . r . URL . RawQuery , "/" )
paramStrList := strings . Split ( paramStr , "&" )
for _ , val := range paramStrList {
index := strings . Index ( val , "=" )
if index >= 0 {
@@ -125,124 +135,249 @@ func (slf *HttpRequest) Query(key string) (string, bool) {
return ret , ok
}
type HttpSession struct {
request * HttpRequest
resp * HttpRespone
func ( slf * HttpSession ) GetBody ( ) [ ] byte {
return slf . body
}
type HttpProcessor struct {
httpSessionChan chan * HttpSession
pathRouter map [ HTTP_METHOD ] map [ string ] routerMatchData //url地址, 对应本service地址
staticRouterResource map [ HTTP_METHOD ] routerStaticResoutceData
func ( slf * HttpSession ) GetMethod ( ) HTTP_METHOD {
return slf . getMethod ( slf . r . Method )
}
var Default_HttpSessionChannelNum = 100000
func ( slf * HttpSession ) GetPath ( ) string {
return strings . Trim ( slf . r . URL . Path , "/" )
}
func NewHttpProcessor ( ) * HttpProcessor {
httpProcessor := & HttpProcessor { }
httpProcessor . httpSessionChan = make ( chan * HttpSession , Default_HttpSessionChannelNum )
httpProcessor . staticRouterResource = map [ HTTP_METHOD ] routerStaticResoutceData { }
httpProcessor . pathRouter = map [ HTTP_METHOD ] map [ string ] routerMatchData { }
func ( slf * HttpSession ) SetHeader ( key , value string ) {
slf . w . Header ( ) . Set ( key , value )
}
for i := METHOD_NONE + 1 ; i < METHOD_INVALID ; i ++ {
httpProcessor . pathRouter [ i ] = map [ string ] routerMatchData { }
func ( slf * HttpSession ) AddHeader ( key , value string ) {
slf . w . Header ( ) . Add ( key , value )
}
func ( slf * HttpSession ) WriteStatusCode ( statusCode int ) {
slf . statusCode = statusCode
}
func ( slf * HttpSession ) Write ( msg [ ] byte ) {
slf . msg = msg
}
func ( slf * HttpSession ) flush ( ) {
slf . w . WriteHeader ( slf . statusCode )
if slf . msg != nil {
slf . w . Write ( slf . msg )
}
}
func ( slf * HttpSession ) done ( ) {
slf . sessionDone <- slf
}
func ( slf * HttpSession ) getMethod ( method string ) HTTP_METHOD {
switch method {
case "POST" :
return METHOD_POST
case "GET" :
return METHOD_GET
}
return httpProcessor
return METHOD_INVALID
}
var Default_HttpProcessor * HttpProcessor = NewHttpProcessor ( )
type IHttpProcessor interface {
PutHttpSession ( httpSession * HttpSession )
GetHttpSessionChannel ( ) chan * HttpSession
RegRouter ( method HTTP_METHOD , url string , handle HttpHandle )
Router ( session * HttpSession )
}
func ( slf * HttpProcesso r ) PutHttpSession ( httpSession * HttpSession ) {
slf . httpSessionChan <- httpSession
}
func ( slf * HttpRoute r ) analysisRouterUrl ( url string ) ( string , error ) {
func ( slf * HttpProcessor ) GetHttpSessionChannel ( ) chan * HttpSession {
return slf . httpSessionChan
}
func ( slf * HttpProcessor ) RegRouter ( method HTTP_METHOD , url string , handle HttpHandle ) {
pathRouter
}
func ( slf * HttpProcessor ) Router ( session * HttpSession ) {
}
func ( slf * HttpService ) SetHttpProcessor ( httpProcessor IHttpProcessor ) {
slf . httpProcessor = httpProcessor
}
func ( slf * HttpService ) Request ( method HTTP_METHOD , url string , handle HttpHandle ) error {
fnpath := runtime . FuncForPC ( reflect . ValueOf ( handle ) . Pointer ( ) ) . Name ( )
sidx := strings . LastIndex ( fnpath , "*" )
if sidx == - 1 {
return errors . New ( fmt . Sprintf ( "http post func path is error, %s\n" , fnpath ) )
//替换所有空格
url = strings . ReplaceAll ( url , " " , "" )
if len ( url ) <= 1 || url [ 0 ] != '/' {
return "" , fmt . Errorf ( "url %s format is error!" , url )
}
eidx := strings . LastIndex ( fnpath , "-fm" )
if sidx == - 1 {
return errors . New ( fmt . Sprintf ( "http post func path is error, %s\n" , fnpath ) )
}
callpath := fnpath [ sidx + 1 : eidx ]
ridx := strings . LastIndex ( callpath , ")" )
if ridx == - 1 {
return errors . New ( fmt . Sprintf ( "http post func path is error, %s\n" , fnpath ) )
//去掉尾部的/
return strings . Trim ( url , "/" ) , nil
}
func ( slf * HttpSession ) Handle ( ) {
slf . httpRouter . Router ( slf )
}
func ( slf * HttpRouter ) SetFormFileKey ( formFileKey string ) {
slf . formFileKey = formFileKey
}
func ( slf * HttpRouter ) GetFormFileKey ( ) string {
return slf . formFileKey
}
func ( slf * HttpRouter ) PutHttpSession ( httpSession * HttpSession ) {
slf . eventReciver . NotifyEvent ( & event . Event { Type : event . Sys_Event_Http_Event , Data : httpSession } )
}
func ( slf * HttpRouter ) RegRouter ( method HTTP_METHOD , url string , handle HttpHandle ) bool {
mapRouter , ok := slf . pathRouter [ method ]
if ok == false {
return false
}
hidx := strings . LastIndex ( callpath , "HTTP_" )
if hidx == - 1 {
return errors . New ( fmt . Sprintf ( "http post func not contain HTTP_, %s\n" , fnpath ) )
mapRouter [ strings . Trim ( url , "/" ) ] = routerMatchData { httpHandle : handle }
return true
}
func ( slf * HttpRouter ) Router ( session * HttpSession ) {
if slf . httpFiltrateList != nil {
for _ , fun := range slf . httpFiltrateList {
if fun ( session ) == false {
session . done ( )
return
}
}
}
callp ath = strings . ReplaceAll ( callpath , ")" , "" )
urlP ath : = session . GetPath ( )
for {
mapRouter , ok := slf . pathRouter [ session . GetMethod ( ) ]
if ok == false {
break
}
var r RouterMatchData
var matchURL string
var err error
r . routerType = 0
r . callpath = "_" + callpath
matchURL , err = AnalysisRouterUrl ( url )
v , ok := map Router[ urlPath ]
if ok == false {
break
}
v . httpHandle ( session )
session . done ( )
return
}
for k , v := range slf . serveFileData {
idx := strings . Index ( urlPath , k )
if idx != - 1 {
session . fileData = v
session . done ( )
return
}
}
session . WriteStatusCode ( http . StatusNotFound )
session . done ( )
}
func ( slf * HttpService ) SetHttpRouter ( httpRouter IHttpRouter ) {
slf . httpRouter = httpRouter
}
func ( slf * HttpRouter ) SetServeFile ( method HTTP_METHOD , urlpath string , dirname string ) error {
_ , err := os . Stat ( dirname )
if err != nil {
return err
}
var strMethod string
if method == METHOD_GET {
strMethod = "GET"
} else if method == METHOD_POST {
strMethod = "POST"
} else {
return nil
matchURL , aErr := slf . analysisRouterUrl ( urlpath )
if aErr != nil {
return aErr
}
postAliasUrl [ strMethod ] [ matchURL ] = r
var routerData routerServeFileData
routerData . method = method
routerData . localPath = dirname
routerData . matchUrl = matchURL
slf . serveFileData [ matchURL ] = & routerData
return nil
}
func Post ( url string , handle HttpHandle ) error {
return Request ( METHOD_POST , url , handle )
type HttpFiltrate func ( session * HttpSession ) bool //true is pass
func ( slf * HttpRouter ) AddHttpFiltrate ( FiltrateFun HttpFiltrate ) bool {
slf . httpFiltrateList = append ( slf . httpFiltrateList , FiltrateFun )
return false
}
func Get ( url string , handle HttpHandle ) error {
return Request ( METHOD_GET , url , handle )
func ( slf * HttpSession ) Redirect ( url string , cookieList [ ] * http . Cookie ) {
redirectData := & HttpRedirectData { }
redirectData . Url = url
redirectData . CookieList = cookieList
slf . redirectData = redirectData
}
func ( slf * HttpSession ) redirects ( ) {
if slf . redirectData == nil {
return
}
if slf . redirectData . CookieList != nil {
for _ , v := range slf . redirectData . CookieList {
http . SetCookie ( slf . w , v )
}
}
http . Redirect ( slf . w , slf . r , slf . redirectData . Url ,
http . StatusTemporaryRedirect )
}
func ( slf * HttpService ) OnInit ( ) error {
slf . serverHTTPMux = ServeHTTPRouterMux { }
slf . httpserver . Init ( slf . port , & slf . serverHTTPMux , 10 * time . Second , 10 * time . Second )
if slf . ishttps == true {
slf . httpserver . SetHttps ( slf . certfile , slf . keyfile )
iConfig : = slf . GetServiceCfg ( )
if iConfig == nil {
return fmt . Errorf ( "%s service config is error!" , slf . GetName ( ) )
}
tcpCfg := iConfig . ( map [ string ] interface { } )
addr , ok := tcpCfg [ "ListenAddr" ]
if ok == false {
return fmt . Errorf ( "%s service config is error!" , slf . GetName ( ) )
}
var readTimeout time . Duration = Default_ReadTimeout
var writeTimeout time . Duration = Default_WriteTimeout
if cfgRead , ok := tcpCfg [ "ReadTimeout" ] ; ok == true {
readTimeout = time . Duration ( cfgRead . ( float64 ) ) * time . Millisecond
}
if cfgWrite , ok := tcpCfg [ "WriteTimeout" ] ; ok == true {
writeTimeout = time . Duration ( cfgWrite . ( float64 ) ) * time . Millisecond
}
slf . processTimeout = Default_ProcessTimeout
if cfgProcessTimeout , ok := tcpCfg [ "ProcessTimeout" ] ; ok == true {
slf . processTimeout = time . Duration ( cfgProcessTimeout . ( float64 ) ) * time . Millisecond
}
slf . httpServer . Init ( addr . ( string ) , slf , readTimeout , writeTimeout )
//Set CAFile
caFileList , ok := tcpCfg [ "CAFile" ]
if ok == false {
return nil
}
iCaList := caFileList . ( [ ] interface { } )
var caFile [ ] network . CAFile
for _ , i := range iCaList {
mapCAFile := i . ( map [ string ] interface { } )
c , ok := mapCAFile [ "Certfile" ]
if ok == false {
continue
}
k , ok := mapCAFile [ "Certfile" ]
if ok == false {
continue
}
if c . ( string ) != "" && k . ( string ) != "" {
caFile = append ( caFile , network . CAFile {
Certfile : c . ( string ) ,
Keyfile : k . ( string ) ,
} )
}
}
slf . httpServer . SetCAFile ( caFile )
slf . httpServer . Start ( )
return nil
}
@@ -250,6 +385,60 @@ func (slf *HttpService) SetAlowOrigin(allowOrigin bool) {
slf . allowOrigin = allowOrigin
}
func ( slf * HttpService ) ProcessFile ( session * HttpSession ) {
upath := session . r . URL . Path
idx := strings . Index ( upath , session . fileData . matchUrl )
subPath := strings . Trim ( upath [ idx + len ( session . fileData . matchUrl ) : ] , "/" )
destLocalPath := session . fileData . localPath + "/" + subPath
switch session . GetMethod ( ) {
case METHOD_GET :
//判断文件夹是否存在
_ , err := os . Stat ( destLocalPath )
if err == nil {
http . ServeFile ( session . w , session . r , destLocalPath )
} else {
session . WriteStatusCode ( http . StatusNotFound )
session . flush ( )
return
}
//上传资源
case METHOD_POST :
// 在这儿处理例外路由接口
session . r . ParseMultipartForm ( 32 << 20 ) // max memory is set to 32MB
resourceFile , resourceFileHeader , err := session . r . FormFile ( session . httpRouter . GetFormFileKey ( ) )
if err != nil {
session . WriteStatusCode ( http . StatusNotFound )
session . flush ( )
return
}
defer resourceFile . Close ( )
//重新拼接文件名
imgFormat := strings . Split ( resourceFileHeader . Filename , "." )
if len ( imgFormat ) < 2 {
session . WriteStatusCode ( http . StatusNotFound )
session . flush ( )
return
}
filePrefixName := uuid . Rand ( ) . HexEx ( )
fileName := filePrefixName + "." + imgFormat [ len ( imgFormat ) - 1 ]
//创建文件
localpath := fmt . Sprintf ( "%s%s" , destLocalPath , fileName )
localfd , err := os . OpenFile ( localpath , os . O_WRONLY | os . O_CREATE , 0666 )
if err != nil {
session . WriteStatusCode ( http . StatusNotFound )
session . flush ( )
return
}
defer localfd . Close ( )
io . Copy ( localfd , resourceFile )
session . WriteStatusCode ( http . StatusOK )
session . Write ( [ ] byte ( upath + "/" + fileName ) )
session . flush ( )
}
}
func ( slf * HttpService ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) {
if slf . allowOrigin == true {
if origin := r . Header . Get ( "Origin" ) ; origin != "" {
@@ -259,304 +448,37 @@ func (slf *HttpService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
"Action, Module" ) //有使用自定义头 需要这个,Action, Module是例子
}
}
if r . Method == "OPTIONS" {
return
}
methodRouter , bok := postAliasUrl [ r . Meth od]
if bok = = false {
writeResp one ( w , http . StatusNotFound , fmt . Sprint ( "Can not support method." ) )
return
}
//权限验证
var errRet error
for _ , filter := range slf . httpfiltrateList {
ret := filter ( r . URL . Path , w , r )
if ret == nil {
errRet = nil
break
} else {
errRet = ret
}
}
if errRet != nil {
writeRespone ( w , http . StatusOK , errRet . Error ( ) )
return
}
url := strings . Trim ( r . URL . Path , "/" )
var strCallPath string
matchData , ok := methodRouter [ url ]
if ok == true {
strCallPath = matchData . callpath
} else {
//如果是资源处理
for k , v := range staticRouterResource {
idx := strings . Index ( url , k )
if idx != - 1 {
staticServer ( k , v , w , r )
return
}
}
// 拼接得到rpc服务的名称
vstr := strings . Split ( url , "/" )
if len ( vstr ) < 2 {
writeRespone ( w , http . StatusNotFound , "Cannot find path." )
return
}
strCallPath = "_" + vstr [ 0 ] + ".HTTP_" + vstr [ 1 ]
}
session := & HttpSession { sessionDone : make ( chan * HttpSession , 1 ) , httpRouter : slf . httpRoute r, statusC ode : http . StatusOK }
session . r = r
sessi on . w = w
defer r . Body . Close ( )
msg , err := ioutil . ReadAll ( r . Body )
body , err := ioutil . ReadAll ( r . Body )
if err != nil {
writeRespone ( w , http . StatusBadRequest , "" )
session . WriteStatusCode ( http . StatusGatewayTimeout )
session . flush ( )
return
}
session . body = body
request := H ttpRequest { r . Header , string ( msg ) , r . URL . RawQuery , nil , r . URL . Path }
var resp HttpRespone
//resp.Resp = w
timeFuncStart := time . Now ( )
err = cluster . InstanceClusterMgr ( ) . Call ( strCallPath , & request , & resp )
timeFuncPass := time . Since ( timeFuncStart )
if bPrintRequestTime {
service . GetLogger ( ) . Printf ( service . LEVER_INFO , "HttpServer Time : %s url : %s\n" , timeFuncPass , strCallPath )
}
if err != nil {
writeRespone ( w , http . StatusBadRequest , fmt . Sprint ( err ) )
} else {
if r esp . RedirectData . Url != "" {
resp . redirects ( & w , r )
} else {
writeRespone ( w , http . StatusOK , string ( resp . Respone ) )
}
}
}
// CkResourceDir 检查静态资源文件夹路径
func SetStaticResource ( method HTTP_METHOD , urlpath string , dirname string ) error {
_ , err := os . Stat ( dirname )
if err != nil {
return err
}
matchURL , berr := AnalysisRouterUrl ( urlpath )
if berr != nil {
return berr
}
var routerData RouterStaticResoutceData
if method == METHOD_GET {
routerData . method = "GET"
} else if method == METHOD_POST {
routerData . method = "POST"
} else {
return nil
}
routerData . localpath = dirname
staticRouterResource [ matchURL ] = routerData
return nil
}
func writeRespone ( w http . ResponseWriter , status int , msg string ) {
w . Header ( ) . Set ( "Content-Type" , "text/plain; charset=utf-8" )
w . WriteHeader ( status )
w . Write ( [ ] byte ( msg ) )
}
type HttpFiltrate func ( path string , w http . ResponseWriter , r * http . Request ) error
func ( slf * HttpService ) AppendHttpFiltrate ( fun HttpFiltrate ) bool {
slf . serverHTTPMux . httpfiltrateList = append ( slf . serverHTTPMux . httpfiltrateList , fun )
return false
}
func ( slf * HttpService ) OnRun ( ) bool {
slf . httpserver . Start ( )
return false
}
func NewHttpServerService ( port uint16 ) * HttpServerService {
http := new ( HttpServerService )
http . port = port
return http
}
func ( slf * HttpService ) OnDestory ( ) error {
return nil
}
func ( slf * HttpService ) OnSetupService ( iservice service . IService ) {
rpc . RegisterName ( iservice . GetServiceName ( ) , "HTTP_" , iservice )
}
func ( slf * HttpServerService ) OnRemoveService ( iservice service . IService ) {
return
}
func ( slf * HttpService ) SetPrintRequestTime ( isPrint bool ) {
bPrintRequestTime = isPrint
}
func staticServer ( routerUrl string , routerData RouterStaticResoutceData , w http . ResponseWriter , r * http . Request ) {
upath := r . URL . Path
idx := strings . Index ( upath , routerUrl )
subPath := strings . Trim ( upath [ idx + len ( routerUrl ) : ] , "/" )
destLocalPath := routerData . localpath + subPath
writeResp := func ( status int , msg string ) {
w . Header ( ) . Set ( "Content-Type" , "text/plain; charset=utf-8" )
w . WriteHeader ( status )
w . Write ( [ ] byte ( msg ) )
}
switch r . Method {
//获取资源
case "GET" :
//判断文件夹是否存在
_ , err := os . Stat ( destLocalPath )
if err == nil {
http . ServeFile ( w , r , destLocalPath )
} else {
writeResp ( http . StatusNotFound , "" )
return
}
//上传资源
case "POST" :
// 在这儿处理例外路由接口
/*
var errRet error
for _, filter := range slf.httpfiltrateList {
ret := filter(r.URL.Path, w, r)
if ret == nil {
errRet = nil
break
} else {
errRet = ret
}
}
if errRet != nil {
w.Write([]byte(errRet.Error()))
return
}*/
r . ParseMultipartForm ( 32 << 20 ) // max memory is set to 32MB
resourceFile , resourceFileHeader , err := r . FormFile ( "file" )
if err != nil {
fmt . Println ( err )
writeResp ( http . StatusNotFound , err . Error ( ) )
return
}
defer resourceFile . Close ( )
//重新拼接文件名
imgFormat := strings . Split ( resourceFileHeader . Filename , "." )
if len ( imgFormat ) < 2 {
writeResp ( http . StatusNotFound , "not a file" )
return
}
filePrefixName := uuid . Rand ( ) . HexEx ( )
fileName := filePrefixName + "." + imgFormat [ len ( imgFormat ) - 1 ]
//创建文件
localpath := fmt . Sprintf ( "%s%s" , destLocalPath , fileName )
localfd , err := os . OpenFile ( localpath , os . O_WRONLY | os . O_CREATE , 0666 )
if err != nil {
fmt . Println ( err )
writeResp ( http . StatusNotFound , "upload fail" )
return
}
defer localfd . Close ( )
io . Copy ( localfd , resourceFile )
writeResp ( http . StatusOK , upath + "/" + fileName )
}
}
func ( slf * HttpService ) GetMethod ( strCallPath string ) ( * reflect . Value , error ) {
value , ok := slf . controllerMaps [ strCallPath ]
if ok == false {
err := fmt . Errorf ( "not find api" )
return nil , err
}
return & value , nil
}
func ( slf * HttpService ) SetHttps ( certfile string , keyfile string ) bool {
if certfile == "" || keyfile == "" {
return false
}
slf . ishttps = true
slf . certfile = certfile
slf . keyfile = keyfile
return true
}
//序列化后写入Respone
func ( slf * HttpRespone ) WriteRespne ( v interface { } ) error {
StrRet , retErr := json . Marshal ( v )
if retErr != nil {
slf . Respone = [ ] byte ( ` { "Code": 2,"Message":"service error"} ` )
service . GetLogger ( ) . Printf ( sysmodule . LEVER_ERROR , "Json Marshal Error:%v\n" , retErr )
} else {
slf . Respone = StrRet
}
return retErr
}
func ( slf * HttpRespone ) WriteRespones ( Code int32 , Msg string , Data interface { } ) {
var StrRet string
//判断是否有错误码
if Code > 0 {
StrRet = fmt . Sprintf ( ` { "RCode": %d,"RMsg":"%s"} ` , Code , Msg )
} else {
if Data == nil {
if Msg != "" {
StrRet = fmt . Sprintf ( ` { "RCode": 0,"RMsg":"%s"} ` , Msg )
} else {
StrRet = ` { "RCode": 0} `
}
} else {
if reflect . TypeOf ( Data ) . Kind ( ) == reflect . String {
StrRet = fmt . Sprintf ( ` { "RCode": %d , "Data": "%s"} ` , Code , Data )
} else {
JsonRet , Err := json . Marshal ( Data )
if Err != nil {
service . GetLogger ( ) . Printf ( sysmodule . LEVER_ERROR , "common WriteRespone Json Marshal Err %+v" , Data )
} else {
StrRet = fmt . Sprintf ( ` { "RCode": %d , "Data": %s} ` , Code , JsonRet )
}
}
slf . h ttpRouter . PutHttpSession ( session )
ticker := time . NewTicker ( slf . processTimeout )
select {
case <- ticker . C :
session . WriteStatusCode ( http . StatusGatewayTimeout )
session . flush ( )
break
case <- session . sessionDone :
if session . fileData != nil {
slf . ProcessFile ( session )
} else if session . redirectData != nil {
session . redirects ( )
} else {
s ession . flush ( )
}
}
slf . Respone = [ ] byte ( StrRet )
}
func ( slf * HttpRespone ) Redirect ( url string , cookieList [ ] * http . Cookie ) {
slf . RedirectData . Url = url
slf . RedirectData . CookieList = cookieList
}
func ( slf * HttpRespone ) redirects ( w * http . ResponseWriter , req * http . Request ) {
if slf . RedirectData . CookieList != nil {
for _ , v := range slf . RedirectData . CookieList {
http . SetCookie ( * w , v )
}
}
http . Redirect ( * w , req , slf . RedirectData . Url ,
// see @andreiavrammsd comment: often 307 > 301
http . StatusTemporaryRedirect )
}