feat: add HTTP/HTTPS URL input support for STP files
Add capability to download STP files directly from HTTP/HTTPS URLs in both CLI and HTTP server modes. Changes: - Add http_downloader module for downloading files from URLs - Extend GlobalConfig to track downloaded files - Update CLI parameter processing to detect and handle URLs - Enhance HTTP server to accept URL parameter alongside file upload - Implement automatic cleanup of downloaded temporary files - Add comprehensive usage documentation (USAGE.md) Usage examples: CLI: STP2GLB.exe --stp https://example.com/model.stp --glb output.glb API: curl -X POST http://localhost:8080/convert -F "url=https://example.com/model.stp" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bc9165803b
commit
096812b7d2
@ -72,6 +72,7 @@ set(SOURCES
|
|||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/config_utils.cpp
|
src/config_utils.cpp
|
||||||
src/http_server.cpp
|
src/http_server.cpp
|
||||||
|
src/http_downloader.cpp
|
||||||
src/geom/Color.cpp
|
src/geom/Color.cpp
|
||||||
src/cadit/occt/step_tree.cpp
|
src/cadit/occt/step_tree.cpp
|
||||||
src/cadit/occt/debug.cpp
|
src/cadit/occt/debug.cpp
|
||||||
@ -87,6 +88,7 @@ set(HEADERS
|
|||||||
src/config_utils.h
|
src/config_utils.h
|
||||||
src/config_structs.h
|
src/config_structs.h
|
||||||
src/http_server.h
|
src/http_server.h
|
||||||
|
src/http_downloader.h
|
||||||
src/geom/Color.h
|
src/geom/Color.h
|
||||||
src/cadit/occt/step_tree.h
|
src/cadit/occt/step_tree.h
|
||||||
src/cadit/occt/convert.h
|
src/cadit/occt/convert.h
|
||||||
|
|||||||
180
USAGE.md
Normal file
180
USAGE.md
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
# STP2GLB 使用说明
|
||||||
|
|
||||||
|
STP2GLB 支持两种运行模式:**CLI命令行模式** 和 **HTTP服务器模式**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CLI 命令行模式
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
|
||||||
|
#### 1. 本地文件转换
|
||||||
|
```bash
|
||||||
|
STP2GLB.exe --stp input.stp --glb output.glb
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. HTTP URL转换(新功能)
|
||||||
|
```bash
|
||||||
|
STP2GLB.exe --stp https://example.com/model.stp --glb output.glb
|
||||||
|
```
|
||||||
|
|
||||||
|
### 主要参数
|
||||||
|
|
||||||
|
| 参数 | 说明 | 默认值 | 范围 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| `--stp` | STP文件路径或HTTP/HTTPS URL(必填) | - | 本地路径或URL |
|
||||||
|
| `--glb` | 输出GLB文件路径(必填) | - | 本地路径 |
|
||||||
|
| `--lin-defl` | 线性偏差 | 0.5 | 0.0-1.0 |
|
||||||
|
| `--ang-defl` | 角度偏差 | 0.8 | 0.0-1.0 |
|
||||||
|
| `--rel-defl` | 相对偏差模式 | false | - |
|
||||||
|
| `--debug` | 调试模式(更详细的错误信息) | false | - |
|
||||||
|
| `--solid-only` | 仅转换实体 | false | - |
|
||||||
|
| `--max-geometry-num` | 最大几何体数量(0=无限制) | 0 | ≥0 |
|
||||||
|
| `--tessellation-timeout` | 网格化超时时间(秒) | 30 | >0 |
|
||||||
|
|
||||||
|
### 使用示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 本地文件转换,调整精度
|
||||||
|
STP2GLB.exe --stp model.stp --glb output.glb --lin-defl 0.1 --ang-defl 0.5
|
||||||
|
|
||||||
|
# 从URL下载并转换
|
||||||
|
STP2GLB.exe --stp http://example.com/files/part.step --glb result.glb
|
||||||
|
|
||||||
|
# 调试模式转换
|
||||||
|
STP2GLB.exe --stp model.stp --glb output.glb --debug
|
||||||
|
|
||||||
|
# 限制几何体数量
|
||||||
|
STP2GLB.exe --stp large.stp --glb output.glb --max-geometry-num 100
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HTTP 服务器模式
|
||||||
|
|
||||||
|
### 启动服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
STP2GLB.exe --server --port 8080 --host 0.0.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 服务器参数
|
||||||
|
|
||||||
|
| 参数 | 说明 | 默认值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `--server` | 启动服务器模式 | - |
|
||||||
|
| `--port` | 服务器端口 | 8080 |
|
||||||
|
| `--host` | 监听地址 | 0.0.0.0 |
|
||||||
|
| `--max-file-size` | 最大文件大小(MB) | 500 |
|
||||||
|
|
||||||
|
### API 端点
|
||||||
|
|
||||||
|
#### 1. 健康检查
|
||||||
|
```bash
|
||||||
|
GET /health
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"service": "STP2GLB"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 文件转换
|
||||||
|
```bash
|
||||||
|
POST /convert
|
||||||
|
```
|
||||||
|
|
||||||
|
**支持两种输入方式:**
|
||||||
|
|
||||||
|
##### 方式一:文件上传
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8080/convert \
|
||||||
|
-F "file=@model.stp" \
|
||||||
|
-F "linearDeflection=0.1" \
|
||||||
|
-F "angularDeflection=0.5"
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 方式二:HTTP URL(新功能)
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8080/convert \
|
||||||
|
-F "url=https://example.com/model.stp" \
|
||||||
|
-F "linearDeflection=0.1"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 转换参数
|
||||||
|
|
||||||
|
| 参数名 | 说明 | 默认值 |
|
||||||
|
|--------|------|--------|
|
||||||
|
| `file` | STP文件(multipart上传) | - |
|
||||||
|
| `url` | STP文件HTTP/HTTPS URL | - |
|
||||||
|
| `linearDeflection` | 线性偏差 | 0.5 |
|
||||||
|
| `angularDeflection` | 角度偏差 | 0.8 |
|
||||||
|
| `relativeDeflection` | 相对偏差(true/false) | false |
|
||||||
|
| `debug` | 调试模式(true/false) | false |
|
||||||
|
| `solidOnly` | 仅实体(true/false) | false |
|
||||||
|
| `maxGeometryNum` | 最大几何体数量 | 0 |
|
||||||
|
|
||||||
|
**注意:** `file` 和 `url` 二选一,`url` 优先级更高
|
||||||
|
|
||||||
|
### 响应示例
|
||||||
|
|
||||||
|
**成功响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"output_file": "1234567890_5678.glb",
|
||||||
|
"output_path": "./output/1234567890_5678.glb",
|
||||||
|
"conversion_time": 2.35
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Failed to download from URL: HTTP error: 404 Not Found"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **URL下载**:
|
||||||
|
- 仅支持HTTP和HTTPS协议
|
||||||
|
- URL必须直接指向.stp或.step文件
|
||||||
|
- 下载的临时文件会在转换完成后自动清理
|
||||||
|
|
||||||
|
2. **文件大小限制**:
|
||||||
|
- HTTP服务器模式默认限制500MB
|
||||||
|
- 可通过 `--max-file-size` 参数调整
|
||||||
|
|
||||||
|
3. **超时设置**:
|
||||||
|
- 默认网格化超时30秒
|
||||||
|
- 大型复杂模型建议增加超时时间
|
||||||
|
|
||||||
|
4. **调试模式**:
|
||||||
|
- 提供详细的STEP实体转换失败信息
|
||||||
|
- 会显著降低转换速度
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# CLI模式测试
|
||||||
|
STP2GLB.exe --stp https://example.com/test.stp --glb test.glb
|
||||||
|
|
||||||
|
# 服务器模式测试
|
||||||
|
STP2GLB.exe --server --port 8080
|
||||||
|
|
||||||
|
# 测试健康检查
|
||||||
|
curl http://localhost:8080/health
|
||||||
|
|
||||||
|
# 测试URL转换
|
||||||
|
curl -X POST http://localhost:8080/convert \
|
||||||
|
-F "url=https://example.com/model.stp"
|
||||||
|
```
|
||||||
@ -42,6 +42,10 @@ struct GlobalConfig {
|
|||||||
|
|
||||||
BuildConfig buildConfig;
|
BuildConfig buildConfig;
|
||||||
ServerConfig serverConfig;
|
ServerConfig serverConfig;
|
||||||
|
|
||||||
|
// HTTP download tracking
|
||||||
|
bool is_downloaded_from_url = false;
|
||||||
|
std::string original_url;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "config_structs.h"
|
#include "config_structs.h"
|
||||||
#include "cadit/occt/helpers.h"
|
#include "cadit/occt/helpers.h"
|
||||||
#include "CLI/App.hpp"
|
#include "CLI/App.hpp"
|
||||||
|
#include "http_downloader.h"
|
||||||
|
|
||||||
// Helper function to process filter names from input or file
|
// Helper function to process filter names from input or file
|
||||||
std::vector<std::string> process_filter_names(const std::string& input, const std::string& file_name)
|
std::vector<std::string> process_filter_names(const std::string& input, const std::string& file_name)
|
||||||
@ -79,19 +80,40 @@ GlobalConfig process_parameters(CLI::App& app)
|
|||||||
const auto filter_names_include = process_filter_names(filter_names_include_input, filter_names_file_include);
|
const auto filter_names_include = process_filter_names(filter_names_include_input, filter_names_file_include);
|
||||||
const auto filter_names_exclude = process_filter_names(filter_names_exclude_input, filter_names_file_exclude);
|
const auto filter_names_exclude = process_filter_names(filter_names_exclude_input, filter_names_file_exclude);
|
||||||
|
|
||||||
const std::string stpFilename = app.get_option("--stp")->results()[0];
|
std::string stpFilename = app.get_option("--stp")->results()[0];
|
||||||
const std::string glbFilename = app.get_option("--glb")->results()[0];
|
std::string glbFilename = app.get_option("--glb")->results()[0];
|
||||||
|
|
||||||
|
bool isDownloadedFromUrl = false;
|
||||||
|
std::string originalUrl;
|
||||||
|
std::filesystem::path stpFilePath;
|
||||||
|
std::filesystem::path glbFilePath;
|
||||||
|
|
||||||
|
// Check if input is HTTP URL
|
||||||
|
if (is_http_url(stpFilename)) {
|
||||||
|
std::cout << "Detected HTTP URL, downloading..." << std::endl;
|
||||||
|
try {
|
||||||
|
std::string downloaded_path = download_file_from_url(stpFilename, "./temp");
|
||||||
|
stpFilePath = std::filesystem::path(downloaded_path);
|
||||||
|
isDownloadedFromUrl = true;
|
||||||
|
originalUrl = stpFilename;
|
||||||
|
std::cout << "URL download completed: " << downloaded_path << std::endl;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
throw std::runtime_error("Failed to download from URL: " + std::string(ex.what()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stpFilePath = std::filesystem::path(stpFilename);
|
||||||
|
// Check if local file exists
|
||||||
|
if (!exists(stpFilePath)) {
|
||||||
|
throw std::invalid_argument("Invalid --stp filename \"" + stpFilename + "\". File does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glbFilePath = std::filesystem::path(glbFilename);
|
||||||
|
|
||||||
// Validate extensions
|
// Validate extensions
|
||||||
const bool isStpValid = endsWithCaseInsensitive(stpFilename, ".stp") || endsWithCaseInsensitive(stpFilename, ".step");
|
bool isStpValid = endsWithCaseInsensitive(stpFilePath.string(), ".stp") || endsWithCaseInsensitive(stpFilePath.string(), ".step");
|
||||||
const bool isGlbValid = endsWithCaseInsensitive(glbFilename, ".glb");
|
bool isGlbValid = endsWithCaseInsensitive(glbFilename, ".glb");
|
||||||
auto stpFilePath = std::filesystem::path(stpFilename);
|
|
||||||
auto glbFilePath = std::filesystem::path(glbFilename);
|
|
||||||
|
|
||||||
// check if file paths exists
|
|
||||||
if (!exists(stpFilePath)) {
|
|
||||||
throw std::invalid_argument("Invalid --stp filename \"" + stpFilename + "\". File does not exist.");
|
|
||||||
}
|
|
||||||
if (exists(glbFilePath)) {
|
if (exists(glbFilePath)) {
|
||||||
std::cout << "Warning: --glb filename \"" << glbFilename << "\" already exists and will be overwritten.\n";
|
std::cout << "Warning: --glb filename \"" << glbFilename << "\" already exists and will be overwritten.\n";
|
||||||
}
|
}
|
||||||
@ -106,7 +128,7 @@ GlobalConfig process_parameters(CLI::App& app)
|
|||||||
|
|
||||||
// Create configuration
|
// Create configuration
|
||||||
return {
|
return {
|
||||||
.stpFile = stpFilename,
|
.stpFile = stpFilePath,
|
||||||
.glbFile = glbFilename,
|
.glbFile = glbFilename,
|
||||||
.debug_mode = app.get_option("--debug")->as<bool>(),
|
.debug_mode = app.get_option("--debug")->as<bool>(),
|
||||||
.linearDeflection = app.get_option("--lin-defl")->as<double>(),
|
.linearDeflection = app.get_option("--lin-defl")->as<double>(),
|
||||||
@ -126,6 +148,8 @@ GlobalConfig process_parameters(CLI::App& app)
|
|||||||
.host = app.get_option("--host")->as<std::string>(),
|
.host = app.get_option("--host")->as<std::string>(),
|
||||||
.max_file_size_mb = app.get_option("--max-file-size")->as<size_t>(),
|
.max_file_size_mb = app.get_option("--max-file-size")->as<size_t>(),
|
||||||
.temp_dir = "./temp"
|
.temp_dir = "./temp"
|
||||||
}
|
},
|
||||||
|
.is_downloaded_from_url = isDownloadedFromUrl,
|
||||||
|
.original_url = originalUrl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/config_utils.h
Normal file
15
src/config_utils.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by ofskrand on 13.01.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CONFIG_UTILS_H
|
||||||
|
#define CONFIG_UTILS_H
|
||||||
|
#include <CLI/App.hpp>
|
||||||
|
|
||||||
|
#include "config_structs.h"
|
||||||
|
|
||||||
|
|
||||||
|
GlobalConfig process_parameters(CLI::App& app);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CONFIG_UTILS_H
|
||||||
120
src/http_downloader.cpp
Normal file
120
src/http_downloader.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include "http_downloader.h"
|
||||||
|
#include "third_party/httplib.h"
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
bool is_http_url(const std::string& path) {
|
||||||
|
std::string lower_path = path;
|
||||||
|
std::transform(lower_path.begin(), lower_path.end(), lower_path.begin(), ::tolower);
|
||||||
|
return lower_path.substr(0, 7) == "http://" || lower_path.substr(0, 8) == "https://";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generate_download_filename(const std::string& extension) {
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
||||||
|
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
std::uniform_int_distribution<> dis(1000, 9999);
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "download_" << timestamp << "_" << dis(gen) << extension;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string download_file_from_url(const std::string& url, const std::string& temp_dir) {
|
||||||
|
std::cout << "Downloading file: " << url << std::endl;
|
||||||
|
|
||||||
|
// Ensure temp directory exists
|
||||||
|
fs::create_directories(temp_dir);
|
||||||
|
|
||||||
|
// Parse URL
|
||||||
|
size_t protocol_end = url.find("://");
|
||||||
|
if (protocol_end == std::string::npos) {
|
||||||
|
throw std::runtime_error("Invalid URL format: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string protocol = url.substr(0, protocol_end);
|
||||||
|
std::string remaining = url.substr(protocol_end + 3);
|
||||||
|
|
||||||
|
size_t host_end = remaining.find('/');
|
||||||
|
std::string host;
|
||||||
|
std::string path;
|
||||||
|
|
||||||
|
if (host_end == std::string::npos) {
|
||||||
|
host = remaining;
|
||||||
|
path = "/";
|
||||||
|
} else {
|
||||||
|
host = remaining.substr(0, host_end);
|
||||||
|
path = remaining.substr(host_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract file extension from URL path
|
||||||
|
std::string extension = ".stp";
|
||||||
|
size_t last_dot = path.find_last_of('.');
|
||||||
|
if (last_dot != std::string::npos) {
|
||||||
|
std::string url_ext = path.substr(last_dot);
|
||||||
|
// Ensure it's a STP-related extension
|
||||||
|
std::string lower_ext = url_ext;
|
||||||
|
std::transform(lower_ext.begin(), lower_ext.end(), lower_ext.begin(), ::tolower);
|
||||||
|
if (lower_ext == ".stp" || lower_ext == ".step") {
|
||||||
|
extension = lower_ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate local filename
|
||||||
|
std::string filename = generate_download_filename(extension);
|
||||||
|
fs::path local_path = fs::path(temp_dir) / filename;
|
||||||
|
|
||||||
|
std::cout << "Target host: " << host << std::endl;
|
||||||
|
std::cout << "Request path: " << path << std::endl;
|
||||||
|
std::cout << "Saving to: " << local_path << std::endl;
|
||||||
|
|
||||||
|
// Create HTTP client
|
||||||
|
std::unique_ptr<httplib::Client> cli;
|
||||||
|
|
||||||
|
if (protocol == "https") {
|
||||||
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
|
cli = std::make_unique<httplib::SSLClient>(host);
|
||||||
|
#else
|
||||||
|
throw std::runtime_error("HTTPS not supported in this build");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cli = std::make_unique<httplib::Client>(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set timeout
|
||||||
|
cli->set_read_timeout(300, 0); // 300 seconds
|
||||||
|
cli->set_write_timeout(300, 0);
|
||||||
|
|
||||||
|
// Execute GET request
|
||||||
|
auto res = cli->Get(path.c_str());
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
throw std::runtime_error("HTTP request failed: " + httplib::to_string(res.error()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res->status != 200) {
|
||||||
|
throw std::runtime_error("HTTP error: " + std::to_string(res->status) + " " + res->reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to local file
|
||||||
|
std::ofstream ofs(local_path, std::ios::binary);
|
||||||
|
if (!ofs) {
|
||||||
|
throw std::runtime_error("Cannot create file: " + local_path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs.write(res->body.c_str(), res->body.size());
|
||||||
|
ofs.close();
|
||||||
|
|
||||||
|
std::cout << "Download completed, file size: " << res->body.size() << " bytes" << std::endl;
|
||||||
|
|
||||||
|
return local_path.string();
|
||||||
|
}
|
||||||
13
src/http_downloader.h
Normal file
13
src/http_downloader.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef HTTP_DOWNLOADER_H
|
||||||
|
#define HTTP_DOWNLOADER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// 判断路径是否为HTTP/HTTPS URL
|
||||||
|
bool is_http_url(const std::string& path);
|
||||||
|
|
||||||
|
// 从URL下载文件到指定目录,返回本地文件路径
|
||||||
|
// 下载失败会抛出std::runtime_error异常
|
||||||
|
std::string download_file_from_url(const std::string& url, const std::string& temp_dir);
|
||||||
|
|
||||||
|
#endif // HTTP_DOWNLOADER_H
|
||||||
@ -2,6 +2,7 @@
|
|||||||
#include "third_party/httplib.h"
|
#include "third_party/httplib.h"
|
||||||
#include "cadit/occt/convert.h"
|
#include "cadit/occt/convert.h"
|
||||||
#include "cadit/occt/debug.h"
|
#include "cadit/occt/debug.h"
|
||||||
|
#include "http_downloader.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -48,13 +49,30 @@ void start_http_server(const GlobalConfig& base_config) {
|
|||||||
svr.Post("/convert", [&base_config](const httplib::Request& req, httplib::Response& res) {
|
svr.Post("/convert", [&base_config](const httplib::Request& req, httplib::Response& res) {
|
||||||
std::cout << "Received conversion request" << "\n";
|
std::cout << "Received conversion request" << "\n";
|
||||||
|
|
||||||
if (!req.is_multipart_form_data() || !req.form.has_file("file")) {
|
bool use_url = false;
|
||||||
|
std::string url_param;
|
||||||
|
|
||||||
|
// Check if URL parameter is provided
|
||||||
|
if (req.form.has_field("url")) {
|
||||||
|
url_param = req.form.get_field("url");
|
||||||
|
if (!url_param.empty() && is_http_url(url_param)) {
|
||||||
|
use_url = true;
|
||||||
|
std::cout << "Using URL parameter: " << url_param << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no URL, check file upload
|
||||||
|
if (!use_url && (!req.is_multipart_form_data() || !req.form.has_file("file"))) {
|
||||||
res.status = 400;
|
res.status = 400;
|
||||||
res.set_content("{\"error\":\"No file uploaded. Use 'file' field.\"}", "application/json");
|
res.set_content("{\"error\":\"No file uploaded or URL provided. Use 'file' field or 'url' parameter.\"}", "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& file = req.form.get_file("file", 0);
|
std::string file_content;
|
||||||
|
if (!use_url) {
|
||||||
|
const auto& file = req.form.get_file("file", 0);
|
||||||
|
file_content = file.content;
|
||||||
|
}
|
||||||
|
|
||||||
GlobalConfig config = base_config;
|
GlobalConfig config = base_config;
|
||||||
|
|
||||||
@ -81,13 +99,22 @@ void start_http_server(const GlobalConfig& base_config) {
|
|||||||
std::string stp_filename = base_filename + ".stp";
|
std::string stp_filename = base_filename + ".stp";
|
||||||
std::string glb_filename = base_filename + ".glb";
|
std::string glb_filename = base_filename + ".glb";
|
||||||
|
|
||||||
fs::path stp_path = fs::path(config.serverConfig.temp_dir) / stp_filename;
|
fs::path stp_path;
|
||||||
fs::path glb_path = fs::path(config.serverConfig.output_dir) / glb_filename;
|
fs::path glb_path = fs::path(config.serverConfig.output_dir) / glb_filename;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::ofstream ofs(stp_path, std::ios::binary);
|
// If using URL, download file; otherwise save uploaded file
|
||||||
ofs.write(file.content.c_str(), file.content.size());
|
if (use_url) {
|
||||||
ofs.close();
|
std::string downloaded_path = download_file_from_url(url_param, config.serverConfig.temp_dir);
|
||||||
|
stp_path = fs::path(downloaded_path);
|
||||||
|
config.is_downloaded_from_url = true;
|
||||||
|
config.original_url = url_param;
|
||||||
|
} else {
|
||||||
|
stp_path = fs::path(config.serverConfig.temp_dir) / stp_filename;
|
||||||
|
std::ofstream ofs(stp_path, std::ios::binary);
|
||||||
|
ofs.write(file_content.c_str(), file_content.size());
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
|
||||||
config.stpFile = stp_path;
|
config.stpFile = stp_path;
|
||||||
config.glbFile = glb_path;
|
config.glbFile = glb_path;
|
||||||
|
|||||||
12
src/main.cpp
12
src/main.cpp
@ -140,5 +140,17 @@ int main(int argc, char* argv[])
|
|||||||
const double seconds = static_cast<double>(duration.count()) / 1e6;
|
const double seconds = static_cast<double>(duration.count()) / 1e6;
|
||||||
std::cout << "STP converted in: " << std::fixed << std::setprecision(2) << seconds << " seconds" << "\n";
|
std::cout << "STP converted in: " << std::fixed << std::setprecision(2) << seconds << " seconds" << "\n";
|
||||||
|
|
||||||
|
// Clean up downloaded temporary file
|
||||||
|
if (config.is_downloaded_from_url) {
|
||||||
|
try {
|
||||||
|
if (std::filesystem::exists(config.stpFile)) {
|
||||||
|
std::filesystem::remove(config.stpFile);
|
||||||
|
std::cout << "Cleaned up downloaded file: " << config.stpFile << "\n";
|
||||||
|
}
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::cerr << "Warning: Failed to clean up downloaded file: " << ex.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user