简介
下载好电影电视剧但是又不想呆在电脑旁边, 你可能只需要开启一个Go服务, 简单几句代码....
实现
-
中间件
做一个简单的包装器, 用于处理所有外部访问。 -
IP过滤器
过滤IP, 对不符合的IP进行过滤
步骤
代码
IP过滤器
filter.go
package mainimport "errors"var (FliterParameterError = errors.New("parameter error")
)type IFilterResult interface {IsOK() boolLastError() error
}type IFilter interface {Filter(v interface{}) IFilterResult
}type oker struct {
}func (o *oker) IsOK() bool {return true
}func (o *oker) LastError() error { return nil }type notOker struct {err error
}func (o *notOker) IsOK() bool {return false
}func (o *notOker) LastError() error { return o.err }
ipfilter.go
package mainimport "errors"var (FliterBlackListError = errors.New("blacklist error")
)type IPFilter struct {whites []stringblacks []string
}func NewIPFliter(whiteIPs []string, blackIPs []string) IFilter {return &IPFilter{whites: whiteIPs, blacks: blackIPs}
}func (t *IPFilter) Filter(v interface{}) IFilterResult {str, ok := v.(string)if !ok {return ¬Oker{err: FliterParameterError}}ok, err := t.filter(str)if ok {return &oker{}}return ¬Oker{err: err}
}func (t *IPFilter) filter(str string) (ok bool, err error) {for i := range t.whites {if str == t.whites[i] {ok = truereturn}}for i := range t.blacks {if str == t.blacks[i] {ok = falseerr = FliterBlackListErrorreturn}}return
}
中间件
middleware.go
package mainimport ("fmt""net/http""strings"
)type Wrapper struct {httpHandler http.Handlerfilter IFilter
}func NewWrapper(h http.Handler, filter IFilter) *Wrapper {var (wrp = &Wrapper{httpHandler: h, filter: filter})return wrp
}func (wrp *Wrapper) HttpHandler() http.Handler {return http.HandlerFunc(wrp.handle)
}/* handle: 所有外部访问都会经过这里 */
func (wrp *Wrapper) handle(w http.ResponseWriter, r *http.Request) {fliter := wrp.filter.Filter(wrp.getClientIP(r))if !fliter.IsOK() {wrp.writeWelcomView(w, r, fliter.LastError())return}wrp.httpHandler.ServeHTTP(w, r)
}func (wrp *Wrapper) writeWelcomView(w http.ResponseWriter, r *http.Request, err error) {fmt.Fprintf(w, "<html><head><title>非法访问</title></head><body>")fmt.Fprintf(w, "<h1>Welcom!!!!<h1>")fmt.Fprintf(w, "<h2>您还不是白名单用户,请联系亲爱的管理员同志!(温馨提醒, 别打人!) </h2>")fmt.Fprintf(w, "<h3>您的IP地址是: %s</h3>", wrp.getClientIP(r))if nil != err {fmt.Fprintf(w, "<p>errMsg : %s</p>", err.Error())}fmt.Fprintf(w, "</body></html>")
}func (wrp *Wrapper) getClientIP(r *http.Request) string {// 获取客户端IP地址clientIP := r.RemoteAddr// 如果服务器后面有代理,使用X-Forwarded-For或X-Real-IP获取真实的客户端IPif xff := r.Header.Get("X-Forwarded-For"); xff != "" {clientIP = xff} else if xri := r.Header.Get("X-Real-IP"); xri != "" {clientIP = xri}strs := strings.Split(clientIP, ":") // ip:portif 0 < len(strs) {return strs[0]}return clientIP
}
main
package mainimport ("log""net/http"
)func main() {mux := http.NewServeMux()ipfilter := NewIPFliter([]string{ // 可以访问的IP"192.168.3.42", // 本机IP}, []string{ // 不能访问的IP})warpper := NewWrapper(mux, ipfilter)mux.Handle("/dsj/", http.StripPrefix("/dsj/", http.FileServer(http.Dir("D:\\AppData\\XmpCache\\电视剧"))))if err := http.ListenAndServe(":1020", warpper.HttpHandler()); err != nil {log.Fatal(err)}
}
共赏
Go实现简易网页电脑目录访问