github.com/go-kivik/kivik/v4@v4.3.2/x/kivikd/couchserver/couchserver.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 //go:build !js 14 15 package couchserver 16 17 import ( 18 "context" 19 "log" 20 "net/http" 21 22 "github.com/go-chi/chi" 23 24 "github.com/go-kivik/kivik/v4" 25 ) 26 27 const ( 28 typeJSON = "application/json" 29 ) 30 31 type db interface { 32 Stats(context.Context) (*kivik.DBStats, error) 33 Flush(context.Context) error 34 } 35 36 type backend interface { 37 AllDBs(context.Context, ...kivik.Option) ([]string, error) 38 CreateDB(context.Context, string, ...kivik.Option) error 39 DB(context.Context, string, ...kivik.Option) (db, error) 40 DBExists(context.Context, string, ...kivik.Option) (bool, error) 41 } 42 43 type clientWrapper struct { 44 *kivik.Client 45 } 46 47 var _ backend = &clientWrapper{} 48 49 func (c *clientWrapper) DB(_ context.Context, dbName string, options ...kivik.Option) (db, error) { 50 db := c.Client.DB(dbName, options...) 51 return db, db.Err() 52 } 53 54 // Handler is a CouchDB server handler. 55 type Handler struct { 56 client backend 57 // CompatVersion is the CouchDB compatibility version to report. If unset, 58 // defaults to the CompatVersion constant/. 59 CompatVersion string 60 // Vendor is the vendor name to report. If unset, defaults to the 61 // kivik.Vendor constant. 62 Vendor string 63 // VendorVersion is the vendor version to report. If unset, defaults to the 64 // kivik.VendorVersion constant. 65 VendorVersion string 66 Logger *log.Logger 67 // Favicon is the path to a favicon.ico to serve. 68 Favicon string 69 // SessionKey is a temporary solution to avoid import cycles. Soon I will move the key to another package. 70 SessionKey interface{} 71 } 72 73 // NewHandler returns a CouchDB server handler. 74 func NewHandler(client *kivik.Client) *Handler { 75 return &Handler{client: &clientWrapper{client}} 76 } 77 78 // CompatVersion is the default CouchDB compatibility provided by this package. 79 const CompatVersion = "0.0.0" 80 81 func (h *Handler) vendor() (compatVer, vend, ver string) { 82 if h.CompatVersion == "" { 83 compatVer = CompatVersion 84 } else { 85 compatVer = h.CompatVersion 86 } 87 if h.Vendor == "" { 88 vend = "Kivik" 89 } else { 90 vend = h.Vendor 91 } 92 if h.VendorVersion == "" { 93 ver = kivik.Version 94 } else { 95 ver = h.VendorVersion 96 } 97 return compatVer, vend, ver 98 } 99 100 // Main returns an http.Handler to handle all CouchDB endpoints. 101 func (h *Handler) Main() http.Handler { 102 r := chi.NewRouter() 103 r.Get("/", h.GetRoot()) 104 r.Get("/favicon.ico", h.GetFavicon()) 105 r.Get("/_all_dbs", h.GetAllDBs()) 106 r.Get("/{db}", h.GetDB()) 107 r.Put("/{db}", h.PutDB()) 108 r.Head("/{db}", h.HeadDB()) 109 r.Post("/{db}/_ensure_full_commit", h.Flush()) 110 r.Get("/_session", h.GetSession()) 111 return r 112 } 113 114 type serverInfo struct { 115 CouchDB string `json:"couchdb"` 116 Version string `json:"version"` 117 Vendor vendorInfo `json:"vendor"` 118 } 119 120 type vendorInfo struct { 121 Name string `json:"name"` 122 Version string `json:"version"` 123 }