func handleGpuAttest()

in src/local_gpu_verifier_http_service/cmd/local_gpu_verifier_http_service/main.go [138:258]


func handleGpuAttest(w http.ResponseWriter, r *http.Request, config Config) {
	start := time.Now()

	// Log incoming request details
	logger.Debug("Incoming GPU attestation request",
		"method", r.Method,
		"remote_addr", r.RemoteAddr,
		"headers", r.Header,
	)

	// Parse request ID from request header or generate a new one
	var requestIdFields = []string{"x-request-id", "x-ms-request-id", "request-id", "requestid"}
	var reqId string
	for _, key := range requestIdFields {
		if val := r.Header.Get(key); val != "" {
			reqId = val
			logger.Info("Found request ID in header", "request_id", reqId)
			break
		}
	}
	if reqId == "" {
		reqId = uuid.NewString()
		logger.Info("Assign new request ID", "request_id", reqId)
	}

	// Create a request-scoped logger that includes request_id in every log
	reqLogger := logger.With("request_id", reqId)

	// Also set x-ms-request-id in the response
	w.Header().Set("x-ms-request-id", reqId)

	// Optional nonce in POST request body or GET request query param
	var nonce string
	switch r.Method {
	case http.MethodGet:
		reqLogger.Info("GET request query", "params", r.URL.Query())
		nonce = r.URL.Query().Get("nonce")

	case http.MethodPost:
		// Log the request body
		bodyBytes, err := io.ReadAll(r.Body)
		if err != nil {
			reqLogger.Error("Failed to read request body", "error", err)
			http.Error(w, "Failed to read request body", http.StatusBadRequest)
			return
		}
		r.Body.Close()
		r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
		reqLogger.Info("POST request body", "body", string(bodyBytes))

		// Parse request body as JSON
		type gpuAttestRequest struct {
			Nonce string `json:"nonce"`
		}
		var attReq gpuAttestRequest
		if err := json.Unmarshal(bodyBytes, &attReq); err == nil {
			nonce = attReq.Nonce // might be empty if not present
		}

	default:
		reqLogger.Warn("Method not allowed", "method", r.Method)
		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
		return
	}

	// Log the nonce if present
	if nonce == "" {
		reqLogger.Info("No nonce provided in request")
	} else {
		reqLogger.Info("Nonce found in request", "nonce", nonce)
	}

	// Execute the GPU attestation command
	pythonPath := filepath.Join(config.VerifierRoot, "prodtest", "bin", "python3")
	cmd := exec.Command("sudo", pythonPath, "-m", "verifier.cc_admin")

	// Add nonce if provided
	if nonce != "" {
		// Check if the nonce is a valid hex string representing 32 bytes
		if !isValidHex(nonce, defaultNonceSize) {
			reqLogger.Error("Invalid nonce provided; must be a hex string representing 32 bytes", "nonce", nonce)
			http.Error(w, "Invalid args: nonce must be a 32-byte hex string", http.StatusBadRequest)
			return
		}
		cmd.Args = append(cmd.Args, "--nonce", nonce)
	}

	var outBuf, errBuf bytes.Buffer
	cmd.Stdout = &outBuf
	cmd.Stderr = &errBuf

	runErr := cmd.Run()
	combinedOutput := outBuf.String() + errBuf.String()
	reqLogger.Info("GPU Attestation Command output", "output", combinedOutput)

	if runErr != nil {
		reqLogger.Error("Error executing cc_admin", "error", runErr)
		respondJSON(w, http.StatusInternalServerError, combinedOutput, nil)
		reqLogger.Error("Completed /gpu_attest with HTTP 500", "duration", time.Since(start))
		return
	}

	// Determine success based on the output message
	isSuccess := strings.Contains(combinedOutput, config.SuccessStr)

	// Extract attestation token if available
	attToken := parseToken(combinedOutput)

	// Assign HTTP status code, 200 if attestation succeeded, 400 if failed
	statusCode := http.StatusOK
	if !isSuccess {
		statusCode = http.StatusBadRequest
	}

	// Respond with JSON output
	respondJSON(w, statusCode, combinedOutput, attToken)
	reqLogger.Info("Completed /gpu_attest",
		"duration", time.Since(start),
		"status_code", statusCode,
	)
}