|
@@ -381,18 +381,18 @@ void Server::registerEndpoints() {
|
|
|
auto authConfig = m_authMiddleware->getConfig();
|
|
auto authConfig = m_authMiddleware->getConfig();
|
|
|
std::string authMethod = "none";
|
|
std::string authMethod = "none";
|
|
|
switch (authConfig.authMethod) {
|
|
switch (authConfig.authMethod) {
|
|
|
- case AuthMethod::UNIX:
|
|
|
|
|
- authMethod = "unix";
|
|
|
|
|
|
|
+ case AuthMethod::PAM:
|
|
|
|
|
+ authMethod = "pam";
|
|
|
break;
|
|
break;
|
|
|
- case AuthMethod::JWT:
|
|
|
|
|
- authMethod = "jwt";
|
|
|
|
|
|
|
+ case AuthMethod::SHARED_KEY:
|
|
|
|
|
+ authMethod = "shared-key";
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
authMethod = "none";
|
|
authMethod = "none";
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
configJs << " authMethod: '" << authMethod << "',\n"
|
|
configJs << " authMethod: '" << authMethod << "',\n"
|
|
|
- << " authEnabled: " << (authConfig.authMethod != AuthMethod::NONE ? "true" : "false") << "\n";
|
|
|
|
|
|
|
+ << " authEnabled: " << (authConfig.authMethod != AuthMethod::PAM && authConfig.authMethod != AuthMethod::SHARED_KEY ? "true" : "false") << "\n";
|
|
|
} else {
|
|
} else {
|
|
|
configJs << " authMethod: 'none',\n"
|
|
configJs << " authMethod: 'none',\n"
|
|
|
<< " authEnabled: false\n";
|
|
<< " authEnabled: false\n";
|
|
@@ -449,13 +449,10 @@ void Server::registerEndpoints() {
|
|
|
// Check if authentication is enabled
|
|
// Check if authentication is enabled
|
|
|
if (m_authMiddleware) {
|
|
if (m_authMiddleware) {
|
|
|
auto authConfig = m_authMiddleware->getConfig();
|
|
auto authConfig = m_authMiddleware->getConfig();
|
|
|
- if (authConfig.authMethod != AuthMethod::NONE) {
|
|
|
|
|
|
|
+ if (authConfig.authMethod != AuthMethod::PAM && authConfig.authMethod != AuthMethod::SHARED_KEY) {
|
|
|
// Authentication is enabled, check if user is authenticated
|
|
// Authentication is enabled, check if user is authenticated
|
|
|
AuthContext authContext = m_authMiddleware->authenticate(req, res);
|
|
AuthContext authContext = m_authMiddleware->authenticate(req, res);
|
|
|
|
|
|
|
|
- // For Unix auth, we need to check if the user is authenticated
|
|
|
|
|
- // The authenticateUnix function will return a guest context for UI requests
|
|
|
|
|
- // when no Authorization header is present, but we still need to show the login page
|
|
|
|
|
if (!authContext.authenticated) {
|
|
if (!authContext.authenticated) {
|
|
|
// Check if this is a request for a static asset (JS, CSS, images)
|
|
// Check if this is a request for a static asset (JS, CSS, images)
|
|
|
// These should be served even without authentication to allow the login page to work
|
|
// These should be served even without authentication to allow the login page to work
|
|
@@ -507,12 +504,16 @@ void Server::registerEndpoints() {
|
|
|
</head>
|
|
</head>
|
|
|
<body>
|
|
<body>
|
|
|
<h1>Login Required</h1>
|
|
<h1>Login Required</h1>
|
|
|
- <p>Please enter your username to continue.</p>
|
|
|
|
|
|
|
+ <p>Please enter your credentials to continue.</p>
|
|
|
<form id="loginForm">
|
|
<form id="loginForm">
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
<label for="username">Username:</label>
|
|
<label for="username">Username:</label>
|
|
|
<input type="text" id="username" name="username" required>
|
|
<input type="text" id="username" name="username" required>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="form-group">
|
|
|
|
|
+ <label for="password">Password:</label>
|
|
|
|
|
+ <input type="password" id="password" name="password" required>
|
|
|
|
|
+ </div>
|
|
|
<button type="submit">Login</button>
|
|
<button type="submit">Login</button>
|
|
|
</form>
|
|
</form>
|
|
|
<div id="error" class="error"></div>
|
|
<div id="error" class="error"></div>
|
|
@@ -520,22 +521,23 @@ void Server::registerEndpoints() {
|
|
|
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
|
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
const username = document.getElementById('username').value;
|
|
const username = document.getElementById('username').value;
|
|
|
|
|
+ const password = document.getElementById('password').value;
|
|
|
const errorDiv = document.getElementById('error');
|
|
const errorDiv = document.getElementById('error');
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
const response = await fetch('/api/auth/login', {
|
|
const response = await fetch('/api/auth/login', {
|
|
|
method: 'POST',
|
|
method: 'POST',
|
|
|
- headers: { 'Content-Type': 'application/nlohmann::json' },
|
|
|
|
|
- body: JSON.stringify({ username })
|
|
|
|
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
+ body: JSON.stringify({ username, password })
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
if (response.ok) {
|
|
|
- const data = await response.nlohmann::json();
|
|
|
|
|
|
|
+ const data = await response.json();
|
|
|
localStorage.setItem('auth_token', data.token);
|
|
localStorage.setItem('auth_token', data.token);
|
|
|
- localStorage.setItem('unix_user', username);
|
|
|
|
|
|
|
+ localStorage.setItem('username', username);
|
|
|
window.location.reload();
|
|
window.location.reload();
|
|
|
} else {
|
|
} else {
|
|
|
- const error = await response.nlohmann::json();
|
|
|
|
|
|
|
+ const error = await response.json();
|
|
|
errorDiv.textContent = error.message || 'Login failed';
|
|
errorDiv.textContent = error.message || 'Login failed';
|
|
|
}
|
|
}
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
@@ -698,9 +700,11 @@ void Server::handleLogin(const httplib::Request& req, httplib::Response& res) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Check if using Unix authentication
|
|
|
|
|
- if (m_authMiddleware->getConfig().authMethod == AuthMethod::UNIX) {
|
|
|
|
|
- // For Unix auth, get username and password from request body
|
|
|
|
|
|
|
+ // Check authentication method and handle accordingly
|
|
|
|
|
+ auto authMethod = m_authMiddleware->getConfig().authMethod;
|
|
|
|
|
+
|
|
|
|
|
+ if (authMethod == AuthMethod::PAM) {
|
|
|
|
|
+ // For PAM auth, get username and password from request body
|
|
|
std::string username = requestJson.value("username", "");
|
|
std::string username = requestJson.value("username", "");
|
|
|
std::string password = requestJson.value("password", "");
|
|
std::string password = requestJson.value("password", "");
|
|
|
|
|
|
|
@@ -709,62 +713,60 @@ void Server::handleLogin(const httplib::Request& req, httplib::Response& res) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Check if PAM is enabled - if so, password is required
|
|
|
|
|
- if (m_userManager->isPamAuthEnabled() && password.empty()) {
|
|
|
|
|
- sendErrorResponse(res, "Password is required for Unix authentication", 400, "MISSING_PASSWORD", requestId);
|
|
|
|
|
|
|
+ if (password.empty()) {
|
|
|
|
|
+ sendErrorResponse(res, "Password is required for PAM authentication", 400, "MISSING_PASSWORD", requestId);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Authenticate Unix user (with or without password depending on PAM)
|
|
|
|
|
- auto result = m_userManager->authenticateUnix(username, password);
|
|
|
|
|
|
|
+ // Authenticate user with PAM
|
|
|
|
|
+ auto result = m_userManager->authenticatePam(username, password);
|
|
|
|
|
|
|
|
if (!result.success) {
|
|
if (!result.success) {
|
|
|
- sendErrorResponse(res, result.errorMessage, 401, "UNIX_AUTH_FAILED", requestId);
|
|
|
|
|
|
|
+ sendErrorResponse(res, result.errorMessage, 401, "PAM_AUTH_FAILED", requestId);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Generate simple token for Unix auth
|
|
|
|
|
- std::string token = "unix_token_" + std::to_string(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count()) + "_" + username;
|
|
|
|
|
|
|
+ // Generate simple token for PAM auth
|
|
|
|
|
+ std::string token = "pam_token_" + std::to_string(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count()) + "_" + username;
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"token", token},
|
|
{"token", token},
|
|
|
{"user", {{"id", result.userId}, {"username", result.username}, {"role", result.role}, {"permissions", result.permissions}}},
|
|
{"user", {{"id", result.userId}, {"username", result.username}, {"role", result.role}, {"permissions", result.permissions}}},
|
|
|
- {"message", "Unix authentication successful"}};
|
|
|
|
|
|
|
+ {"message", "PAM authentication successful"}};
|
|
|
|
|
|
|
|
sendJsonResponse(res, response);
|
|
sendJsonResponse(res, response);
|
|
|
return;
|
|
return;
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // For non-Unix auth, validate required fields
|
|
|
|
|
- if (!requestJson.contains("username") || !requestJson.contains("password")) {
|
|
|
|
|
- sendErrorResponse(res, "Missing username or password", 400, "MISSING_CREDENTIALS", requestId);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } else if (authMethod == AuthMethod::SHARED_KEY) {
|
|
|
|
|
+ // For shared key auth, get the shared key from request body
|
|
|
|
|
+ std::string sharedKey = requestJson.value("shared_key", "");
|
|
|
|
|
|
|
|
- std::string username = requestJson["username"];
|
|
|
|
|
- std::string password = requestJson["password"];
|
|
|
|
|
|
|
+ if (sharedKey.empty()) {
|
|
|
|
|
+ sendErrorResponse(res, "Missing shared_key", 400, "MISSING_SHARED_KEY", requestId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Authenticate user
|
|
|
|
|
- auto result = m_userManager->authenticateUser(username, password);
|
|
|
|
|
|
|
+ // Authenticate with shared key
|
|
|
|
|
+ auto result = m_userManager->authenticateSharedKey(sharedKey);
|
|
|
|
|
|
|
|
- if (!result.success) {
|
|
|
|
|
- sendErrorResponse(res, result.errorMessage, 401, "INVALID_CREDENTIALS", requestId);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!result.success) {
|
|
|
|
|
+ sendErrorResponse(res, result.errorMessage, 401, "SHARED_KEY_AUTH_FAILED", requestId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Generate JWT token if using JWT auth
|
|
|
|
|
- std::string token;
|
|
|
|
|
- if (m_authMiddleware->getConfig().authMethod == AuthMethod::JWT) {
|
|
|
|
|
- // For now, create a simple token (in a real implementation, use JWT)
|
|
|
|
|
- token = "token_" + std::to_string(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count()) + "_" + username;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // Generate simple token for shared key auth
|
|
|
|
|
+ std::string token = "shared_key_token_" + std::to_string(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
|
|
|
|
|
|
|
|
- nlohmann::json response = {
|
|
|
|
|
- {"token", token},
|
|
|
|
|
- {"user", {{"id", result.userId}, {"username", result.username}, {"role", result.role}, {"permissions", result.permissions}}},
|
|
|
|
|
- {"message", "Login successful"}};
|
|
|
|
|
|
|
+ nlohmann::json response = {
|
|
|
|
|
+ {"token", token},
|
|
|
|
|
+ {"user", {{"id", result.userId}, {"username", result.username}, {"role", result.role}, {"permissions", result.permissions}}},
|
|
|
|
|
+ {"message", "Shared key authentication successful"}};
|
|
|
|
|
|
|
|
- sendJsonResponse(res, response);
|
|
|
|
|
|
|
+ sendJsonResponse(res, response);
|
|
|
|
|
+ return;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ sendErrorResponse(res, "Authentication method not supported", 400, "UNSUPPORTED_AUTH_METHOD", requestId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
} catch (const std::exception& e) {
|
|
} catch (const std::exception& e) {
|
|
|
sendErrorResponse(res, std::string("Login failed: ") + e.what(), 500, "LOGIN_ERROR", requestId);
|
|
sendErrorResponse(res, std::string("Login failed: ") + e.what(), 500, "LOGIN_ERROR", requestId);
|
|
@@ -1368,7 +1370,8 @@ void Server::handleQueueStatus(const httplib::Request& /*req*/, httplib::Respons
|
|
|
{"start_time", startTime > 0 ? nlohmann::json(startTime) : nlohmann::json(nullptr)},
|
|
{"start_time", startTime > 0 ? nlohmann::json(startTime) : nlohmann::json(nullptr)},
|
|
|
{"end_time", endTime > 0 ? nlohmann::json(endTime) : nlohmann::json(nullptr)},
|
|
{"end_time", endTime > 0 ? nlohmann::json(endTime) : nlohmann::json(nullptr)},
|
|
|
{"position", job.position},
|
|
{"position", job.position},
|
|
|
- {"progress", job.progress}});
|
|
|
|
|
|
|
+ {"progress", job.progress},
|
|
|
|
|
+ {"model_load_progress", job.modelLoadProgress}});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
@@ -1457,7 +1460,7 @@ void Server::handleJobStatus(const httplib::Request& req, httplib::Response& res
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
- {"job", {{"id", jobInfo.id}, {"status", statusStr}, {"prompt", jobInfo.prompt}, {"queued_time", queuedTime}, {"start_time", startTime > 0 ? nlohmann::json(startTime) : nlohmann::json(nullptr)}, {"end_time", endTime > 0 ? nlohmann::json(endTime) : nlohmann::json(nullptr)}, {"position", jobInfo.position}, {"outputs", outputUrls}, {"error_message", jobInfo.errorMessage}, {"progress", jobInfo.progress}}}};
|
|
|
|
|
|
|
+ {"job", {{"id", jobInfo.id}, {"status", statusStr}, {"prompt", jobInfo.prompt}, {"queued_time", queuedTime}, {"start_time", startTime > 0 ? nlohmann::json(startTime) : nlohmann::json(nullptr)}, {"end_time", endTime > 0 ? nlohmann::json(endTime) : nlohmann::json(nullptr)}, {"position", jobInfo.position}, {"outputs", outputUrls}, {"error_message", jobInfo.errorMessage}, {"progress", jobInfo.progress}, {"model_load_progress", jobInfo.modelLoadProgress}}}};
|
|
|
|
|
|
|
|
sendJsonResponse(res, response);
|
|
sendJsonResponse(res, response);
|
|
|
} catch (const std::exception& e) {
|
|
} catch (const std::exception& e) {
|
|
@@ -1608,7 +1611,7 @@ void Server::handleDownloadOutput(const httplib::Request& req, httplib::Response
|
|
|
|
|
|
|
|
// Set response headers for proper browser handling
|
|
// Set response headers for proper browser handling
|
|
|
res.set_header("Content-Type", contentType);
|
|
res.set_header("Content-Type", contentType);
|
|
|
- res.set_header("Content-Length", std::to_string(fileContent.length()));
|
|
|
|
|
|
|
+ // res.set_header("Content-Length", std::to_string(fileContent.length())); -> http lib calculate it
|
|
|
res.set_header("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
|
|
res.set_header("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
|
|
|
res.set_header("Access-Control-Allow-Origin", "*"); // CORS for image access
|
|
res.set_header("Access-Control-Allow-Origin", "*"); // CORS for image access
|
|
|
// Uncomment if you want to force download instead of inline display:
|
|
// Uncomment if you want to force download instead of inline display:
|
|
@@ -1617,7 +1620,7 @@ void Server::handleDownloadOutput(const httplib::Request& req, httplib::Response
|
|
|
// Set the content
|
|
// Set the content
|
|
|
res.set_content(fileContent, contentType);
|
|
res.set_content(fileContent, contentType);
|
|
|
res.status = 200;
|
|
res.status = 200;
|
|
|
- LOG_DEBUG("Successfully server image: " + filename + " (" + std::to_string(fileContent.length()) + " bytes)");
|
|
|
|
|
|
|
+ LOG_DEBUG("Successfully served image: " + filename + " (" + std::to_string(fileContent.length()) + " bytes)");
|
|
|
|
|
|
|
|
} catch (const std::exception& e) {
|
|
} catch (const std::exception& e) {
|
|
|
LOG_ERROR("Exception in handleDownloadOutput: " + std::string(e.what()));
|
|
LOG_ERROR("Exception in handleDownloadOutput: " + std::string(e.what()));
|
|
@@ -3058,11 +3061,10 @@ void Server::handleText2Img(const httplib::Request& req, httplib::Response& res)
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"request_id", requestId},
|
|
{"request_id", requestId},
|
|
|
|
|
+ {"job_id", requestId},
|
|
|
{"status", "queued"},
|
|
{"status", "queued"},
|
|
|
{"message", "Text-to-image generation request queued successfully"},
|
|
{"message", "Text-to-image generation request queued successfully"},
|
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
|
- {"estimated_time_seconds", estimateGenerationTime(genRequest) / 1000},
|
|
|
|
|
- {"estimated_memory_mb", estimateMemoryUsage(genRequest) / (1024 * 1024)},
|
|
|
|
|
{"type", "text2img"},
|
|
{"type", "text2img"},
|
|
|
{"parameters", params}};
|
|
{"parameters", params}};
|
|
|
|
|
|
|
@@ -3214,11 +3216,10 @@ void Server::handleImg2Img(const httplib::Request& req, httplib::Response& res)
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"request_id", requestId},
|
|
{"request_id", requestId},
|
|
|
|
|
+ {"job_id", requestId},
|
|
|
{"status", "queued"},
|
|
{"status", "queued"},
|
|
|
{"message", "Image-to-image generation request queued successfully"},
|
|
{"message", "Image-to-image generation request queued successfully"},
|
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
|
- {"estimated_time_seconds", estimateGenerationTime(genRequest) / 1000},
|
|
|
|
|
- {"estimated_memory_mb", estimateMemoryUsage(genRequest) / (1024 * 1024)},
|
|
|
|
|
{"type", "img2img"},
|
|
{"type", "img2img"},
|
|
|
{"parameters", params}};
|
|
{"parameters", params}};
|
|
|
|
|
|
|
@@ -3359,11 +3360,10 @@ void Server::handleControlNet(const httplib::Request& req, httplib::Response& re
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"request_id", requestId},
|
|
{"request_id", requestId},
|
|
|
|
|
+ {"job_id", requestId},
|
|
|
{"status", "queued"},
|
|
{"status", "queued"},
|
|
|
{"message", "ControlNet generation request queued successfully"},
|
|
{"message", "ControlNet generation request queued successfully"},
|
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
|
- {"estimated_time_seconds", estimateGenerationTime(genRequest) / 1000},
|
|
|
|
|
- {"estimated_memory_mb", estimateMemoryUsage(genRequest) / (1024 * 1024)},
|
|
|
|
|
{"type", "controlnet"},
|
|
{"type", "controlnet"},
|
|
|
{"parameters", params}};
|
|
{"parameters", params}};
|
|
|
|
|
|
|
@@ -3446,6 +3446,7 @@ void Server::handleUpscale(const httplib::Request& req, httplib::Response& res)
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"request_id", requestId},
|
|
{"request_id", requestId},
|
|
|
|
|
+ {"job_id", requestId},
|
|
|
{"status", "queued"},
|
|
{"status", "queued"},
|
|
|
{"message", "Upscale request queued successfully"},
|
|
{"message", "Upscale request queued successfully"},
|
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
@@ -3626,11 +3627,10 @@ void Server::handleInpainting(const httplib::Request& req, httplib::Response& re
|
|
|
|
|
|
|
|
nlohmann::json response = {
|
|
nlohmann::json response = {
|
|
|
{"request_id", requestId},
|
|
{"request_id", requestId},
|
|
|
|
|
+ {"job_id", requestId},
|
|
|
{"status", "queued"},
|
|
{"status", "queued"},
|
|
|
{"message", "Inpainting generation request queued successfully"},
|
|
{"message", "Inpainting generation request queued successfully"},
|
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
{"queue_position", m_generationQueue->getQueueSize()},
|
|
|
- {"estimated_time_seconds", estimateGenerationTime(genRequest) / 1000},
|
|
|
|
|
- {"estimated_memory_mb", estimateMemoryUsage(genRequest) / (1024 * 1024)},
|
|
|
|
|
{"type", "inpainting"},
|
|
{"type", "inpainting"},
|
|
|
{"parameters", params}};
|
|
{"parameters", params}};
|
|
|
|
|
|
|
@@ -4493,7 +4493,7 @@ void Server::handleLoadModelById(const httplib::Request& req, httplib::Response&
|
|
|
// Validate that the identifier is a hash (10+ hexadecimal characters)
|
|
// Validate that the identifier is a hash (10+ hexadecimal characters)
|
|
|
if (modelIdentifier.length() < 10 ||
|
|
if (modelIdentifier.length() < 10 ||
|
|
|
!std::all_of(modelIdentifier.begin(), modelIdentifier.end(),
|
|
!std::all_of(modelIdentifier.begin(), modelIdentifier.end(),
|
|
|
- [](char c) { return std::isxdigit(c); })) {
|
|
|
|
|
|
|
+ [](char c) { return std::isxdigit(c); })) {
|
|
|
sendErrorResponse(res, "Invalid model identifier: must be a hash (10+ hexadecimal characters)", 400, "INVALID_MODEL_IDENTIFIER", requestId);
|
|
sendErrorResponse(res, "Invalid model identifier: must be a hash (10+ hexadecimal characters)", 400, "INVALID_MODEL_IDENTIFIER", requestId);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -5178,7 +5178,8 @@ void Server::logHttpAccess(const httplib::Request& req, const httplib::Response&
|
|
|
logMessage += " [" + endpoint + "]";
|
|
logMessage += " [" + endpoint + "]";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (res.status != 200) {
|
|
|
|
|
|
|
+ // non error http response codes
|
|
|
|
|
+ if (res.status > 299) {
|
|
|
LOG_ERROR("HTTP: " + logMessage);
|
|
LOG_ERROR("HTTP: " + logMessage);
|
|
|
} else {
|
|
} else {
|
|
|
LOG_INFO("HTTP: " + logMessage);
|
|
LOG_INFO("HTTP: " + logMessage);
|