github.com/readium/readium-lcp-server@v0.0.0-20240509124024-799e77a0bbd6/lsdserver/server/server.go (about)

     1  // Copyright 2017 European Digital Reading Lab. All rights reserved.
     2  // Licensed to the Readium Foundation under one or more contributor license agreements.
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file exposed on Github (readium) in the project repository.
     5  
     6  package lsdserver
     7  
     8  import (
     9  	"net/http"
    10  	"time"
    11  
    12  	auth "github.com/abbot/go-http-auth"
    13  	"github.com/gorilla/mux"
    14  
    15  	"github.com/readium/readium-lcp-server/api"
    16  	licensestatuses "github.com/readium/readium-lcp-server/license_statuses"
    17  	apilsd "github.com/readium/readium-lcp-server/lsdserver/api"
    18  	"github.com/readium/readium-lcp-server/transactions"
    19  )
    20  
    21  type Server struct {
    22  	http.Server
    23  	readonly  bool
    24  	goofyMode bool
    25  	lst       licensestatuses.LicenseStatuses
    26  	trns      transactions.Transactions
    27  }
    28  
    29  func (s *Server) LicenseStatuses() licensestatuses.LicenseStatuses {
    30  	return s.lst
    31  }
    32  
    33  func (s *Server) Transactions() transactions.Transactions {
    34  	return s.trns
    35  }
    36  
    37  func (s *Server) GoofyMode() bool {
    38  	return s.goofyMode
    39  }
    40  
    41  func New(bindAddr string, readonly bool, goofyMode bool, lst *licensestatuses.LicenseStatuses, trns *transactions.Transactions, basicAuth *auth.BasicAuth) *Server {
    42  
    43  	sr := api.CreateServerRouter("")
    44  
    45  	s := &Server{
    46  		Server: http.Server{
    47  			Handler:        sr.N,
    48  			Addr:           bindAddr,
    49  			WriteTimeout:   15 * time.Second,
    50  			ReadTimeout:    15 * time.Second,
    51  			MaxHeaderBytes: 1 << 20,
    52  		},
    53  		readonly:  readonly,
    54  		lst:       *lst,
    55  		trns:      *trns,
    56  		goofyMode: goofyMode,
    57  	}
    58  
    59  	// Route.PathPrefix: http://www.gorillatoolkit.org/pkg/mux#Route.PathPrefix
    60  	// Route.Subrouter: http://www.gorillatoolkit.org/pkg/mux#Route.Subrouter
    61  	// Router.StrictSlash: http://www.gorillatoolkit.org/pkg/mux#Router.StrictSlash
    62  
    63  	licenseRoutesPathPrefix := "/licenses"
    64  	licenseRoutes := sr.R.PathPrefix(licenseRoutesPathPrefix).Subrouter().StrictSlash(false)
    65  
    66  	s.handlePrivateFunc(sr.R, licenseRoutesPathPrefix, apilsd.FilterLicenseStatuses, basicAuth).Methods("GET")
    67  
    68  	s.handleFunc(licenseRoutes, "/{key}/status", apilsd.GetLicenseStatusDocument).Methods("GET")
    69  	s.handleFunc(licenseRoutes, "/{key}", apilsd.GetFreshLicense).Methods("GET")
    70  
    71  	s.handlePrivateFunc(licenseRoutes, "/{key}/registered", apilsd.ListRegisteredDevices, basicAuth).Methods("GET")
    72  	if !readonly {
    73  		s.handleFunc(licenseRoutes, "/{key}/register", apilsd.RegisterDevice).Methods("POST")
    74  		s.handleFunc(licenseRoutes, "/{key}/return", apilsd.LendingReturn).Methods("PUT")
    75  		s.handleFunc(licenseRoutes, "/{key}/renew", apilsd.LendingRenewal).Methods("PUT")
    76  		s.handlePrivateFunc(licenseRoutes, "/{key}/status", apilsd.LendingCancellation, basicAuth).Methods("PATCH")
    77  
    78  		s.handlePrivateFunc(sr.R, "/licenses", apilsd.CreateLicenseStatusDocument, basicAuth).Methods("PUT")
    79  		s.handlePrivateFunc(licenseRoutes, "/", apilsd.CreateLicenseStatusDocument, basicAuth).Methods("PUT")
    80  	}
    81  
    82  	return s
    83  }
    84  
    85  type HandlerFunc func(w http.ResponseWriter, r *http.Request, s apilsd.Server)
    86  
    87  func (s *Server) handleFunc(router *mux.Router, route string, fn HandlerFunc) *mux.Route {
    88  	return router.HandleFunc(route, func(w http.ResponseWriter, r *http.Request) {
    89  		fn(w, r, s)
    90  	})
    91  }
    92  
    93  type HandlerPrivateFunc func(w http.ResponseWriter, r *http.Request, s apilsd.Server)
    94  
    95  func (s *Server) handlePrivateFunc(router *mux.Router, route string, fn HandlerPrivateFunc, authenticator *auth.BasicAuth) *mux.Route {
    96  	return router.HandleFunc(route, func(w http.ResponseWriter, r *http.Request) {
    97  		if api.CheckAuth(authenticator, w, r) {
    98  			fn(w, r, s)
    99  		}
   100  	})
   101  }