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,
)
}