MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / wrapRouter

Function wrapRouter

rest/routing.go:426–480  ·  view source on GitHub ↗

Returns a top-level HTTP handler for a Router. This adds behavior for URLs that don't match anything -- it handles the OPTIONS method as well as returning either a 404 or 405 for URLs that don't match a route.

(sc *ServerContext, privs handlerPrivs, serverType serverType, router *mux.Router)

Source from the content-addressed store, hash-verified

424// match anything -- it handles the OPTIONS method as well as returning either a 404 or 405
425// for URLs that don't match a route.
426func wrapRouter(sc *ServerContext, privs handlerPrivs, serverType serverType, router *mux.Router) http.Handler {
427 return http.HandlerFunc(func(response http.ResponseWriter, rq *http.Request) {
428 FixQuotedSlashes(rq)
429 var match mux.RouteMatch
430 if router.Match(rq, &match) {
431 router.ServeHTTP(response, rq)
432 } else {
433 // Log the request
434 h := newHandler(sc, privs, serverType, response, rq, handlerOptions{})
435 h.logRequestLine()
436
437 // Inject CORS if enabled and requested and not admin port
438 // What methods would have matched?
439 var options []string
440 var keyspace string
441 for _, method := range []string{"GET", "HEAD", "POST", "PUT", "DELETE"} {
442 found, matchedKeyspace := wouldMatch(router, rq, method)
443 if found {
444 options = append(options, method)
445 if keyspace == "" && matchedKeyspace != "" {
446 keyspace = matchedKeyspace
447 }
448 }
449 }
450
451 cors := sc.Config.API.CORS
452 dbName, _, _, _ := ParseKeyspace(keyspace)
453 if dbName != "" {
454 db, err := h.server.GetActiveDatabase(dbName)
455 if err == nil {
456 cors = db.CORS
457 }
458 }
459 if !cors.IsEmpty() && privs != adminPrivs && privs != metricsPrivs {
460 cors.AddResponseHeaders(rq, response)
461 }
462 if len(options) == 0 {
463 h.writeStatus(http.StatusNotFound, "unknown URL")
464 } else {
465 // Add CORS headers for OPTIONS request, since these are never registered by muxer.
466 response.Header().Add("Allow", strings.Join(options, ", "))
467 if privs != adminPrivs && cors != nil && len(rq.Header["Origin"]) > 0 {
468 response.Header().Add("Access-Control-Max-Age", strconv.Itoa(cors.MaxAge))
469 response.Header().Add("Access-Control-Allow-Methods", strings.Join(options, ", "))
470 }
471 if rq.Method != "OPTIONS" {
472 h.writeStatus(http.StatusMethodNotAllowed, "")
473 } else {
474 h.writeStatus(http.StatusNoContent, "")
475 }
476 }
477 h.logDuration(true)
478 }
479 })
480}
481
482func FixQuotedSlashes(rq *http.Request) {
483 uri := rq.RequestURI

Callers 4

CreatePublicHandlerFunction · 0.85
CreateAdminHandlerFunction · 0.85
CreateMetricHandlerFunction · 0.85
createDiagnosticHandlerFunction · 0.85

Calls 12

FixQuotedSlashesFunction · 0.85
newHandlerFunction · 0.85
wouldMatchFunction · 0.85
ParseKeyspaceFunction · 0.85
logRequestLineMethod · 0.80
GetActiveDatabaseMethod · 0.80
AddResponseHeadersMethod · 0.80
writeStatusMethod · 0.80
HeaderMethod · 0.80
logDurationMethod · 0.80
IsEmptyMethod · 0.45
AddMethod · 0.45

Tested by

no test coverage detected