github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/servermaster/http.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package servermaster 15 16 import ( 17 "net/http" 18 "net/http/pprof" 19 "strings" 20 21 "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 22 "github.com/pingcap/failpoint" 23 "github.com/pingcap/tiflow/engine/pkg/openapi" 24 "github.com/pingcap/tiflow/engine/pkg/promutil" 25 "github.com/pingcap/tiflow/pkg/util" 26 ) 27 28 // registerRoutes registers the routes for the HTTP server. 29 func registerRoutes(router *http.ServeMux, grpcMux *runtime.ServeMux, forwardJobAPI http.HandlerFunc) { 30 // Swagger UI 31 router.HandleFunc("/swagger", openapi.SwaggerUI) 32 router.HandleFunc("/swagger/v1/openapiv2.json", openapi.SwaggerAPIv1) 33 34 // Job API 35 // There are two types of job API: 36 // 1. The job API implemented by the framework. 37 // 2. The job API implemented by the job master. 38 // Both of them are registered in the same "/api/v1/jobs/" path. 39 // The job API implemented by the job master is registered in the "/api/v1/jobs/{job_id}/". 40 // But framework has a special APIs cancel will register in the "/api/v1/jobs/{job_id}/" path too. 41 // So we first check whether the request should be forwarded to the job master. 42 // If yes, forward the request to the job master. Otherwise, delegate the request to the framework. 43 router.HandleFunc("/api/v1/", func(w http.ResponseWriter, r *http.Request) { 44 if shouldForwardJobAPI(r) { 45 forwardJobAPI(w, r) 46 } else { 47 grpcMux.ServeHTTP(w, r) 48 } 49 }) 50 51 // pprof debug API 52 router.HandleFunc("/debug/pprof/", pprof.Index) 53 router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 54 router.HandleFunc("/debug/pprof/profile", pprof.Profile) 55 router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 56 router.HandleFunc("/debug/pprof/trace", pprof.Trace) 57 router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) 58 59 // Failpoint API 60 if util.FailpointBuild { 61 // `http.StripPrefix` is needed because `failpoint.HttpHandler` assumes that it handles the prefix `/`. 62 router.Handle("/debug/fail/", http.StripPrefix("/debug/fail", &failpoint.HttpHandler{})) 63 } 64 65 // Prometheus metrics API 66 router.Handle("/metrics", promutil.HTTPHandlerForMetric()) 67 } 68 69 // shouldForwardJobAPI indicates whether the request should be forwarded to the job master. 70 func shouldForwardJobAPI(r *http.Request) bool { 71 if !strings.HasPrefix(r.URL.Path, openapi.JobAPIPrefix) { 72 return false 73 } 74 apiPath := strings.TrimPrefix(r.URL.Path, openapi.JobAPIPrefix) 75 fields := strings.SplitN(apiPath, "/", 2) 76 if len(fields) != 2 { 77 return false 78 } 79 // cancel is implemented by framework, 80 // don't forward them to the job master. 81 if fields[1] == "cancel" { 82 return false 83 } 84 return true 85 }