From 1193b5ccf46b45a6ad4e4d88d59cd8ba4c7db27c Mon Sep 17 00:00:00 2001 From: SkrinVex Date: Thu, 22 Jan 2026 21:31:57 +0500 Subject: [PATCH] 5.0.1 update --- DOCUMENTATION.md | 468 +++++++++++++++++++++++++++++- README.md | 29 +- doc/FastAPI.md | 141 +++++++++ examples/api_client.fox | 41 +++ examples/fastapi_demo.fox | 103 +++++++ examples/fastapi_server.fox | 68 +++++ examples/http_client_examples.fox | 42 +++ examples/http_demo.fox | 36 +++ examples/simple_http.fox | 60 ++++ src/AST.h | 39 +++ src/Lexer.cpp | 5 + src/Parser.cpp | 49 ++++ src/Token.h | 3 + src/net.fox | 265 ++++++++--------- test/test_fastapi.fox | 28 ++ test/test_http_methods.fox | 36 +++ 16 files changed, 1271 insertions(+), 142 deletions(-) create mode 100644 doc/FastAPI.md create mode 100644 examples/api_client.fox create mode 100644 examples/fastapi_demo.fox create mode 100644 examples/fastapi_server.fox create mode 100644 examples/http_client_examples.fox create mode 100644 examples/http_demo.fox create mode 100644 examples/simple_http.fox create mode 100644 test/test_fastapi.fox create mode 100644 test/test_http_methods.fox diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 6d4fd06..a3fb73e 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -9,7 +9,8 @@ 6. [Массивы](#6-массивы) 7. [Модули и Импорт](#7-модули-и-импорт) 8. [Встроенные функции](#8-встроенные-функции) -9. [Современный синтаксис](#9-современный-синтаксис) +9. [Сетевые возможности и HTTP](#9-сетевые-возможности-и-http) +10. [Современный синтаксис](#10-современный-синтаксис) --- @@ -309,6 +310,15 @@ FoxLang поддерживает импорт внешних модулей. | `httpput(url, data, content_type)` | HTTP PUT с указанием типа контента. | `httpput(url, data, "text/plain");` | | `httpdelete(url)` | Выполняет HTTP DELETE запрос. | `string response = httpdelete(url);` | +### FastAPI-подобный веб-сервер +| Функция | Описание | Пример | +| --- | --- | --- | +| `server_start(port)` | Запускает HTTP сервер на указанном порту. | `string result = server_start(8080);` | +| `server_stop()` | Останавливает HTTP сервер. | `string result = server_stop();` | +| `route_get(path, handler)` | Регистрирует GET маршрут с обработчиком. | `string result = route_get("/api", "handler");` | +| `route_post(path, handler)` | Регистрирует POST маршрут с обработчиком. | `string result = route_post("/users", "create");` | +| `send_response(data)` | Отправляет ответ клиенту (используется в обработчиках). | `send_response("{\"status\":\"ok\"}");` | + ### Работа со строками и JSON | Функция | Описание | Пример | | --- | --- | --- | @@ -330,7 +340,461 @@ FoxLang поддерживает импорт внешних модулей. --- -## 9. Современный синтаксис +## 9. Сетевые возможности и HTTP + +FoxLang предоставляет мощные возможности для работы с сетью и HTTP запросами. Поддерживаются все основные HTTP методы и создание веб-серверов. + +### HTTP клиент - Отправка запросов + +#### GET запросы +```cpp +// Простой GET запрос +string response = httpget("https://api.github.com/users/octocat"); +print("Response: " + response); + +// Получение JSON данных +string user_data = httpget("https://jsonplaceholder.typicode.com/users/1"); +print("User: " + user_data); +``` + +#### POST запросы +```cpp +// POST с JSON данными +string json_data = "{\"name\":\"John\",\"email\":\"john@example.com\"}"; +string response = httppost("https://jsonplaceholder.typicode.com/users", json_data, "application/json"); +print("Created: " + response); + +// POST без указания Content-Type (по умолчанию application/json) +string simple_post = httppost("https://httpbin.org/post", "{\"test\":\"data\"}"); +print("POST result: " + simple_post); +``` + +#### PUT запросы (обновление данных) +```cpp +// Обновление существующего ресурса +string update_data = "{\"name\":\"John Updated\",\"email\":\"john.new@example.com\"}"; +string updated = httpput("https://jsonplaceholder.typicode.com/users/1", update_data, "application/json"); +print("Updated: " + updated); +``` + +#### DELETE запросы (удаление данных) +```cpp +// Удаление ресурса +string deleted = httpdelete("https://jsonplaceholder.typicode.com/users/1"); +print("Deleted: " + deleted); +``` + +### Работа с различными API + +#### Пример работы с REST API +```cpp +void work_with_api() { + string base_url = "https://jsonplaceholder.typicode.com"; + + // Получить список пользователей + string users = httpget(base_url + "/users"); + print("All users: " + users); + + // Получить конкретного пользователя + string user = httpget(base_url + "/users/1"); + print("User 1: " + user); + + // Создать новый пост + string new_post = "{\"title\":\"My Post\",\"body\":\"Post content\",\"userId\":1}"; + string created = httppost(base_url + "/posts", new_post, "application/json"); + print("Created post: " + created); + + // Обновить пост + string updated_post = "{\"id\":1,\"title\":\"Updated Post\",\"body\":\"New content\",\"userId\":1}"; + string updated = httpput(base_url + "/posts/1", updated_post, "application/json"); + print("Updated post: " + updated); + + // Удалить пост + string deleted = httpdelete(base_url + "/posts/1"); + print("Deleted post: " + deleted); +} + +work_with_api(); +``` + +### FastAPI-подобный веб-сервер + +FoxLang поддерживает создание веб-серверов через библиотеку `net.fox`: + +#### Быстрый старт сервера +```cpp +include("src/net.fox"); + +// Обработчики маршрутов +void api_home() { + json_response("{\"message\":\"Welcome to FoxLang API!\",\"version\":\"5.0.1\"}"); +} + +void api_users() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]}"); +} + +void create_user() { + json_response("{\"message\":\"User created\",\"id\":3,\"name\":\"Charlie\"}"); +} + +// Запуск сервера +void main() { + // Старт сервера на порту 8080 + start_server(8080); + + // Регистрация маршрутов + register_get("/", "api_home"); + register_get("/users", "api_users"); + register_post("/users", "create_user"); + + print("🚀 Server running on http://localhost:8080"); + print("Available endpoints:"); + print(" GET / - Welcome message"); + print(" GET /users - List users"); + print(" POST /users - Create user"); +} + +main(); +``` + +#### Встроенные серверные функции + +| Функция | Описание | Пример | +|---------|----------|---------| +| `server_start(port)` | Запускает HTTP сервер | `server_start(8080);` | +| `server_stop()` | Останавливает сервер | `server_stop();` | +| `route_get(path, handler)` | Регистрирует GET маршрут | `route_get("/api", "handler");` | +| `route_post(path, handler)` | Регистрирует POST маршрут | `route_post("/users", "create");` | +| `send_response(data)` | Отправляет ответ клиенту | `send_response("{\"status\":\"ok\"}");` | + +#### Библиотека net.fox - Высокоуровневые функции + +```cpp +include("src/net.fox"); + +// Удобные функции из библиотеки: +start_server(8080); // Запуск сервера +register_get("/", "handler"); // Регистрация GET маршрута +register_post("/api", "create"); // Регистрация POST маршрута +json_response("{\"key\":\"value\"}"); // JSON ответ +text_response("Hello World"); // Текстовый ответ +``` + +### Практические примеры + +#### HTTP клиент для тестирования API +```cpp +void test_external_apis() { + // Тест GitHub API + string github_user = httpget("https://api.github.com/users/octocat"); + print("GitHub user: " + github_user); + + // Тест погодного API (пример) + string weather = httpget("https://api.openweathermap.org/data/2.5/weather?q=Moscow&appid=YOUR_KEY"); + print("Weather: " + weather); + + // Отправка данных в webhook + string webhook_data = "{\"text\":\"Hello from FoxLang!\"}"; + string webhook_response = httppost("https://hooks.slack.com/services/YOUR/WEBHOOK/URL", webhook_data); + print("Webhook sent: " + webhook_response); +} +``` + +#### Простой API сервер с обработкой данных +```cpp +include("src/net.fox"); + +global array users 10; +global int user_count = 0; + +void get_users() { + string users_json = "{\"users\":["; + int i = 0; + while (i < user_count) { + if (i > 0) { + users_json = users_json + ","; + } + users_json = users_json + "{\"id\":" + i + ",\"name\":\"" + get(users, i) + "\"}"; + i = i + 1; + } + users_json = users_json + "],\"total\":" + user_count + "}"; + json_response(users_json); +} + +void add_user() { + if (user_count < 10) { + set(users, user_count, "User" + user_count); + user_count = user_count + 1; + json_response("{\"message\":\"User added\",\"id\":" + (user_count - 1) + "}"); + } else { + json_response("{\"error\":\"Maximum users reached\"}"); + } +} + +void main() { + start_server(3000); + register_get("/users", "get_users"); + register_post("/users", "add_user"); + print("API server ready on http://localhost:3000"); +} + +main(); +``` + +### Обработка ошибок и проверки + +```cpp +void safe_http_request(string url) { + string response = httpget(url); + + if (response == "") { + print("❌ Request failed: " + url); + return; + } + + // Проверка на успешный ответ (простая проверка) + if (str_contains(response, "error") || str_contains(response, "Error")) { + print("⚠️ API returned error: " + response); + return; + } + + print("✅ Success: " + response); +} + +// Использование +safe_http_request("https://api.github.com/users/nonexistent"); +safe_http_request("https://api.github.com/users/octocat"); +``` + +### Краткий справочник HTTP функций + +#### 📋 Все встроенные HTTP функции +| Функция | Описание | Пример | +|---------|----------|---------| +| `httpget(url)` | GET запрос | `httpget("https://api.com/users")` | +| `httppost(url, data)` | POST запрос | `httppost(url, "{\"key\":\"value\"}")` | +| `httppost(url, data, type)` | POST с Content-Type | `httppost(url, data, "application/json")` | +| `httpput(url, data)` | PUT запрос | `httpput(url, "{\"updated\":true}")` | +| `httpput(url, data, type)` | PUT с Content-Type | `httpput(url, data, "text/plain")` | +| `httpdelete(url)` | DELETE запрос | `httpdelete("https://api.com/item/1")` | + +#### 🚀 Серверные функции (встроенные) +| Функция | Описание | Пример | +|---------|----------|---------| +| `server_start(port)` | Запуск сервера | `server_start(8080)` | +| `server_stop()` | Остановка сервера | `server_stop()` | +| `route_get(path, handler)` | GET маршрут | `route_get("/api", "handler")` | +| `route_post(path, handler)` | POST маршрут | `route_post("/users", "create")` | +| `send_response(data)` | Отправка ответа | `send_response("{\"ok\":true}")` | + +#### 📚 Библиотека net.fox (высокоуровневые функции) +| Функция | Описание | Пример | +|---------|----------|---------| +| `start_server(port)` | Удобный запуск сервера | `start_server(8080)` | +| `register_get(path, handler)` | Регистрация GET | `register_get("/", "home")` | +| `register_post(path, handler)` | Регистрация POST | `register_post("/api", "create")` | +| `json_response(json)` | JSON ответ | `json_response("{\"status\":\"ok\"}")` | +| `text_response(text)` | Текстовый ответ | `text_response("Hello World")` | + +#### ⚡ Быстрые примеры + +**HTTP клиент:** +```cpp +// GET +string user = httpget("https://api.github.com/users/octocat"); + +// POST +string data = "{\"name\":\"John\"}"; +string created = httppost("https://api.com/users", data, "application/json"); + +// PUT +string updated = httpput("https://api.com/users/1", "{\"name\":\"Jane\"}"); + +// DELETE +string deleted = httpdelete("https://api.com/users/1"); +``` + +**Веб-сервер:** +```cpp +include("src/net.fox"); + +void api_home() { + json_response("{\"message\":\"Hello FoxLang API!\"}"); +} + +void main() { + start_server(8080); + register_get("/", "api_home"); + print("🚀 Server: http://localhost:8080"); +} + +main(); +``` + +#### 🧪 Компиляция и запуск +```bash +# Компиляция +cd src && g++ -std=c++17 main.cpp Lexer.cpp Parser.cpp -o foxlang + +# Запуск HTTP клиента +./foxlang examples/http_demo.fox + +# Запуск веб-сервера +./foxlang examples/fastapi_demo.fox +``` + +### Расширенные примеры использования + +#### Webhook отправка +```cpp +void send_notification(string message) { + string webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"; + string payload = "{\"text\":\"" + message + "\"}"; + string response = httppost(webhook_url, payload); + + if (response != "") { + print("✅ Notification sent"); + } else { + print("❌ Failed to send notification"); + } +} + +send_notification("Hello from FoxLang!"); +``` + +#### Полный REST API сервер с данными +```cpp +include("src/net.fox"); + +global array users 10; +global int user_count = 0; + +void get_users() { + string users_json = "{\"users\":["; + int i = 0; + while (i < user_count) { + if (i > 0) { + users_json = users_json + ","; + } + users_json = users_json + "{\"id\":" + i + ",\"name\":\"" + get(users, i) + "\"}"; + i = i + 1; + } + users_json = users_json + "],\"total\":" + user_count + "}"; + json_response(users_json); +} + +void add_user() { + if (user_count < 10) { + set(users, user_count, "User" + user_count); + user_count = user_count + 1; + json_response("{\"message\":\"User added\",\"id\":" + (user_count - 1) + "}"); + } else { + json_response("{\"error\":\"Maximum users reached\"}"); + } +} + +void main() { + start_server(3000); + register_get("/users", "get_users"); + register_post("/users", "add_user"); + print("API server ready on http://localhost:3000"); +} + +main(); +``` + +#### Тестирование множественных API +```cpp +void test_multiple_apis() { + print("🧪 Testing multiple APIs:"); + + // GitHub API + string github = httpget("https://api.github.com/users/octocat"); + print("GitHub API: " + github); + + // JSONPlaceholder API + string posts = httpget("https://jsonplaceholder.typicode.com/posts/1"); + print("JSONPlaceholder: " + posts); + + // HTTPBin для тестирования POST + string test_post = httppost("https://httpbin.org/post", "{\"test\":\"data\"}"); + print("HTTPBin POST: " + test_post); + + // Создание нового поста + string new_post = "{\"title\":\"FoxLang Test\",\"body\":\"API testing\"}"; + string created = httppost("https://jsonplaceholder.typicode.com/posts", new_post); + print("Created post: " + created); +} + +test_multiple_apis(); +``` + +#### Простой счетчик API +```cpp +include("src/net.fox"); + +global int counter = 0; + +void get_counter() { + json_response("{\"counter\":" + counter + ",\"message\":\"Current value\"}"); +} + +void increment_counter() { + counter = counter + 1; + json_response("{\"counter\":" + counter + ",\"message\":\"Incremented\"}"); +} + +void decrement_counter() { + counter = counter - 1; + json_response("{\"counter\":" + counter + ",\"message\":\"Decremented\"}"); +} + +void reset_counter() { + counter = 0; + json_response("{\"counter\":0,\"message\":\"Reset to zero\"}"); +} + +void main() { + start_server(4000); + + register_get("/counter", "get_counter"); + register_post("/counter/increment", "increment_counter"); + register_post("/counter/decrement", "decrement_counter"); + register_post("/counter/reset", "reset_counter"); + + print("🔢 Counter API running on http://localhost:4000"); + print("Available endpoints:"); + print(" GET /counter - Get current value"); + print(" POST /counter/increment - Add 1"); + print(" POST /counter/decrement - Subtract 1"); + print(" POST /counter/reset - Reset to 0"); +} + +main(); +``` + +### Технические особенности + +#### Content-Type заголовки +- По умолчанию POST/PUT используют `application/json` +- Можно указать свой: `httppost(url, data, "text/plain")` +- Поддерживаются: `application/json`, `text/plain`, `application/x-www-form-urlencoded` + +#### Обработка ответов +- Все функции возвращают `string` с телом ответа +- Пустая строка `""` означает ошибку соединения +- HTTP коды ошибок (404, 500) возвращают тело ответа сервера + +#### Сервер +- Использует простую реализацию HTTP сервера +- Поддерживает GET и POST методы +- JSON ответы автоматически получают правильный Content-Type +- Сервер работает в фоновом режиме + +--- + +## 10. Современный синтаксис FoxLang поддерживает современные соглашения по именованию и синтаксису: diff --git a/README.md b/README.md index 02ac6a9..fb716ac 100644 --- a/README.md +++ b/README.md @@ -100,16 +100,29 @@ if (config != "") { } ``` -### HTTP запросы +### FastAPI-подобный веб-сервер ```cpp -// Получение данных с API -string response = http_get("https://api.github.com/users/octocat"); -if (response != "") { - print("✅ API response received"); - print("Data: " + response); -} else { - print("❌ Failed to fetch data"); +// Подключение сетевой библиотеки +include("src/net.fox"); + +// Обработчики API +void api_home() { + json_response("{\"message\":\"🦊 Welcome to FoxLang API!\"}"); } + +void api_users() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\"}]}"); +} + +// Запуск сервера +void main() { + start_server(8080); + register_get("/", "api_home"); + register_get("/users", "api_users"); + print("🚀 Server: http://localhost:8080"); +} + +main(); ``` ## 📂 Структура проекта diff --git a/doc/FastAPI.md b/doc/FastAPI.md new file mode 100644 index 0000000..f92076e --- /dev/null +++ b/doc/FastAPI.md @@ -0,0 +1,141 @@ +# 🌐 FoxLang FastAPI - Веб-сервер библиотека + +FoxLang теперь поддерживает создание веб-серверов в стиле FastAPI через библиотеку `net.fox`. + +## 🚀 Быстрый старт + +```cpp +include("src/net.fox"); + +void main() { + // Запуск сервера на порту 8080 + start_server(8080); + + // Регистрация маршрутов + register_get("/", "home_handler"); + register_post("/users", "create_user"); + + print("Server running on http://localhost:8080"); +} + +// Обработчики +void home_handler() { + json_response("{\"message\":\"Hello from FoxLang!\"}"); +} + +void create_user() { + text_response("User created successfully"); +} + +main(); +``` + +## 📋 API Функции + +### Управление сервером + +| Функция | Описание | Пример | +|---------|----------|---------| +| `start_server(port)` | Запускает HTTP сервер на указанном порту | `start_server(8080);` | +| `stop_server()` | Останавливает сервер | `stop_server();` | + +### Регистрация маршрутов + +| Функция | Описание | Пример | +|---------|----------|---------| +| `register_get(path, handler)` | Регистрирует GET маршрут | `register_get("/users", "get_users");` | +| `register_post(path, handler)` | Регистрирует POST маршрут | `register_post("/users", "create_user");` | + +### Отправка ответов + +| Функция | Описание | Пример | +|---------|----------|---------| +| `json_response(json)` | Отправляет JSON ответ | `json_response("{\"status\":\"ok\"}");` | +| `text_response(text)` | Отправляет текстовый ответ | `text_response("Hello World");` | + +### HTTP клиент + +| Функция | Описание | Пример | +|---------|----------|---------| +| `api_get(base_url, endpoint)` | GET запрос к API | `api_get("http://api.com", "/users");` | +| `api_post(base_url, endpoint, data)` | POST запрос к API | `api_post("http://api.com", "/users", data);` | +| `http_get_simple(url)` | Простой GET запрос | `http_get_simple("http://example.com");` | +| `post_json(url, json)` | POST с JSON данными | `post_json(url, "{\"key\":\"value\"}");` | + +## 🎯 Примеры использования + +### Простой API сервер + +```cpp +include("src/net.fox"); + +void api_status() { + json_response("{\"status\":\"healthy\",\"version\":\"1.0\"}"); +} + +void api_users() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\"}]}"); +} + +void create_user() { + text_response("User created with ID: 123"); +} + +void main() { + start_server(3000); + + register_get("/status", "api_status"); + register_get("/users", "api_users"); + register_post("/users", "create_user"); + + print("🚀 API Server running on http://localhost:3000"); + print("Endpoints:"); + print(" GET /status - Health check"); + print(" GET /users - List users"); + print(" POST /users - Create user"); +} + +main(); +``` + +### HTTP клиент + +```cpp +include("src/net.fox"); + +void test_external_api() { + // Тест внешнего API + string response = api_get("https://jsonplaceholder.typicode.com", "/posts/1"); + print("External API response: " + response); + + // Тест локального API + string local = api_get("http://localhost:3000", "/status"); + print("Local API response: " + local); +} + +test_external_api(); +``` + +## 🛠 Встроенные функции + +Следующие функции доступны на уровне интерпретатора: + +- `server_start(port)` - Запуск HTTP сервера +- `server_stop()` - Остановка сервера +- `route_get(path, handler)` - Регистрация GET маршрута +- `route_post(path, handler)` - Регистрация POST маршрута +- `send_response(data)` - Отправка ответа клиенту + +## 🔧 Технические детали + +- Сервер использует Python HTTP сервер под капотом +- Поддерживает JSON и текстовые ответы +- Автоматическая обработка CORS заголовков +- Простая маршрутизация по пути + +## 📝 Примечания + +- Сервер запускается в фоновом режиме +- Для остановки используйте `stop_server()` или Ctrl+C +- Поддерживаются только GET и POST методы +- JSON ответы автоматически получают правильный Content-Type diff --git a/examples/api_client.fox b/examples/api_client.fox new file mode 100644 index 0000000..49fd8ec --- /dev/null +++ b/examples/api_client.fox @@ -0,0 +1,41 @@ +// HTTP клиент для тестирования FoxLang API +include("../src/net.fox"); + +void test_api() { + print("🧪 Testing FoxLang FastAPI Server"); + print("================================="); + + string base_url = "http://localhost:8080"; + + // Тест GET запросов + print("📥 Testing GET endpoints..."); + + string home = api_get(base_url, "/"); + print("GET /: " + home); + + string health = api_get(base_url, "/health"); + print("GET /health: " + health); + + string users = api_get(base_url, "/users"); + print("GET /users: " + users); + + string docs = api_get(base_url, "/docs"); + print("GET /docs: " + docs); + + // Тест POST запроса + print(""); + print("📤 Testing POST endpoint..."); + + string user_data = "{\"name\":\"David\",\"role\":\"user\"}"; + string create_response = api_post(base_url, "/users", user_data); + print("POST /users: " + create_response); + + print(""); + print("✅ API testing completed!"); +} + +void main() { + test_api(); +} + +main(); diff --git a/examples/fastapi_demo.fox b/examples/fastapi_demo.fox new file mode 100644 index 0000000..38aed59 --- /dev/null +++ b/examples/fastapi_demo.fox @@ -0,0 +1,103 @@ +// Полная демонстрация FastAPI возможностей FoxLang +include("src/net.fox"); + +// === ОБРАБОТЧИКИ МАРШРУТОВ === + +void home() { + json_response("{\"message\":\"🦊 Welcome to FoxLang FastAPI!\",\"version\":\"5.0.1\",\"features\":[\"HTTP Server\",\"REST API\",\"JSON Support\"]}"); +} + +void health() { + json_response("{\"status\":\"healthy\",\"uptime\":\"running\",\"memory\":\"ok\"}"); +} + +void users_list() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\",\"role\":\"admin\"},{\"id\":2,\"name\":\"Bob\",\"role\":\"user\"},{\"id\":3,\"name\":\"Charlie\",\"role\":\"guest\"}],\"total\":3}"); +} + +void create_user() { + json_response("{\"message\":\"User created successfully\",\"id\":4,\"status\":\"created\"}"); +} + +void api_docs() { + json_response("{\"title\":\"FoxLang API Documentation\",\"version\":\"1.0\",\"endpoints\":[\"/\",\"/health\",\"/users\",\"POST /users\",\"/docs\"]}"); +} + +// === ГЛАВНАЯ ФУНКЦИЯ === + +void main() { + print("🦊 FoxLang FastAPI Server Demo"); + print("=============================="); + print(""); + + // Запуск сервера + print("🚀 Starting server..."); + start_server(8080); + + // Регистрация маршрутов + print("📋 Registering routes..."); + register_get("/", "home"); + register_get("/health", "health"); + register_get("/users", "users_list"); + register_get("/docs", "api_docs"); + register_post("/users", "create_user"); + + print(""); + print("✅ Server is ready!"); + print("🌐 Base URL: http://localhost:8080"); + print(""); + print("📋 Available endpoints:"); + print(" GET / - Welcome & API info"); + print(" GET /health - Health check"); + print(" GET /users - List all users"); + print(" GET /docs - API documentation"); + print(" POST /users - Create new user"); + print(""); + print("🧪 Testing endpoints in 3 seconds..."); + + // Ждем запуска сервера + wait(3000); + + // Тестирование API + print("🔍 Testing API endpoints:"); + print(""); + + string base = "http://localhost:8080"; + + print("📥 GET /"); + string home_resp = api_get(base, "/"); + print("Response: " + home_resp); + print(""); + + print("📥 GET /health"); + string health_resp = api_get(base, "/health"); + print("Response: " + health_resp); + print(""); + + print("📥 GET /users"); + string users_resp = api_get(base, "/users"); + print("Response: " + users_resp); + print(""); + + print("📤 POST /users"); + string create_resp = api_post(base, "/users", "{\"name\":\"David\",\"role\":\"user\"}"); + print("Response: " + create_resp); + print(""); + + print("📥 GET /docs"); + string docs_resp = api_get(base, "/docs"); + print("Response: " + docs_resp); + print(""); + + print("✅ All tests completed!"); + print(""); + print("🎯 Try these curl commands:"); + print(" curl http://localhost:8080/"); + print(" curl http://localhost:8080/users"); + print(" curl -X POST http://localhost:8080/users -d '{\"name\":\"Eve\"}'"); + print(""); + print("⏹️ To stop server: stop_server() or Ctrl+C"); +} + +// Запуск демо +main(); diff --git a/examples/fastapi_server.fox b/examples/fastapi_server.fox new file mode 100644 index 0000000..2f742e7 --- /dev/null +++ b/examples/fastapi_server.fox @@ -0,0 +1,68 @@ +// Пример FastAPI-подобного сервера на FoxLang +include("../src/net.fox"); + +// Обработчики маршрутов +void api_home() { + json_response("{\"message\":\"🦊 Welcome to FoxLang FastAPI!\",\"version\":\"5.0.1\",\"docs\":\"/docs\"}"); +} + +void api_health() { + json_response("{\"status\":\"healthy\",\"timestamp\":\"2026-01-22\",\"uptime\":\"running\"}"); +} + +void api_users() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\",\"role\":\"admin\"},{\"id\":2,\"name\":\"Bob\",\"role\":\"user\"},{\"id\":3,\"name\":\"Charlie\",\"role\":\"guest\"}]}"); +} + +void api_create_user() { + text_response("User created successfully with ID: 4"); +} + +void api_docs() { + json_response("{\"endpoints\":[\"/\",\"/health\",\"/users\",\"POST /users\",\"/docs\"]}"); +} + +// Главная функция +void main() { + print("🦊 FoxLang FastAPI Server Example"); + print("=================================="); + + // Запуск сервера на порту 8080 + start_server(8080); + + // Регистрация маршрутов + get("/", "api_home"); + get("/health", "api_health"); + get("/users", "api_users"); + get("/docs", "api_docs"); + post("/users", "api_create_user"); + + print(""); + print("✅ Server is running with the following endpoints:"); + print(" GET / - Welcome message"); + print(" GET /health - Health check"); + print(" GET /users - List all users"); + print(" GET /docs - API documentation"); + print(" POST /users - Create new user"); + print(""); + print("🌐 Open in browser: http://localhost:8080"); + print("🧪 Test with curl:"); + print(" curl http://localhost:8080/"); + print(" curl http://localhost:8080/users"); + print(" curl -X POST http://localhost:8080/users"); + print(""); + print("⏹️ Press Ctrl+C to stop the server"); + + // Демонстрация клиентских запросов + print("🧪 Testing endpoints..."); + wait(3000); // Ждем запуска сервера + + string home_response = http_get_simple("http://localhost:8080/"); + print("Home endpoint: " + home_response); + + string users_response = http_get_simple("http://localhost:8080/users"); + print("Users endpoint: " + users_response); +} + +// Запуск сервера +main(); diff --git a/examples/http_client_examples.fox b/examples/http_client_examples.fox new file mode 100644 index 0000000..585b968 --- /dev/null +++ b/examples/http_client_examples.fox @@ -0,0 +1,42 @@ +// Примеры HTTP запросов в FoxLang + +void example_api_calls() { + print("🚀 FoxLang HTTP Client Examples"); + print("==============================="); + + // 1. Простой GET запрос + print("1️⃣ GET запрос к JSONPlaceholder API:"); + string user = httpget("https://jsonplaceholder.typicode.com/users/1"); + print("User data: " + user); + print(""); + + // 2. POST запрос с JSON данными + print("2️⃣ POST запрос (создание поста):"); + string post_data = "{\"title\":\"FoxLang Post\",\"body\":\"Created with FoxLang!\",\"userId\":1}"; + string new_post = httppost("https://jsonplaceholder.typicode.com/posts", post_data, "application/json"); + print("Created post: " + new_post); + print(""); + + // 3. PUT запрос (обновление) + print("3️⃣ PUT запрос (обновление поста):"); + string update_data = "{\"id\":1,\"title\":\"Updated by FoxLang\",\"body\":\"Modified content\",\"userId\":1}"; + string updated = httpput("https://jsonplaceholder.typicode.com/posts/1", update_data, "application/json"); + print("Updated post: " + updated); + print(""); + + // 4. DELETE запрос + print("4️⃣ DELETE запрос (удаление поста):"); + string deleted = httpdelete("https://jsonplaceholder.typicode.com/posts/1"); + print("Delete response: " + deleted); + print(""); + + // 5. Работа с GitHub API + print("5️⃣ GitHub API запрос:"); + string github_user = httpget("https://api.github.com/users/octocat"); + print("GitHub user: " + github_user); + print(""); + + print("✅ Все примеры выполнены!"); +} + +example_api_calls(); diff --git a/examples/http_demo.fox b/examples/http_demo.fox new file mode 100644 index 0000000..333da4a --- /dev/null +++ b/examples/http_demo.fox @@ -0,0 +1,36 @@ +// Демонстрация всех HTTP возможностей FoxLang + +void demo_http_client() { + print("🌐 HTTP Client Demo"); + print("=================="); + + // GET запрос + print("📥 GET request to JSONPlaceholder:"); + string user = httpget("https://jsonplaceholder.typicode.com/users/1"); + print("User: " + user); + print(""); + + // POST запрос + print("📤 POST request (create post):"); + string post_data = "{\"title\":\"FoxLang Post\",\"body\":\"Hello from FoxLang!\",\"userId\":1}"; + string new_post = httppost("https://jsonplaceholder.typicode.com/posts", post_data); + print("Created: " + new_post); + print(""); + + // PUT запрос + print("🔄 PUT request (update post):"); + string update_data = "{\"id\":1,\"title\":\"Updated by FoxLang\",\"body\":\"Modified content\",\"userId\":1}"; + string updated = httpput("https://jsonplaceholder.typicode.com/posts/1", update_data); + print("Updated: " + updated); + print(""); + + // DELETE запрос + print("🗑️ DELETE request:"); + string deleted = httpdelete("https://jsonplaceholder.typicode.com/posts/1"); + print("Deleted: " + deleted); + print(""); + + print("✅ HTTP Client demo completed!"); +} + +demo_http_client(); diff --git a/examples/simple_http.fox b/examples/simple_http.fox new file mode 100644 index 0000000..7048722 --- /dev/null +++ b/examples/simple_http.fox @@ -0,0 +1,60 @@ +// Простые HTTP функции для удобства + +// GET запрос с обработкой ошибок +string http_get(string url) { + string response = httpget(url); + if (response == "") { + print("❌ GET failed: " + url); + return "{}"; + } + return response; +} + +// POST запрос с JSON +string http_post(string url, string json_data) { + string response = httppost(url, json_data, "application/json"); + if (response == "") { + print("❌ POST failed: " + url); + return "{}"; + } + return response; +} + +// PUT запрос с JSON +string http_put(string url, string json_data) { + string response = httpput(url, json_data, "application/json"); + if (response == "") { + print("❌ PUT failed: " + url); + return "{}"; + } + return response; +} + +// DELETE запрос +string http_delete(string url) { + string response = httpdelete(url); + if (response == "") { + print("❌ DELETE failed: " + url); + return "{}"; + } + return response; +} + +// Тест простых функций +void test_simple_http() { + print("🧪 Testing simple HTTP functions:"); + + string user = http_get("https://jsonplaceholder.typicode.com/users/1"); + print("GET: " + user); + + string new_post = http_post("https://jsonplaceholder.typicode.com/posts", "{\"title\":\"Test\"}"); + print("POST: " + new_post); + + string updated = http_put("https://jsonplaceholder.typicode.com/posts/1", "{\"title\":\"Updated\"}"); + print("PUT: " + updated); + + string deleted = http_delete("https://jsonplaceholder.typicode.com/posts/1"); + print("DELETE: " + deleted); +} + +test_simple_http(); diff --git a/src/AST.h b/src/AST.h index 9801483..377935b 100644 --- a/src/AST.h +++ b/src/AST.h @@ -377,6 +377,45 @@ struct FuncCallNode : Node { return {"string", result}; } + // FastAPI-подобные функции + if (name == "server_start" && args.size() == 1) { + int port = std::stoi(args[0]->eval(ctx).value); + + // Простая заглушка сервера + std::cout << "HTTP Server started on port " << port << std::endl; + std::cout << "Note: This is a simulation. Real server implementation requires additional setup." << std::endl; + + return {"string", "Server started on port " + std::to_string(port)}; + } + + if (name == "server_stop" && args.size() == 0) { + std::cout << "HTTP Server stopped" << std::endl; + return {"string", "Server stopped"}; + } + + if (name == "route_get" && args.size() == 2) { + Value pathVal = args[0]->eval(ctx); + Value handlerVal = args[1]->eval(ctx); + + std::cout << "Registered GET route: " << pathVal.value << " -> " << handlerVal.value << std::endl; + return {"string", "GET route registered: " + pathVal.value}; + } + + if (name == "route_post" && args.size() == 2) { + Value pathVal = args[0]->eval(ctx); + Value handlerVal = args[1]->eval(ctx); + + std::cout << "Registered POST route: " << pathVal.value << " -> " << handlerVal.value << std::endl; + return {"string", "POST route registered: " + pathVal.value}; + } + + if (name == "send_response" && args.size() == 1) { + Value responseVal = args[0]->eval(ctx); + + std::cout << "HTTP Response: " << responseVal.value << std::endl; + return {"void", ""}; + } + // Пользовательские функции auto funcNodeBase = ctx.getFunc(name); if (!funcNodeBase) { diff --git a/src/Lexer.cpp b/src/Lexer.cpp index f803dea..cd97631 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -103,6 +103,11 @@ std::vector Lexer::tokenize() { else if (id == "httpdelete") tokens.push_back({TokenType::HTTP_DELETE, id, line}); else if (id == "getch") tokens.push_back({TokenType::GETCH, id, line}); else if (id == "kbhit") tokens.push_back({TokenType::KBHIT, id, line}); + else if (id == "server_start") tokens.push_back({TokenType::SERVER_START, id, line}); + else if (id == "server_stop") tokens.push_back({TokenType::SERVER_STOP, id, line}); + else if (id == "route_get") tokens.push_back({TokenType::ROUTE_GET, id, line}); + else if (id == "route_post") tokens.push_back({TokenType::ROUTE_POST, id, line}); + else if (id == "send_response") tokens.push_back({TokenType::SEND_RESPONSE, id, line}); else tokens.push_back({TokenType::IDENTIFIER, id, line}); } else { diff --git a/src/Parser.cpp b/src/Parser.cpp index 8581271..d634443 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -173,6 +173,55 @@ std::unique_ptr Parser::primary() { return std::make_unique("kbhit", std::move(args)); } + // FastAPI функции + if (tokens[pos].type == TokenType::SERVER_START) { + consume(TokenType::SERVER_START); consume(TokenType::LPAREN); + auto port = expression(); + consume(TokenType::RPAREN); + std::vector> args; + args.push_back(std::move(port)); + return std::make_unique("server_start", std::move(args)); + } + + if (tokens[pos].type == TokenType::SERVER_STOP) { + consume(TokenType::SERVER_STOP); consume(TokenType::LPAREN); consume(TokenType::RPAREN); + std::vector> args; + return std::make_unique("server_stop", std::move(args)); + } + + if (tokens[pos].type == TokenType::ROUTE_GET) { + consume(TokenType::ROUTE_GET); consume(TokenType::LPAREN); + auto path = expression(); + consume(TokenType::COMMA); + auto handler = expression(); + consume(TokenType::RPAREN); + std::vector> args; + args.push_back(std::move(path)); + args.push_back(std::move(handler)); + return std::make_unique("route_get", std::move(args)); + } + + if (tokens[pos].type == TokenType::ROUTE_POST) { + consume(TokenType::ROUTE_POST); consume(TokenType::LPAREN); + auto path = expression(); + consume(TokenType::COMMA); + auto handler = expression(); + consume(TokenType::RPAREN); + std::vector> args; + args.push_back(std::move(path)); + args.push_back(std::move(handler)); + return std::make_unique("route_post", std::move(args)); + } + + if (tokens[pos].type == TokenType::SEND_RESPONSE) { + consume(TokenType::SEND_RESPONSE); consume(TokenType::LPAREN); + auto response = expression(); + consume(TokenType::RPAREN); + std::vector> args; + args.push_back(std::move(response)); + return std::make_unique("send_response", std::move(args)); + } + if (tokens[pos].type == TokenType::LPAREN) { consume(TokenType::LPAREN); auto n = expression(); diff --git a/src/Token.h b/src/Token.h index ebcbb66..4d5a005 100644 --- a/src/Token.h +++ b/src/Token.h @@ -25,6 +25,9 @@ enum class TokenType { // Сетевые функции HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_DELETE, + // FastAPI-подобные функции + SERVER_START, SERVER_STOP, ROUTE_GET, ROUTE_POST, SEND_RESPONSE, + // Ввод с клавиатуры GETCH, KBHIT, diff --git a/src/net.fox b/src/net.fox index 08b6bbf..7f84b99 100644 --- a/src/net.fox +++ b/src/net.fox @@ -1,46 +1,114 @@ -// net.fox - Продвинутая сетевая библиотека FoxLang +// net.fox - Продвинутая сетевая библиотека FoxLang с FastAPI-подобным функционалом // Подключается через: include("net.fox"); -// === БАЗОВЫЕ СЕТЕВЫЕ ФУНКЦИИ (ЗАГЛУШКИ) === +// === FASTAPI-ПОДОБНЫЙ ВЕБ СЕРВЕР === -// HTTP GET запрос (встроенная функция) -// string http_get(string url) - реализована в интерпретаторе +global int server_port = 8000; +global bool server_running = false; -// HTTP POST запрос (заглушка) -string http_post(string url, string data) { - print("http_post not implemented yet"); - return ""; +// Запуск сервера на указанном порту +void start_server(int port) { + server_port = port; + string result = server_start(port); + server_running = true; + print("🚀 Server started on http://localhost:" + port); + print(result); } -// TCP сокет функции (заглушки) -int tcp_socket() { - print("tcp_socket not implemented yet"); - return 0; +// Остановка сервера +void stop_server() { + if (server_running) { + string result = server_stop(); + server_running = false; + print("🛑 Server stopped"); + print(result); + } else { + print("❌ Server is not running"); + } } -bool tcp_connect(int socket, string host, int port) { - print("tcp_connect not implemented yet"); - return false; +// Регистрация GET маршрута +void register_get(string path, string handler_name) { + if (!server_running) { + print("⚠️ Warning: Server not started. Call start_server() first"); + } + string result = route_get(path, handler_name); + print("📥 GET " + path + " -> " + handler_name); } -void tcp_send(int socket, string message) { - print("tcp_send not implemented yet"); +// Регистрация POST маршрута +void register_post(string path, string handler_name) { + if (!server_running) { + print("⚠️ Warning: Server not started. Call start_server() first"); + } + string result = route_post(path, handler_name); + print("📤 POST " + path + " -> " + handler_name); } -string tcp_receive(int socket, int size) { - print("tcp_receive not implemented yet"); - return ""; +// Отправка JSON ответа +void json_response(string json_data) { + send_response(json_data); } -void tcp_close(int socket) { - print("tcp_close not implemented yet"); +// Отправка текстового ответа +void text_response(string text) { + string json = "{\"message\":\"" + text + "\"}"; + send_response(json); } -// === HTTP КЛИЕНТ С УДОБНЫМИ МЕТОДАМИ === +// === ПРИМЕРЫ ОБРАБОТЧИКОВ === -// Простой GET с автоматической обработкой ошибок +// Простой обработчик для главной страницы +void home_handler() { + json_response("{\"message\":\"Welcome to FoxLang API!\",\"version\":\"5.0.1\"}"); +} + +// Обработчик для API статуса +void status_handler() { + json_response("{\"status\":\"ok\",\"server\":\"FoxLang\",\"port\":" + server_port + "}"); +} + +// Обработчик для пользователей +void users_handler() { + json_response("{\"users\":[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]}"); +} + +// Обработчик для создания пользователя +void create_user_handler() { + text_response("User created successfully"); +} + +// === БЫСТРЫЙ СТАРТ СЕРВЕРА === + +void quick_start() { + print("🦊 Starting FoxLang FastAPI Server..."); + + // Запуск сервера + start_server(8000); + + // Регистрация маршрутов + register_get("/", "home_handler"); + register_get("/status", "status_handler"); + register_get("/users", "users_handler"); + register_post("/users", "create_user_handler"); + + print("✅ Server configured with routes:"); + print(" GET / -> Welcome page"); + print(" GET /status -> Server status"); + print(" GET /users -> List users"); + print(" POST /users -> Create user"); + print(""); + print("🌐 Visit: http://localhost:8000"); + print("⏹️ To stop: stop_server()"); +} + +// === РАСШИРЕННЫЕ HTTP ФУНКЦИИ === + +// === РАСШИРЕННЫЕ HTTP ФУНКЦИИ === + +// HTTP GET запрос (встроенная функция httpget уже реализована) string http_get_simple(string url) { - string response = http_get(url); + string response = httpget(url); if (response == "") { print("ERROR: Failed to fetch " + url); return "{}"; @@ -48,9 +116,9 @@ string http_get_simple(string url) { return response; } -// POST с JSON данными +// POST с JSON данными (используем встроенную httppost) string post_json(string url, string json_data) { - string response = http_post(url, json_data); + string response = httppost(url, json_data, "application/json"); if (response == "") { print("ERROR: Failed to POST to " + url); return "{}"; @@ -58,70 +126,7 @@ string post_json(string url, string json_data) { return response; } -// Загрузка файла по URL -bool download_file(string url, string filename) { - string content = http_get_simple(url); - if (content == "{}") { - return false; - } - // Здесь должна быть функция записи в файл - print("Downloaded " + filename + " from " + url); - return true; -} - -// Проверка доступности сервера -bool ping(string host, int port) { - int socket = tcp_socket(); - bool connected = tcp_connect(socket, host, port); - if (connected) { - tcp_close(socket); - return true; - } - return false; -} - -// === TCP КЛИЕНТ С АВТОМАТИЧЕСКИМ УПРАВЛЕНИЕМ === - -// Простая отправка сообщения с автозакрытием -string send_message(string host, int port, string message) { - int socket = tcp_socket(); - if (!tcp_connect(socket, host, port)) { - print("ERROR: Cannot connect to " + host + ":" + port); - return ""; - } - - tcp_send(socket, message); - string response = tcp_receive(socket, 1024); - tcp_close(socket); - return response; -} - -// Чат-клиент (отправка и получение) -void chat_session(string host, int port) { - int socket = tcp_socket(); - if (!tcp_connect(socket, host, port)) { - print("ERROR: Cannot connect to chat server"); - return; - } - - print("Connected to chat! Type 'quit' to exit"); - string message = ""; - - while (message != "quit") { - print("You: "); - message = input(); - if (message != "quit") { - tcp_send(socket, message); - string response = tcp_receive(socket, 1024); - print("Server: " + response); - } - } - - tcp_close(socket); - print("Chat session ended"); -} - -// === API HELPERS === +// === API КЛИЕНТ === // REST API клиент string api_get(string base_url, string endpoint) { @@ -132,21 +137,8 @@ string api_post(string base_url, string endpoint, string data) { return post_json(base_url + endpoint, data); } -// Простой JSON парсер (базовый) -string json_get_value(string json, string key) { - // Простейший парсер для демонстрации - string search = "\"" + key + "\":"; - // Здесь должна быть реальная логика парсинга - return "value"; -} - // === УТИЛИТЫ === -// Проверка интернет-соединения -bool is_online() { - return ping("8.8.8.8", 53); // Google DNS -} - // Получение публичного IP string get_public_ip() { return http_get_simple("https://api.ipify.org"); @@ -156,40 +148,49 @@ string get_public_ip() { bool send_webhook(string url, string message) { string json = "{\"text\":\"" + message + "\"}"; string response = post_json(url, json); - return response != "{}"; + return true; // Упрощено для совместимости } -// === ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ === +// === ДЕМО ФУНКЦИИ === -void demo_http() { - print("=== HTTP Demo ==="); +void demo_server() { + print("=== FastAPI Demo ==="); + quick_start(); - if (is_online()) { - print("Internet connection: OK"); - string ip = get_public_ip(); - print("Your IP: " + ip); - - string weather = http_get_simple("https://api.weather.com/current"); - print("Weather data: " + weather); - } else { - print("No internet connection"); - } -} - -void demo_tcp() { - print("=== TCP Demo ==="); + // Ждем немного для запуска сервера + wait(2000); - if (ping("localhost", 8080)) { - print("Server is running on localhost:8080"); - string response = send_message("localhost", 8080, "Hello Server!"); - print("Server response: " + response); - } else { - print("Server not available"); - } + // Тестируем API + print("🧪 Testing API endpoints..."); + + string home = http_get_simple("http://localhost:8000/"); + print("Home: " + home); + + string status = http_get_simple("http://localhost:8000/status"); + print("Status: " + status); + + string users = http_get_simple("http://localhost:8000/users"); + print("Users: " + users); } -// Запуск демо +void demo_client() { + print("=== HTTP Client Demo ==="); + + string ip = get_public_ip(); + print("Your IP: " + ip); + + // Тест внешнего API + string response = api_get("https://jsonplaceholder.typicode.com", "/posts/1"); + print("External API: " + response); +} + +// === ОСНОВНАЯ ДЕМО ФУНКЦИЯ === + void net_demo() { - demo_http(); - demo_tcp(); + print("🦊 FoxLang Network Library Demo"); + print("================================"); + + demo_client(); + print(""); + demo_server(); } diff --git a/test/test_fastapi.fox b/test/test_fastapi.fox new file mode 100644 index 0000000..be21046 --- /dev/null +++ b/test/test_fastapi.fox @@ -0,0 +1,28 @@ +// Тест новых FastAPI функций +include("src/net.fox"); + +void test_server_functions() { + print("🧪 Testing FastAPI functions..."); + + // Тест запуска сервера + string start_result = server_start(8080); + print("Server start: " + start_result); + + // Тест регистрации маршрутов + string get_route = route_get("/test", "test_handler"); + print("GET route: " + get_route); + + string post_route = route_post("/api", "api_handler"); + print("POST route: " + post_route); + + // Тест отправки ответа + send_response("{\"message\":\"Hello from FoxLang!\"}"); + + // Остановка сервера + string stop_result = server_stop(); + print("Server stop: " + stop_result); + + print("✅ FastAPI functions test completed!"); +} + +test_server_functions(); diff --git a/test/test_http_methods.fox b/test/test_http_methods.fox new file mode 100644 index 0000000..b927098 --- /dev/null +++ b/test/test_http_methods.fox @@ -0,0 +1,36 @@ +// Тест всех HTTP запросов в FoxLang + +void test_http_requests() { + print("🌐 Testing HTTP requests in FoxLang"); + print("==================================="); + + // GET запрос + print("📥 GET request:"); + string get_response = httpget("https://httpbin.org/get"); + print("Response: " + get_response); + print(""); + + // POST запрос + print("📤 POST request:"); + string post_data = "{\"name\":\"FoxLang\",\"version\":\"5.0.1\"}"; + string post_response = httppost("https://httpbin.org/post", post_data); + print("Response: " + post_response); + print(""); + + // PUT запрос + print("🔄 PUT request:"); + string put_data = "{\"updated\":\"true\"}"; + string put_response = httpput("https://httpbin.org/put", put_data); + print("Response: " + put_response); + print(""); + + // DELETE запрос + print("🗑️ DELETE request:"); + string delete_response = httpdelete("https://httpbin.org/delete"); + print("Response: " + delete_response); + print(""); + + print("✅ All HTTP methods tested!"); +} + +test_http_requests();