精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入理解Go標準庫-HTTP-Server的啟動

開發 前端
除了Go標準庫中提供了http.ServeMux?還有一系列開源庫gorilla/mux、go-chi/chi、julienschmidt/httprouter對Handler進行了實現。每一個庫具有的能力、使用方式、性能不同,但萬變不離其宗,都繞不開組合模式和Handler接口。

如何用最少的代碼創建一個HTTP server?

package main

import (
 "net"
 "net/http"
)

func main() {
 // 方式1
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
   panic(err)
 }
}

點開http.ListenAndServe可以看到函數只是創建了Server類型并調用server.ListenAndServe()

所以下面的和上面的代碼沒有區別

package main

import (
 "net"
 "net/http"
)

func main() {
 // 方式2
 server := &http.Server{Addr: ":8080"}
 err := server.ListenAndServe()
 if err != nil {
  panic(err)
 }
}

ListenAndServe()如其名會干兩件事

  • 監聽一個端口,即Listen的過程
  • 處理進入端口的連接,即Serve的過程

所以下面的代碼和上面的代碼也沒區別

package main

import (
 "net"
 "net/http"
)

func main() {
 // 方式3
 ln, err := net.Listen("tcp", ":8080")
 if err != nil {
  panic(err)
 }

 server := &http.Server{}
 err = server.Serve(ln)
 if err != nil {
  panic(err)
 }
}

一張圖展示三種使用方式

圖片圖片

路由?no!Handler!

按上面的代碼啟動HTTP Server沒有太大意義,因為我們還沒有設定路由,所以無法正常響應請求

$ curl  127.0.0.1:8080 
404 page not found

暫停思考一下,服務器返回404是因為沒有設定路由么?no,no,no,你需要轉變一下思維。服務器返回404不是因為我們沒有設置路由,而是因為沒有設置請求的處理程序,這個處理程序在Go中叫作:Handler!

type Handler interface {
 ServeHTTP(ResponseWriter, *Request)
}

?? 怎么定義請求的處理程序?

由上可知,僅需要實現ServeHTTP(ResponseWriter, *Request)接口即可

注意,示例代碼沒有判斷任何路由(PATH)

type handlerImp struct {
}

func (imp handlerImp) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 if r.Method == "GET" {
  w.Write([]byte("Receive GET request"))
  return
 }
 if r.Method == "POST" {
  w.Write([]byte("Receive POST request"))
  return
 }
 return
}

?? 怎么設置請求的處理程序?

圖片圖片

三種方式本質上都是把自定義的Handler賦值到Server的Handler屬性中

func main() {
 // 方式1
 // err := http.ListenAndServe(":8080", handlerImp{})
 // if err != nil {
 //  panic(err)
 // }

 // 方式2
 // server := &http.Server{Addr: ":8080", Handler: handlerImp{}}
 // err := server.ListenAndServe()
 // if err != nil {
 //  panic(err)
 // }

 // 方式3
 ln, err := net.Listen("tcp", ":8080")
 if err != nil {
  panic(err)
 }

 server := &http.Server{Handler:handlerImp{}}
 err = server.Serve(ln)
 if err != nil {
  panic(err)
 }
}

?? 設置請求的處理程序之后的效果

handlerImp只針對Method做了不同的響應,沒有對PATH做任何的判斷,所以無論請求什么樣的路徑都能拿到一個預期的響應。

$ curl  -X POST 127.0.0.1:8080/foo
Receive POST request%  

$ curl  127.0.0.1:8080/foo/bar 
Receive GET request%

此時再體會一下這句話:我們設置的不是路由,而是設置請求的處理程序

再聊Handler

type handlerImp struct {
}

func (imp handlerImp) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 if r.Method == "GET" {
  w.Write([]byte("Receive GET request"))
  return
 }
 if r.Method == "POST" {
  w.Write([]byte("Receive POST request"))
  return
 }
 return
}

如上所述,無論任何PATH,任何Method等,所有的請求都會被handlerImp.ServeHTTP處理。

我們可以判斷PATH、Method等,根據不同的請求特征執行不同的邏輯,并且全部在這一個函數中全部完成

很明顯,這違反了高內聚,低耦合的編程范式

停下來思考下,如何編寫一個高內聚,低耦合的handlerImp.ServeHTTP,使之針對不同HTTP請求執行不同的邏輯呢

type handlerImp struct {
}

func (imp handlerImp) handleMethodGet(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive GET request"))
 return
}

func (imp handlerImp) handleMethodPost(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive POST request"))
 return
}

func (imp handlerImp) handlePathFoo(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive path foo"))
 return
}

func (imp handlerImp) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 if r.URL.Path == "/foo" {
  imp.handlePathFoo(w, r)
  return
 }
 if r.Method == "GET" {
  imp.handleMethodGet(w, r)
  return
 }
 if r.Method == "POST" {
  imp.handleMethodPost(w, r)
  return
 }
 return
}

如果你的答案和上面的代碼類似,那么我對于這段代碼的點評是:不太高明??

?? 如何編寫一個高內聚,低耦合的ServeHTTP,針對不同HTTP請求執行不同的邏輯?

不知道你有沒有聽過設計模式中,組合模式。沒有了解可以去了解下,或者看下圖

圖片圖片

經過組合模式重新設計的handlerImp,已經不再包含具體的邏輯了,它先搜索有沒有針對PATH處理的邏輯,再搜索有沒有針對Method處理的邏輯,它專注于邏輯分派,它是組合模式中的容器。

容器(Container):容器接收到請求后會將工作分配給自己的子項目, 處理中間結果, 然后將最終結果返回給客戶端。

type handlerImp struct {
 pathHandlers   map[string]http.Handler
 methodHandlers map[string]http.Handler
}

func NewHandlerImp() handlerImp {
 return handlerImp{
  pathHandlers:   make(map[string]http.Handler),
  methodHandlers: make(map[string]http.Handler),
 }
}

func (imp handlerImp) AddPathHandler(path string, h http.Handler) {
 imp.pathHandlers[path] = h
}

func (imp handlerImp) AddMethodHandler(method string, h http.Handler) {
 imp.methodHandlers[method] = h
}

func (imp handlerImp) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 if h, ok := imp.pathHandlers[r.URL.Path]; ok {
  h.ServeHTTP(w, r)
  return
 }

 if h, ok := imp.methodHandlers[r.Method]; ok {
  h.ServeHTTP(w, r)
  return
 }

 return
}

重新設計的handlerImp不執行邏輯,實際的邏輯被分離到每一個葉子結點中,而每一個葉子結點也都實現了ServeHTTP函數,即Handler接口

type PathFoo struct {
}

func (m PathFoo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive path foo"))
 return
}

type MethodGet struct {
}

func (m MethodGet) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive GET request"))
 return
}

type MethodPost struct {
}

func (m MethodPost) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive POST request"))
 return
}

圖片圖片

再次強調,通過對組合模式的運用,我們把邏輯分派的功能聚合到handlerImp,把具體的邏輯聚合到PathFoo、MethodGet、MethodPost

func main() {
 // 方式3
 ln, err := net.Listen("tcp", ":8080")
 if err != nil {
  panic(err)
 }

 h := NewHandlerImp()
 h.AddMethodHandler("GET", MethodGet{})
 h.AddMethodHandler("POST", MethodPost{})
 h.AddPathHandler("/foo", PathFoo{})

 server := &http.Server{Handler: h}
 err = server.Serve(ln)
 if err != nil {
  panic(err)
 }
}

一些Handlers

上面實現的handlerImp利用組合設計模式,已經能針對Path和Method設定和處理不同的邏輯,但整體功能略顯簡單。有哪些可以供我們使用且功能強大的Handlers呢?

http.ServeMux

Go標準庫中就提供了一個Handler實現叫作http.ServeMux

?? 當前(go1.21.*)版本僅支持匹配Path,但目前已經在討論支持Method匹配和占位符了:net/http: add methods and path variables to ServeMux patterns #60227[1]

使用的方式如下

http.ServeMux提供兩個函數用于注冊不同Path的處理函數

  • ServeMux.Handle 接收的是Handler接口實現
  • ServeMux.HandleFunc 接收的是匿名函數
type PathBar struct {
}

func (m PathBar) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive path bar"))
 return
}

func main() {
 // 方式3
 ln, err := net.Listen("tcp", ":8080")
 if err != nil {
  panic(err)
 }

 mx := http.NewServeMux()
 mx.Handle("/bar/", PathBar{})
 mx.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive path foo"))
 })

 server := &http.Server{Handler: mx}
 err = server.Serve(ln)
 if err != nil {
  panic(err)
 }
}

代碼mx.Handle("/bar/", PathBar{})中/bar/由/結尾,所以它可以匹配/bar/*所有的Path

關于http.ServeMux的細節不是本篇重點,后續會單獨介紹

?? 默認的Handler

因為是標準庫內置的實現,當沒有設置http.Server.Handler屬性時,http.Server就會使用一個全局的變量DefaultServeMux *ServeMux來作為http.Server.Handler的值

var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

http包同時提供了兩個函數可以在DefaultServeMux注冊不同Path的處理函數

func main() {
 http.Handle("/bar/", PathBar{})
 http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive path foo"))
 })

 // 方式1
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  panic(err)
 }
}

http.Handle 接收的是Handler接口實現,對應的是

func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }

http.HandleFunc 接收的是匿名函數,對應的是

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 DefaultServeMux.HandleFunc(pattern, handler)
}

gorilla/mux[2]

gorilla/mux是一個相當流行的第三方庫,用法這里簡單寫下

除了經典的Handle、HandleFunc函數,gorilla/mux還提供了Methods、Schemes、Host等非常復雜的功能

但無論多復雜,其一定包含了ServeHTTP函數,即實現了Handler接口

func main() {
 r := mux.NewRouter()
    r.Handle("/foo/{bar}", PathBar{})
 r.Handle("/bar/", PathBar{})
 r.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive path foo"))
 })
 r.Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive GET request"))
 })

 // 方式1
 err := http.ListenAndServe(":8080", r)
 if err != nil {
  panic(err)
 }
}

其他

還有很多其他優秀的mux實現,具體可以參考各自的官方文檔。

https://github.com/go-chi/chi star 15.9k

https://github.com/julienschmidt/httprouter star 15.6k

關于Go標準庫、第三方庫中這些結構的關系通過下圖展示

圖片圖片

再聊組合模式

無論是官方的http.ServeMux,還是一些第三方庫,實現上大多使用了組合設計模式

組合模式的魔力還不止于此。思考一下這個場景:目前已經存在路由servemux/*,并且使用了ServeMux

mx := http.NewServeMux()
mx.Handle("/servemux/bar/", PathBar{})
mx.HandleFunc("/servemux/foo", func(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte("Receive servemux path foo"))
})

但此時還有另外一組路由/gorilla/*,使用了開源庫gorilla/mux

r := mux.NewRouter()
r.Handle("/gorilla/bar/", PathBar{})
r.HandleFunc("/gorilla/foo", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Receive gorilla path foo"))
})

如何啟動這樣的服務器呢?

func main() {
 mx := http.NewServeMux()
 mx.Handle("/servemux/bar/", PathBar{})
 mx.HandleFunc("/servemux/foo", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive servemux path foo"))
 })

 r := mux.NewRouter()
 r.Handle("/gorilla/bar/", PathBar{})
 r.HandleFunc("/gorilla/foo", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Receive gorilla path foo"))
 })

 h := http.NewServeMux()
 h.Handle("/servemux/", mx)
 h.Handle("/gorilla/", r)

 // 方式1
 err := http.ListenAndServe(":8080", h)
 if err != nil {
  panic(err)
 }
}

利用組合設計模式,h := http.NewServeMux()作為新的容器,將不同的路由分配給另外兩個容器

  • mx := http.NewServeMux()
  • r := mux.NewRouter()

圖片圖片

總結

本文主要介紹了Go http server的啟動方式,重點介紹了http server的請求處理器

type Handler interface {
 ServeHTTP(ResponseWriter, *Request)
}

別看它僅包含一個方法,但在組合模式的加成下,可以實現千變萬化的形態。

除了Go標準庫中提供了http.ServeMux還有一系列開源庫gorilla/mux、go-chi/chi、julienschmidt/httprouter對Handler進行了實現。

每一個庫具有的能力、使用方式、性能不同,但萬變不離其宗,都繞不開組合模式和Handler接口

參考資料

[1]net/http: add methods and path variables to ServeMux patterns #60227: https://github.com/golang/go/discussions/60227

[2]gorilla/mux: https://github.com/gorilla/mux#gorillamux

[3]設計模式/結構型模式/組合模式: https://refactoringguru.cn/design-patterns/composite

責任編輯:武曉燕 來源: 涼涼的知識庫
相關推薦

2023-12-04 08:46:40

Go標準庫

2021-10-16 17:53:35

Go函數編程

2022-07-13 14:12:41

HTTP/3前端

2015-03-17 09:44:08

2023-10-27 11:27:14

Go函數

2025-01-13 13:00:00

Go網絡框架nbio

2019-08-19 12:50:00

Go垃圾回收前端

2016-12-08 15:36:59

HashMap數據結構hash函數

2010-06-01 15:25:27

JavaCLASSPATH

2020-07-21 08:26:08

SpringSecurity過濾器

2024-04-07 00:04:00

Go語言Map

2012-11-22 10:11:16

LispLisp教程

2021-12-28 17:39:05

Go精度Json

2019-12-06 09:44:27

HTTP數據安全

2009-09-25 09:14:35

Hibernate日志

2021-02-17 11:25:33

前端JavaScriptthis

2023-10-19 11:12:15

Netty代碼

2013-09-22 14:57:19

AtWood

2017-08-15 13:05:58

Serverless架構開發運維

2025-05-06 00:43:00

MySQL日志文件MIXED 3
點贊
收藏

51CTO技術棧公眾號

日韩av片在线| 男女高潮又爽又黄又无遮挡| 国产精品久久久久久久免费看| 亚洲色图国产| 亚洲精品国产综合久久| 一级特黄性色生活片| 91香蕉在线观看| 91网站在线播放| 成人免费看吃奶视频网站| 国产精品第九页| 色小子综合网| 亚洲精品综合久久中文字幕| 亚洲 国产 图片| 大胆人体一区| 亚洲综合色噜噜狠狠| 色一情一乱一伦一区二区三区丨 | 免费网站看v片在线a| www.激情成人| 99高清视频有精品视频| 啪啪小视频网站| 黄色成人91| 久久伊人色综合| 91久久免费视频| 国产精品传媒| 日韩欧美在线观看一区二区三区| 国产成人黄色片| 日本精品600av| 中文字幕亚洲电影| 日韩欧美精品一区二区三区经典| 女人18毛片水真多18精品| 精品一区二区三区在线播放| 69久久夜色精品国产7777| 永久免费看黄网站| 91精品国产91久久久久久黑人| 亚洲欧美在线一区| 久久无码人妻精品一区二区三区| 伊人精品久久| 欧美一级免费观看| 午夜福利123| 国产亚洲人成a在线v网站| 色综合天天综合网天天看片| 老太脱裤让老头玩ⅹxxxx| 菠萝蜜视频国产在线播放| 国产精品三级久久久久三级| 欧美一区二区综合| 欧美女优在线观看| 久久精品一区蜜桃臀影院| 久久久7777| 三级理论午夜在线观看| 99久久er热在这里只有精品15| 国产精品区一区| 亚洲国产一二三区| 成人av免费在线观看| 国产高清在线一区| 手机看片国产1024| 91麻豆视频网站| 欧美日韩高清免费| 草草影院在线观看| 国产精品久久国产精麻豆99网站| 亚洲成人蜜桃| 午夜小视频在线| 亚洲品质自拍视频网站| av一区二区三区免费观看| 四虎亚洲成人| 天天综合色天天综合色h| 97国产精东麻豆人妻电影 | 国产精品一二三在线| 中文在线a天堂| 九一久久久久久| 91在线直播亚洲| 男人天堂综合网| 久久久www免费人成精品| 亚洲春色在线视频| 亚洲国产精品精华素| 亚洲成人动漫精品| 熟女人妇 成熟妇女系列视频| 欧美123区| 欧美一区二区三区小说| 在线免费看黄色片| 国产真实有声精品录音| 中文字幕欧美国内| 久久久全国免费视频| 亚洲在线成人| 亚洲aa在线观看| 亚洲色图21p| 国产精品高潮久久久久无| 日韩一级特黄毛片| 成人影院网站| 日韩美女视频在线| 中文字幕一区二区三区人妻电影| 97久久夜色精品国产| 久久久久久久久国产精品| 亚洲欧美一区二区三区在线观看| 久久国产尿小便嘘嘘| 福利视频久久| 99青草视频在线播放视| 亚洲一区免费观看| www.色就是色| 麻豆国产欧美一区二区三区r| 一区二区三区 在线观看视| 亚洲av鲁丝一区二区三区| 久久精品女人天堂| 96久久精品| 成人免费一区二区三区视频网站| 亚洲资源中文字幕| 亚洲免费看av| 岳的好大精品一区二区三区| 另类专区欧美制服同性| 波多野结衣电车痴汉| 丁香婷婷深情五月亚洲| 亚洲视频欧美在线| 三级中文字幕在线观看| 日韩免费高清视频| 国产一二三av| 久久伊人亚洲| 久久久久久久久久久久久久久久av| 成人无遮挡免费网站视频在线观看| 欧美性猛交xxxx免费看久久久| 亚洲一区二区偷拍| 成人短片线上看| 日韩免费在线看| 天天摸夜夜添狠狠添婷婷| 亚洲美女区一区| xx欧美撒尿嘘撒尿xx| 亚洲色图丝袜| 69av成年福利视频| 日本精品一二区| 亚洲精品一卡二卡| 热久久久久久久久| 日产午夜精品一线二线三线| 日本亚洲精品在线观看| 日本xxxxxwwwww| 亚洲一区二区三区四区五区中文| 做a视频在线观看| 日韩精品一区二区久久| 国产精品wwwwww| 国产主播福利在线| 日本乱人伦一区| 国产免费看av| 日韩综合一区二区| 日韩一区二区三区高清| 婷婷激情一区| 在线视频一区二区| 中文字幕一区二区三区波野结| 久久久久久久av麻豆果冻| 内射国产内射夫妻免费频道| 果冻天美麻豆一区二区国产| 久久久久久久久久久久av| 亚洲男人第一天堂| 亚洲超碰97人人做人人爱| 国产51自产区| 一区二区三区四区五区在线| 国产中文一区二区| 色是在线视频| 国产亚洲精品日韩| 一级特黄aaaaaa大片| 国产精品国产a| 久久精品无码一区二区三区毛片| 欧美精品导航| 国产在线欧美日韩| 欧美黄色网页| 色多多国产成人永久免费网站 | 欧美一级夜夜爽| 欧美精品99久久久| a亚洲天堂av| aaaaaa亚洲| 91蜜臀精品国产自偷在线| 亚洲xxxx做受欧美| 91美女主播在线视频| 亚洲免费av片| 国产又粗又长又黄| 亚洲午夜久久久久久久久久久| 日本69式三人交| 日韩在线观看一区二区| 秋霞在线一区二区| 超碰成人免费| 国产精国产精品| 黄色网页在线观看| 亚洲精品国产免费| 影音先锋黄色网址| 亚洲一二三区不卡| 美女被到爽高潮视频| 麻豆精品国产91久久久久久| 亚洲精品少妇一区二区| 亚洲成人一品| 91精品国产综合久久久久久蜜臀| 久久一卡二卡| 中文字幕一区二区精品| 午夜精品久久久久久久爽| 一本一道波多野结衣一区二区| 麻豆天美蜜桃91| 懂色av中文一区二区三区| www.国产区| 伊人久久成人| 中文有码久久| 亚洲人挤奶视频| 91成人理论电影| av一区在线播放| 久久久亚洲网站| 美女隐私在线观看| 亚洲欧美精品一区二区| 国内精品偷拍视频| 欧美三级中文字| 欧美一区二区三区四| 亚洲欧美日本韩国| 蜜桃久久精品成人无码av| 高清视频一区二区| 亚洲视频一二三四| 久久久精品网| 一本久道高清无码视频| 久久精品影视| 日韩欧美亚洲在线| 色爱av综合网| 国产日本一区二区三区| 日韩一二三区在线观看| 国产精品自拍小视频| 天堂√中文最新版在线| 欧美国产日韩一区二区三区| 久做在线视频免费观看| 一区二区三区精品99久久| 亚欧在线观看视频| 亚洲精品一区二区三区四区高清| 99久久精品国产成人一区二区| 一本到不卡免费一区二区| 欧美亚韩一区二区三区| 一区二区三区日韩欧美精品| 成人黄色短视频| 国产欧美日韩三区| 天天躁日日躁aaaxxⅹ | 国产农村妇女精品一区| 久久亚洲春色中文字幕久久久| 欧美日韩一区二区三区四区五区六区| 激情伊人五月天久久综合| 欧美三级理论片| 奇米一区二区三区| 一级在线免费视频| 日韩电影免费在线| 网站一区二区三区| 美腿丝袜一区二区三区| 国产野外作爱视频播放| 欧美96一区二区免费视频| 国产一级特黄a大片免费| 老色鬼久久亚洲一区二区| 97国产在线播放| 久久婷婷影院| 免费黄色一级网站| 美女免费视频一区二区| 伊人网在线综合| 激情国产一区二区| 国产成人av免费观看| 国产成人精品亚洲日本在线桃色 | 91老司机福利 在线| 亚洲调教欧美在线| 久久亚洲综合色| av黄色在线免费观看| 国产精品久久毛片a| 午夜爽爽爽男女免费观看| 亚洲欧美日韩一区| 劲爆欧美第一页| 黄色一区二区在线观看| 日本高清不卡码| 欧美亚洲一区三区| 国产女人18毛片18精品| 精品国产乱码久久久久久影片| 粉嫩av一区二区夜夜嗨| 日韩精品黄色网| porn视频在线观看| 久久99精品国产99久久6尤物| 黑人精品视频| 日本亚洲欧美三级| 亚洲国产伊人| 国产精品久久久久久免费观看| 欧美黑人巨大videos精品| 日韩视频在线播放| 欧美黄色免费| www.日日操| 国产精品一区二区久久不卡| 欧类av怡春院| 国产精品毛片久久久久久| 中文字幕五月天| 精品久久久国产| 一级α片免费看刺激高潮视频| 欧美一激情一区二区三区| 天天干天天爽天天操| 色偷偷综合社区| 成人影院在线视频| 国产欧亚日韩视频| 麻豆一区二区麻豆免费观看| 日韩av大全| 亚洲婷婷免费| 一区二区三区入口| av中文字幕不卡| 国产精品国产三级国产传播| 婷婷国产v国产偷v亚洲高清| 国产又黄又大又爽| 亚洲国产成人久久| 淫片在线观看| 66m—66摸成人免费视频| 亚洲伊人精品酒店| 欧洲亚洲一区二区| 激情一区二区| 91丝袜超薄交口足| 国产视频911| 日韩黄色一级大片| 日韩一区二区免费在线电影| 国产小视频福利在线| 久久99国产精品久久久久久久久| 成人国产在线| 欧美xxxx黑人又粗又长密月| 欧美午夜不卡| 国产美女视频免费看| 久久久久久麻豆| 久久国产精品系列| 精品久久久久av影院 | 久久精品论坛| 久久www视频| 久久99国产精品久久99果冻传媒| 精品人妻一区二区三区香蕉| 一片黄亚洲嫩模| 国产一区二区三区四区视频 | 国产一二区在线观看| 国产精品久久久久7777婷婷| 青青草原在线亚洲| 青青在线免费观看| 国产精品18久久久久久久久 | 影音先锋成人在线电影| 日日噜噜夜夜狠狠| 欧美激情一区在线观看| 国产精品suv一区| 日韩不卡在线观看| 超碰在线视屏| 精品婷婷色一区二区三区蜜桃| 欧美日韩p片| 中文字幕1区2区| 亚洲精品乱码久久久久| 国产视频手机在线| 免费av一区二区| 久久9999免费视频| 伊人久久在线观看| 国产精品一区专区| 久久香蕉精品视频| 亚洲大尺度美女在线| gogo高清午夜人体在线| 国产一区免费| 亚洲中字黄色| 亚洲精品乱码久久久久久久久久久久| 欧美性69xxxx肥| 国外av在线| 国产精品日日做人人爱| 日韩久久电影| 亚洲第一区第二区第三区| 亚洲天堂网中文字| 精品久久久久久亚洲综合网站| 美女福利视频一区| 99a精品视频在线观看| 成人在线播放网址| 91免费看片在线观看| 亚洲欧美另类在线视频| 国产一区二区三区欧美| 亚洲国产综合在线观看| av影院在线播放| 99精品一区二区| 天堂av免费在线观看| 久久亚洲一区二区三区四区五区高| 日韩一二三区在线观看| 欧美在线观看www| 国产精品网曝门| www.国产欧美| 97av在线视频| 欧美天天综合| 伊人影院在线观看视频| 激情久久av一区av二区av三区| 欧美伦理影视网| 成人激情av在线| 在线欧美不卡| 亚欧精品视频一区二区三区| 3d动漫精品啪啪1区2区免费| 欧洲一区二区三区| 欧美一区国产一区| 国产自产v一区二区三区c| 中文字幕一区二区三区手机版| 亚洲性生活视频在线观看| 国产精品一区二区精品| 北条麻妃在线视频观看| 综合久久久久久久| 深夜福利在线视频| 91久久精品国产91久久| 亚洲欧洲另类| 蜜桃av.com| 精品偷拍各种wc美女嘘嘘| 亚洲精品一区二区在线播放∴| 中文字幕无码精品亚洲资源网久久| 久久精品视频在线看| 性猛交富婆╳xxx乱大交天津| 欧美一级电影在线| 午夜亚洲福利| 亚洲ⅴ国产v天堂a无码二区| 亚洲а∨天堂久久精品喷水| 外国电影一区二区| 男人用嘴添女人下身免费视频|