ServeManagementHTTP dispatches an authenticated Management API request to a plugin route.
(w http.ResponseWriter, r *http.Request)
| 227 | |
| 228 | // ServeManagementHTTP dispatches an authenticated Management API request to a plugin route. |
| 229 | func (h *Host) ServeManagementHTTP(w http.ResponseWriter, r *http.Request) bool { |
| 230 | if h == nil || w == nil || r == nil || r.URL == nil { |
| 231 | return false |
| 232 | } |
| 233 | key := managementRouteKey(r.Method, r.URL.Path) |
| 234 | h.mu.Lock() |
| 235 | record, okRoute := h.managementRoutes[key] |
| 236 | h.mu.Unlock() |
| 237 | if !okRoute || record.route.Handler == nil || h.isPluginFused(record.pluginID) { |
| 238 | return false |
| 239 | } |
| 240 | |
| 241 | var body []byte |
| 242 | if r.Body != nil { |
| 243 | var errRead error |
| 244 | body, errRead = io.ReadAll(r.Body) |
| 245 | if errRead != nil { |
| 246 | http.Error(w, "failed to read plugin management request body", http.StatusBadRequest) |
| 247 | return true |
| 248 | } |
| 249 | if errClose := r.Body.Close(); errClose != nil { |
| 250 | log.Warnf("pluginhost: failed to close plugin management request body: %v", errClose) |
| 251 | } |
| 252 | } |
| 253 | r.Body = io.NopCloser(bytes.NewReader(body)) |
| 254 | |
| 255 | resp, errHandle := h.callManagementHandler(r.Context(), record, pluginapi.ManagementRequest{ |
| 256 | Method: r.Method, |
| 257 | Path: r.URL.Path, |
| 258 | Headers: cloneHeader(r.Header), |
| 259 | Query: cloneValues(r.URL.Query()), |
| 260 | Body: bytes.Clone(body), |
| 261 | }) |
| 262 | if errHandle != nil { |
| 263 | log.Warnf("pluginhost: management handler %s failed: %v", record.pluginID, errHandle) |
| 264 | http.Error(w, "plugin management handler failed", http.StatusBadGateway) |
| 265 | return true |
| 266 | } |
| 267 | resp.Body = escapeManagementResponseBody(resp) |
| 268 | |
| 269 | for keyHeader, values := range resp.Headers { |
| 270 | for _, value := range values { |
| 271 | w.Header().Add(keyHeader, value) |
| 272 | } |
| 273 | } |
| 274 | statusCode := resp.StatusCode |
| 275 | if statusCode == 0 { |
| 276 | statusCode = http.StatusOK |
| 277 | } |
| 278 | w.WriteHeader(statusCode) |
| 279 | if _, errWrite := w.Write(resp.Body); errWrite != nil { |
| 280 | log.Warnf("pluginhost: failed to write plugin management response: %v", errWrite) |
| 281 | } |
| 282 | return true |
| 283 | } |
| 284 | |
| 285 | // ServeResourceHTTP dispatches an unauthenticated browser-navigable resource request to a plugin route. |
| 286 | func (h *Host) ServeResourceHTTP(w http.ResponseWriter, r *http.Request) bool { |