### Configure Qt HTTP Server Examples with CMake Source: https://github.com/qt/qthttpserver/blob/dev/examples/httpserver/CMakeLists.txt This snippet demonstrates how to conditionally add example projects to the build process. It checks for the existence of required Qt modules before registering the example targets. ```cmake if(TARGET Qt::Gui AND TARGET Qt::Concurrent) qt_internal_add_example(colorpalette) endif() qt_internal_add_example(simple) ``` -------------------------------- ### Basic QHttpServer Setup and Routing Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to set up a basic HTTP server using QHttpServer, define simple routes, routes with path parameters, and return JSON responses. ```APIDOC ## Basic QHttpServer Setup and Routing ### Description This example shows how to initialize `QHttpServer`, define routes for different URL patterns, including those with path parameters, and configure the server to listen on a specific port. ### Method N/A (This is a setup example) ### Endpoint N/A (This is a setup example) ### Parameters N/A ### Request Example N/A ### Response N/A ## GET / ### Description Handles requests to the root path and returns a simple text response. ### Method GET ### Endpoint / ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **response** (string) - "Hello world" ## GET /user/ ### Description Handles requests to a user path with a typed path parameter for user ID. ### Method GET ### Endpoint /user/ ### Parameters #### Path Parameters - **id** (qint32) - Required - The ID of the user. ### Request Example N/A ### Response #### Success Response (200) - **response** (string) - "User [id]" ## GET /user//detail/ ### Description Handles requests with multiple typed path parameters for user ID and year. ### Method GET ### Endpoint /user//detail/ ### Parameters #### Path Parameters - **id** (qint32) - Required - The ID of the user. - **year** (qint32) - Required - The year for the detail. ### Request Example N/A ### Response #### Success Response (200) - **response** (string) - "User [id] detail year - [year]" ## GET /json/ ### Description Handles requests to the /json/ path and returns a JSON object. ### Method GET ### Endpoint /json/ ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **response** (QJsonObject) - A JSON object with key-value pairs. - **key1** (string) - **key2** (string) - **key3** (string) ``` -------------------------------- ### GET /stream Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to use QHttpServerResponder to send a direct response with custom headers. ```APIDOC ## GET /stream ### Description Sends a direct text response with custom headers using the responder object. ### Method GET ### Endpoint /stream ### Parameters None ### Request Example GET /stream ### Response #### Success Response (200) - **body** (string) - Direct response data #### Response Example Direct response data ``` -------------------------------- ### Implementing Async Handlers with QFuture and QtConcurrent Source: https://context7.com/qt/qthttpserver/llms.txt Examples of handling asynchronous requests in QtHttpServer. Includes basic async operations, paginated responses with query parameter parsing, and chunked streaming responses using QHttpServerResponder. ```cpp #include #include #include QHttpServer httpServer; // Async handler returning QFuture httpServer.route("/api/slow-operation", [](const QHttpServerRequest &request) { return QtConcurrent::run([request]() { QThread::sleep(2); return QHttpServerResponse(QJsonObject{ {"status", "completed"}, {"query", request.query().toString()} }); }); }); // Async with pagination and delay support httpServer.route("/api/items", QHttpServerRequest::Method::Get, [](const QHttpServerRequest &request) { return QtConcurrent::run([request]() { qint64 page = 1; qint64 perPage = 10; qint64 delay = 0; QUrlQuery query = request.query(); if (query.hasQueryItem("page")) page = query.queryItemValue("page").toLongLong(); if (query.hasQueryItem("per_page")) perPage = query.queryItemValue("per_page").toLongLong(); if (query.hasQueryItem("delay")) delay = query.queryItemValue("delay").toLongLong(); if (page < 1 || perPage < 1) { return QHttpServerResponse(QHttpServerResponder::StatusCode::BadRequest); } if (delay > 0) { QThread::sleep(delay); } QJsonArray items; qint64 start = (page - 1) * perPage; for (qint64 i = 0; i < perPage; ++i) { items.append(QJsonObject{ {"id", start + i + 1}, {"name", QString("Item %1").arg(start + i + 1)} }); } return QHttpServerResponse(QJsonObject{ {"page", page}, {"per_page", perPage}, {"data", items} }); }); }); // Async handler with responder for streaming httpServer.route("/api/stream", [](QHttpServerRequest request, QHttpServerResponder &&responder) { return QtConcurrent::run([request = std::move(request), responder = std::move(responder)]() mutable { QHttpHeaders headers; headers.append(QHttpHeaders::WellKnownHeader::ContentType, "text/event-stream"); responder.writeBeginChunked(headers); for (int i = 0; i < 5; ++i) { QThread::sleep(1); QString event = QString("data: Event %1\n\n").arg(i + 1); responder.writeChunk(event.toUtf8()); } responder.writeEndChunked(QByteArray()); return QFuture(); }); }); ``` -------------------------------- ### Configure Qt HttpServer Project with CMake Source: https://github.com/qt/qthttpserver/blob/dev/examples/httpserver/simple/CMakeLists.txt This CMakeLists.txt file sets up a Qt 6 project that uses the HttpServer module. It defines the project name, finds required Qt packages, creates an executable, links the HttpServer library, and installs the application and its resources. ```cmake # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(simple LANGUAGES CXX) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/httpserver/${PROJECT_NAME}") find_package(Qt6 REQUIRED COMPONENTS HttpServer) if(ANDROID) find_package(Qt6 REQUIRED COMPONENTS Gui) endif() qt_standard_project_setup() qt_add_executable(simple main.cpp ) target_link_libraries(simple PRIVATE Qt6::HttpServer ) if(ANDROID) target_link_libraries(simple PRIVATE Qt::Gui ) endif() qt_add_resources(simple "assets" PREFIX "/" FILES assets/certificate.crt assets/private.key assets/qt-logo.png ) install(TARGETS simple RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) ``` -------------------------------- ### Configure HTTPS/TLS with HTTP/2 in Qt HTTP Server Source: https://context7.com/qt/qthttpserver/llms.txt This C++ code illustrates how to set up a Qt HTTP server to support secure HTTPS connections using QSslServer. It includes loading SSL certificates and private keys, configuring TLS, and enabling HTTP/2 support via ALPN. The example also shows how to bind both HTTP and HTTPS servers to different ports. ```cpp #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QHttpServer httpServer; httpServer.route("/", []() { return "Secure Hello World!"; }); // Setup HTTP server on port 8080 auto tcpServer = std::make_unique(); if (!tcpServer->listen(QHostAddress::Any, 8080) || !httpServer.bind(tcpServer.get())) { qWarning() << "Failed to start HTTP server"; return -1; } quint16 httpPort = tcpServer->serverPort(); tcpServer.release(); // Setup HTTPS server with TLS QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration(); // Load certificate const auto certChain = QSslCertificate::fromPath(":/certs/server.crt"); if (certChain.isEmpty()) { qWarning() << "Failed to load SSL certificate"; return -1; } sslConfig.setLocalCertificate(certChain.front()); // Load private key QFile keyFile(":/certs/server.key"); if (!keyFile.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open private key file"; return -1; } QSslKey privateKey(&keyFile, QSsl::Rsa); keyFile.close(); sslConfig.setPrivateKey(privateKey); // Enable HTTP/2 via ALPN sslConfig.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2}); auto sslServer = std::make_unique(); sslServer->setSslConfiguration(sslConfig); if (!sslServer->listen(QHostAddress::Any, 8443) || !httpServer.bind(sslServer.get())) { qWarning() << "Failed to start HTTPS server"; return -1; } quint16 httpsPort = sslServer->serverPort(); sslServer.release(); qInfo() << "HTTP server running on port" << httpPort; qInfo() << "HTTPS server running on port" << httpsPort; return app.exec(); } ``` -------------------------------- ### Handling Specific HTTP Methods Source: https://context7.com/qt/qthttpserver/llms.txt Illustrates how to define routes that respond to specific HTTP methods (GET, POST, PUT, DELETE, PATCH) and handle request bodies. ```APIDOC ## API Endpoints for Items ### Description This section details how to create API endpoints for managing items, supporting various HTTP methods for listing, retrieving, creating, updating, and deleting items. ## GET /api/items ### Description Retrieves a list of all items. ### Method GET ### Endpoint /api/items ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **response** (QJsonArray) - An array of item objects. - **id** (number) - **name** (string) ### Response Example ```json [ {"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"} ] ``` ## GET /api/items/ ### Description Retrieves a specific item by its ID. ### Method GET ### Endpoint /api/items/ ### Parameters #### Path Parameters - **itemId** (qint64) - Required - The ID of the item to retrieve. ### Request Example N/A ### Response #### Success Response (200) - **response** (QJsonObject) - The item object. - **id** (number) - **name** (string) ### Response Example ```json {"id": 1, "name": "Item 1"} ``` ## POST /api/items ### Description Creates a new item. ### Method POST ### Endpoint /api/items ### Parameters #### Request Body - **request** (QJsonDocument) - Required - JSON document containing the item details. ### Request Example ```json { "name": "New Item" } ``` ### Response #### Success Response (201 Created) - **response** (QJsonObject) - The newly created item object with an assigned ID. - **id** (number) - **name** (string) #### Error Response (400 Bad Request) Returned if the request body is not a valid JSON. ### Response Example ```json {"id": 123, "name": "New Item"} ``` ## PUT /api/items/ ### Description Updates an existing item by its ID. ### Method PUT ### Endpoint /api/items/ ### Parameters #### Path Parameters - **itemId** (qint64) - Required - The ID of the item to update. #### Request Body - **request** (QJsonDocument) - Required - JSON document with the updated item details. ### Request Example ```json { "name": "Updated Item Name" } ``` ### Response #### Success Response (200 OK) - **response** (QJsonObject) - The updated item object. - **id** (number) - **name** (string) #### Error Response (400 Bad Request) Returned if the request body is not a valid JSON. ### Response Example ```json {"id": 1, "name": "Updated Item Name"} ``` ## DELETE /api/items/ ### Description Deletes an item by its ID. ### Method DELETE ### Endpoint /api/items/ ### Parameters #### Path Parameters - **itemId** (qint64) - Required - The ID of the item to delete. ### Request Example N/A ### Response #### Success Response (200 OK) - **response** (string) - Confirmation message or status. #### Error Response (404 Not Found) Returned if the item with the specified ID is not found. ### Response Example ```json {"status": "deleted"} ``` ## PATCH /api/items/ ### Description Partially updates an existing item by its ID. ### Method PATCH ### Endpoint /api/items/ ### Parameters #### Path Parameters - **itemId** (qint64) - Required - The ID of the item to partially update. #### Request Body - **request** (QJsonDocument) - Required - JSON document with the fields to update. ### Request Example ```json { "name": "Partially Updated Name" } ``` ### Response #### Success Response (200 OK) - **response** (QJsonObject) - The updated item object or a status confirmation. - **id** (number) - **status** (string) ### Response Example ```json {"id": 1, "status": "updated"} ``` ``` -------------------------------- ### GET /chunked Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates streaming data using chunked transfer encoding via QHttpServerResponder. ```APIDOC ## GET /chunked ### Description Initiates a chunked transfer encoding response to stream data to the client. ### Method GET ### Endpoint /chunked ### Parameters None ### Request Example GET /chunked ### Response #### Success Response (200) - **body** (stream) - Multiple chunks of text data #### Response Example First chunk of data\nSecond chunk of data\nThird chunk of data ``` -------------------------------- ### Define RESTful Routes with HTTP Methods Source: https://context7.com/qt/qthttpserver/llms.txt Shows how to restrict routes to specific HTTP methods like GET, POST, PUT, DELETE, and PATCH using the QHttpServerRequest::Method enum and handling request bodies. ```cpp #include #include QHttpServer httpServer; httpServer.route("/api/items", QHttpServerRequest::Method::Get, [](const QHttpServerRequest &request) { return QJsonArray{ QJsonObject{{"id", 1}, {"name", "Item 1"}}, QJsonObject{{"id", 2}, {"name", "Item 2"}} }; }); httpServer.route("/api/items/", QHttpServerRequest::Method::Get, [](qint64 itemId) { return QJsonObject{{"id", itemId}, {"name", QString("Item %1").arg(itemId)}}; }); httpServer.route("/api/items", QHttpServerRequest::Method::Post, [](const QHttpServerRequest &request) { QJsonDocument doc = QJsonDocument::fromJson(request.body()); if (doc.isNull()) { return QHttpServerResponse(QHttpServerResponder::StatusCode::BadRequest); } QJsonObject item = doc.object(); item["id"] = 123; return QHttpServerResponse(item, QHttpServerResponder::StatusCode::Created); }); httpServer.route("/api/items/", QHttpServerRequest::Method::Put, [](qint64 itemId, const QHttpServerRequest &request) { QJsonDocument doc = QJsonDocument::fromJson(request.body()); if (doc.isNull()) { return QHttpServerResponse(QHttpServerResponder::StatusCode::BadRequest); } QJsonObject updated = doc.object(); updated["id"] = itemId; return QHttpServerResponse(updated); }); httpServer.route("/api/items/", QHttpServerRequest::Method::Delete, [](qint64 itemId, const QHttpServerRequest &request) { return QHttpServerResponse(QHttpServerResponder::StatusCode::Ok); }); httpServer.route("/api/items/", QHttpServerRequest::Method::Patch, [](qint64 itemId, const QHttpServerRequest &request) { QJsonDocument doc = QJsonDocument::fromJson(request.body()); return QHttpServerResponse(QJsonObject{{"id", itemId}, {"status", "updated"}}); }); ``` -------------------------------- ### GET /custom/ Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates the use of custom type converters in the router to parse URL segments into specific C++ types. ```APIDOC ## GET /custom/ ### Description Uses a registered custom converter to parse a numeric URL segment into a CustomArg object. ### Method GET ### Endpoint /custom/ ### Parameters #### Path Parameters - **arg** (integer) - Required - A numeric value matching the regex [+-]?\d+ ### Request Example GET /custom/42 ### Response #### Success Response (200) - **body** (string) - Confirmation message with parsed data #### Response Example Received custom arg with data: 42 ``` -------------------------------- ### Create a Basic HTTP Server with Qt Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to initialize a QHttpServer, define routes with parameters, return JSON responses, and bind the server to a QTcpServer instance. ```cpp #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QHttpServer httpServer; httpServer.route("/", []() { return "Hello world"; }); httpServer.route("/user/", [](qint32 id) { return QString("User %1").arg(id); }); httpServer.route("/user//detail/", [](qint32 id, qint32 year) { return QString("User %1 detail year - %2").arg(id).arg(year); }); httpServer.route("/json/", []() { return QJsonObject{ {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"} }; }); auto tcpserver = std::make_unique(); if (!tcpserver->listen(QHostAddress::Any, 8080) || !httpServer.bind(tcpserver.get())) { qWarning() << "Server failed to listen on port 8080"; return -1; } tcpserver.release(); qInfo() << "Server running on http://127.0.0.1:8080/"; return app.exec(); } ``` -------------------------------- ### QHttpServerRequest - Accessing Request Details Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to access various components of an incoming HTTP request, including URL, method, headers, body, query parameters, and client information. ```APIDOC ## GET /request-info ### Description Retrieves and returns detailed information about the incoming HTTP request. ### Method GET ### Endpoint /request-info ### Query Parameters - **name** (string) - Optional - Example query parameter. - **value** (string) - Optional - Another example query parameter. ### Request Body Not applicable for this GET request. ### Request Example GET /request-info?name=test&value=123 ### Response #### Success Response (200) - **url** (string) - The URL of the request. - **method** (string) - The HTTP method used (e.g., GET, POST). - **body** (string) - The request body content. - **contentType** (string) - The value of the Content-Type header. - **headers** (object) - An object containing all request headers. - **query** (object) - An object containing all query parameters. - **remoteAddress** (string) - The IP address of the client. - **remotePort** (integer) - The port of the client. - **localAddress** (string) - The IP address of the server. - **localPort** (integer) - The port of the server. #### Response Example ```json { "url": "http://localhost:8080/request-info?name=test&value=123", "method": "GET", "body": "", "contentType": "", "headers": { "Host": "localhost:8080", "Connection": "keep-alive" }, "query": { "name": "test", "value": "123" }, "remoteAddress": "::1", "remotePort": 51234, "localAddress": "::1", "localPort": 8080 } ``` ``` -------------------------------- ### QHttpServerResponse - Creating Various Responses Source: https://context7.com/qt/qthttpserver/llms.txt Illustrates how to construct different types of HTTP responses, including plain text, JSON objects, JSON arrays, responses with custom status codes, MIME types, and static files. ```APIDOC ## Various Response Endpoints ### Description Provides examples of creating different HTTP responses using QHttpServerResponse. ### Method GET ### Endpoint - /text - /json-object - /json-array - /not-found - /xml - /assets/ - /custom-headers - /error ### Response #### Success Response (200) - Varies by endpoint - **Plain Text**: Returns "Hello, World!". - **JSON Object**: Returns a JSON object with 'message' and 'code'. - **JSON Array**: Returns a JSON array of objects. - **XML**: Returns XML data with 'application/xml' content type. - **Static File**: Serves a file from the application's resource system. - **Custom Headers**: Returns text with custom headers like 'Cache-Control' and 'X-Custom-Header'. #### Error Response (400) - **Error**: Returns "Bad Request: Invalid parameters" with a 400 status code. #### Not Found Response (404) - **Not Found**: Returns a 404 Not Found status code. ### Response Example (JSON Object) ```json { "message": "Success", "code": 200 } ``` ### Response Example (XML) ```xml data ``` ### Response Example (Custom Headers) ``` Custom response ``` Headers: - `Cache-Control`: `no-cache` - `X-Custom-Header`: `CustomValue` ``` -------------------------------- ### Configure QHttpServer Security and Limits Source: https://context7.com/qt/qthttpserver/llms.txt This snippet demonstrates how to configure QHttpServer settings such as rate limiting, connection limits, keep-alive timeouts, request size limits, and IP whitelisting/blacklisting for enhanced security and performance. It shows how to apply these configurations and read them back. ```cpp #include #include #include QHttpServer httpServer; QHttpServerConfiguration config; // Rate limiting - maximum requests per second per client config.setRateLimitPerSecond(100); // Connection limits config.setMaximumConnectionsPerHost(10); // Keep-alive timeout config.setKeepAliveTimeout(std::chrono::seconds(30)); // Request size limits config.setMaximumUrlSize(8192); // Max URL length config.setMaximumBodySize(10 * 1024 * 1024); // Max body size (10MB) config.setMaximumTotalHeaderSize(32768); // Max total headers size config.setMaximumHeaderFieldSize(8192); // Max single header size config.setMaximumHeaderFieldCount(100); // Max number of headers // IP whitelist - only allow specific subnets QList> whitelist = { {QHostAddress("192.168.1.0"), 24}, // 192.168.1.0/24 {QHostAddress("10.0.0.0"), 8}, // 10.0.0.0/8 {QHostAddress::LocalHost, 32} // 127.0.0.1/32 }; config.setWhitelist(whitelist); // IP blacklist - block specific addresses QList> blacklist = { {QHostAddress("192.168.1.100"), 32} // Block single IP }; config.setBlacklist(blacklist); // Apply configuration to server httpServer.setConfiguration(config); // Read current configuration QHttpServerConfiguration currentConfig = httpServer.configuration(); qDebug() << "Rate limit:" << currentConfig.rateLimitPerSecond(); qDebug() << "Max connections:" << currentConfig.maximumConnectionsPerHost(); qDebug() << "Keep-alive timeout:" << currentConfig.keepAliveTimeout().count() << "seconds"; ``` -------------------------------- ### QHttpServerRequest: Accessing Incoming HTTP Request Details Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to extract information from an incoming HTTP request using QHttpServerRequest. This includes accessing the URL, HTTP method, request body, specific headers, all headers, query parameters, and client connection details. It's useful for routing and processing client requests. ```cpp #include #include QHttpServer httpServer; httpServer.route("/request-info", [](const QHttpServerRequest &request) { QJsonObject info; // Get request URL and method info["url"] = request.url().toString(); info["method"] = QVariant::fromValue(request.method()).toString(); // Get request body (for POST/PUT requests) info["body"] = QString::fromUtf8(request.body()); // Get specific header value QByteArray contentType = request.value("Content-Type"); info["contentType"] = QString::fromUtf8(contentType); // Get all headers const QHttpHeaders &headers = request.headers(); QJsonObject headerObj; for (qsizetype i = 0; i < headers.size(); ++i) { headerObj[QString::fromUtf8(headers.nameAt(i))] = QString::fromUtf8(headers.valueAt(i)); } info["headers"] = headerObj; // Get query parameters QUrlQuery query = request.query(); QJsonObject queryObj; for (const auto &pair : query.queryItems()) { queryObj[pair.first] = pair.second; } info["query"] = queryObj; // Get client information info["remoteAddress"] = request.remoteAddress().toString(); info["remotePort"] = request.remotePort(); info["localAddress"] = request.localAddress().toString(); info["localPort"] = request.localPort(); return QHttpServerResponse(info); }); // Example request: GET /request-info?name=test&value=123 // Returns JSON with all request details ``` -------------------------------- ### Control HTTP Responses with QHttpServerResponder Source: https://context7.com/qt/qthttpserver/llms.txt Demonstrates how to use QHttpServerResponder for direct response handling, including sending JSON documents, performing chunked transfers, and including trailer headers in chunked responses. ```cpp #include #include #include QHttpServer httpServer; httpServer.route("/stream", [](const QHttpServerRequest &request, QHttpServerResponder &&responder) { QHttpHeaders headers; headers.append(QHttpHeaders::WellKnownHeader::ContentType, "text/plain"); responder.write(QByteArray("Direct response data"), headers, QHttpServerResponder::StatusCode::Ok); }); httpServer.route("/json-doc", [](QHttpServerResponder &&responder) { QJsonObject data{{"status", "ok"}, {"timestamp", QDateTime::currentSecsSinceEpoch()}}; QJsonDocument doc(data); responder.write(doc, QHttpServerResponder::StatusCode::Ok); }); httpServer.route("/chunked", [](QHttpServerResponder &&responder) { QHttpHeaders headers; headers.append(QHttpHeaders::WellKnownHeader::ContentType, "text/plain"); responder.writeBeginChunked(headers, QHttpServerResponder::StatusCode::Ok); responder.writeChunk("First chunk of data\n"); responder.writeChunk("Second chunk of data\n"); responder.writeChunk("Third chunk of data\n"); responder.writeEndChunked(QByteArray()); }); httpServer.route("/chunked-trailers", [](QHttpServerResponder &&responder) { QHttpHeaders headers; headers.append(QHttpHeaders::WellKnownHeader::ContentType, "application/octet-stream"); QList trailerNames = { QHttpHeaders::WellKnownHeader::ContentMD5 }; responder.writeBeginChunked(headers, trailerNames, QHttpServerResponder::StatusCode::Ok); responder.writeChunk("data chunk 1"); responder.writeChunk("data chunk 2"); QHttpHeaders trailers; trailers.append(QHttpHeaders::WellKnownHeader::ContentMD5, "abc123hash"); responder.writeEndChunked(QByteArray(), trailers); }); ``` -------------------------------- ### Configure Qt HTTP Server Logging at Runtime Source: https://context7.com/qt/qthttpserver/llms.txt This C++ code snippet demonstrates how to set up a Qt HTTP Server that allows runtime configuration of logging filters. It enables all Qt HTTP Server logging by default and provides an HTTP endpoint '/loggingFilter' to dynamically update logging rules based on query parameters. Another endpoint '/loggingStatus' is available to check the current logging status. ```cpp #include #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QHttpServer server; auto tcpserver = std::make_unique(); if (!tcpserver->listen(QHostAddress::LocalHost, 8000) || !server.bind(tcpserver.get())) return -1; tcpserver.release(); // Enable all Qt HTTP Server logging at startup QLoggingCategory::setFilterRules("qt.httpserver=true"); // Route to dynamically change logging configuration server.route("/loggingFilter", [](const QHttpServerRequest &request) { QString filter; QTextStream result(&filter); // Build filter rules from query parameters // Example: ?qt.httpserver=true&qt.httpserver.debug=false for (const auto &pair : request.query().queryItems()) { if (!filter.isEmpty()) result << "\n"; result << pair.first << "=" << pair.second; } // Apply new filter rules QLoggingCategory::setFilterRules(filter); return QJsonObject{ {"message", "Logging filter updated"}, {"filter", filter} }; }); // Route to check current logging status server.route("/loggingStatus", []() { return QJsonObject{ {"qt.httpserver", QLoggingCategory("qt.httpserver").isDebugEnabled()}, {"info", "Use /loggingFilter?category=true|false to configure"} }; }); qInfo() << "Server running on http://127.0.0.1:8000/"; qInfo() << "Configure logging at: http://127.0.0.1:8000/loggingFilter?qt.httpserver=true"; return app.exec(); } // Enable logging via URL: // http://127.0.0.1:8000/loggingFilter?qt.httpserver=true&qt.httpserver.request=true ``` -------------------------------- ### QHttpServerResponse: Constructing HTTP Responses Source: https://context7.com/qt/qthttpserver/llms.txt Illustrates various ways to create HTTP responses using QHttpServerResponse. This includes generating responses with plain text, JSON objects, JSON arrays, custom status codes, custom MIME types, serving static files, and adding custom headers. This is essential for building web APIs and services with Qt. ```cpp #include #include #include #include QHttpServer httpServer; // Plain text response (default status 200 OK) httpServer.route("/text", []() { return QHttpServerResponse("Hello, World!"); }); // JSON object response httpServer.route("/json-object", []() { return QHttpServerResponse(QJsonObject{ {"message", "Success"}, {"code", 200} }); }); // JSON array response httpServer.route("/json-array", []() { return QHttpServerResponse(QJsonArray{ QJsonObject{{"id", 1}}, QJsonObject{{"id", 2}} }); }); // Response with custom status code httpServer.route("/not-found", []() { return QHttpServerResponse(QHttpServerResponder::StatusCode::NotFound); }); // Response with custom MIME type httpServer.route("/xml", []() { QByteArray xmlData = "data"; return QHttpServerResponse("application/xml", xmlData); }); // Serve static file httpServer.route("/assets/", [](const QUrl &url) { return QHttpServerResponse::fromFile(":/assets/" + url.path()); }); // Response with custom headers httpServer.route("/custom-headers", []() { QHttpServerResponse response("Custom response"); QHttpHeaders headers = response.headers(); headers.append(QHttpHeaders::WellKnownHeader::CacheControl, "no-cache"); headers.append("X-Custom-Header", "CustomValue"); response.setHeaders(std::move(headers)); return response; }); // Error response with message httpServer.route("/error", []() { return QHttpServerResponse("text/plain", "Bad Request: Invalid parameters", QHttpServerResponder::StatusCode::BadRequest); }) ``` -------------------------------- ### Configure Qt HTTP Server Project with CMake Source: https://github.com/qt/qthttpserver/blob/dev/doc/snippets/custom-converter/CMakeLists.txt This CMake configuration initializes a C++ project, finds the Qt6 HttpServer component, and links it to the project executable. It ensures the necessary dependencies are resolved for building a custom HTTP server application. ```cmake cmake_minimum_required(VERSION 3.16) project(custom-converter LANGUAGES CXX) find_package(Qt6 REQUIRED COMPONENTS HttpServer) qt_standard_project_setup() qt_add_executable(custom-converter main.cpp ) target_link_libraries(custom-converter PRIVATE Qt6::HttpServer ) ``` -------------------------------- ### QHttpServer Configuration API Source: https://context7.com/qt/qthttpserver/llms.txt Configure server limits, rate limiting, connection management, and IP filtering for security and performance. ```APIDOC ## QHttpServerConfiguration ### Description Configure server limits, rate limiting, connection management, and IP filtering for security and performance. ### Method N/A (Configuration setup) ### Endpoint N/A (Applies to the entire server) ### Parameters N/A (Configuration is done via QHttpServerConfiguration object) ### Request Example ```cpp #include #include #include QHttpServer httpServer; QHttpServerConfiguration config; // Rate limiting - maximum requests per second per client config.setRateLimitPerSecond(100); // Connection limits config.setMaximumConnectionsPerHost(10); // Keep-alive timeout config.setKeepAliveTimeout(std::chrono::seconds(30)); // Request size limits config.setMaximumUrlSize(8192); config.setMaximumBodySize(10 * 1024 * 1024); config.setMaximumTotalHeaderSize(32768); config.setMaximumHeaderFieldSize(8192); config.setMaximumHeaderFieldCount(100); // IP whitelist QList> whitelist = { {QHostAddress("192.168.1.0"), 24}, {QHostAddress("10.0.0.0"), 8}, {QHostAddress::LocalHost, 32} }; config.setWhitelist(whitelist); // IP blacklist QList> blacklist = { {QHostAddress("192.168.1.100"), 32} }; config.setBlacklist(blacklist); // Apply configuration to server httpServer.setConfiguration(config); ``` ### Response N/A (Configuration is applied directly to the server) ### Response Example N/A ``` -------------------------------- ### Handle WebSocket Upgrades with Custom Verification in QHttpServer (C++) Source: https://context7.com/qt/qthttpserver/llms.txt This C++ code demonstrates how to add a WebSocket upgrade verifier to QHttpServer. It allows for custom logic to accept or deny upgrade requests based on the path and authentication headers. It also shows how to handle incoming WebSocket connections and messages. ```cpp #include #include #include QHttpServer httpServer; // Add WebSocket upgrade verifier httpServer.addWebSocketUpgradeVerifier(&httpServer, [](const QHttpServerRequest &request) { // Check the requested WebSocket path QString path = request.url().path(); if (path == "/ws/chat") { // Accept upgrade for chat endpoint return QHttpServerWebSocketUpgradeResponse::accept(); } if (path == "/ws/admin") { // Verify authentication for admin WebSocket auto authHeader = request.value("authorization"); if (authHeader.isEmpty()) { return QHttpServerWebSocketUpgradeResponse::deny( 401, "Authentication required"); } return QHttpServerWebSocketUpgradeResponse::accept(); } // Pass to next handler or deny return QHttpServerWebSocketUpgradeResponse::passToNext(); }); // Connect to newWebSocketConnection signal to handle new connections QObject::connect(&httpServer, &QHttpServer::newWebSocketConnection, [&httpServer]() { while (httpServer.hasPendingWebSocketConnections()) { std::unique_ptr socket = httpServer.nextPendingWebSocketConnection(); // Handle WebSocket messages QObject::connect(socket.get(), &QWebSocket::textMessageReceived, [](const QString &message) { qDebug() << "Received:" << message; }); QObject::connect(socket.get(), &QWebSocket::disconnected, [socket = socket.get()]() { qDebug() << "WebSocket disconnected"; socket->deleteLater(); }); // Send welcome message socket->sendTextMessage("Connected to WebSocket server"); // Transfer ownership socket.release(); } }); ``` -------------------------------- ### CMake Configuration for Qt HttpServer Source: https://github.com/qt/qthttpserver/blob/dev/tests/auto/cmake/CMakeLists.txt This CMake script configures the build for the Qt HttpServer module. It sets up the project, finds necessary Qt packages, and prepares for testing. It ensures that the Qt HttpServer module and its dependencies are correctly integrated into the build process. ```cmake # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause # This is an automatic test for the CMake configuration files. # To run it manually, # 1) mkdir build # Create a build directory # 2) cd build # 3) # Run cmake on this directory # `$qt_prefix/bin/qt-cmake ..` or `cmake -DCMAKE_PREFIX_PATH=/path/to/qt ..` # 4) ctest # Run ctest cmake_minimum_required(VERSION 3.16) project(httpserver_cmake_tests) enable_testing() set(required_packages Core HttpServer) # Setup the test when called as a completely standalone project. if(TARGET Qt6::Core) # Tests are built as part of the repository's build tree. # Setup paths so that the Qt packages are found. qt_internal_set_up_build_dir_package_paths() endif() find_package(Qt6 REQUIRED COMPONENTS ${required_packages}) # Setup common test variables which were previously set by ctest_testcase_common.prf. set(CMAKE_MODULES_UNDER_TEST "${required_packages}") foreach(qt_package ${CMAKE_MODULES_UNDER_TEST}) set(package_name "${QT_CMAKE_EXPORT_NAMESPACE}${qt_package}") if(${package_name}_FOUND) set(CMAKE_${qt_package}_MODULE_MAJOR_VERSION "${${package_name}_VERSION_MAJOR}") set(CMAKE_${qt_package}_MODULE_MINOR_VERSION "${${package_name}_VERSION_MINOR}") set(CMAKE_${qt_package}_MODULE_PATCH_VERSION "${${package_name}_VERSION_PATCH}") endif() endforeach() include("${_Qt6CTestMacros}") set(module_includes HttpServer QHttpServer ) _qt_internal_test_module_includes( ${module_includes} ) ``` -------------------------------- ### Implement HTTP Basic Authentication in QHttpServer Source: https://context7.com/qt/qthttpserver/llms.txt This snippet shows how to implement HTTP Basic Authentication (RFC 7617) in QHttpServer. It includes a public route and a protected route that validates username and password credentials sent via the Authorization header. It also demonstrates how to return a 401 Unauthorized response with the correct WWW-Authenticate header. ```cpp #include #include #include QHttpServer httpServer; // Public route - no authentication required httpServer.route("/", []() { return "Welcome! Visit /protected for authenticated content."; }); // Protected route with Basic Authentication httpServer.route("/protected", [](const QHttpServerRequest &request) { auto auth = request.value("authorization").simplified(); if (auth.size() > 6 && auth.first(6).toLower() == "basic ") { auto token = auth.sliced(6); auto userPass = QByteArray::fromBase64(token); if (auto colon = userPass.indexOf(':'); colon > 0) { auto userId = userPass.first(colon); auto password = userPass.sliced(colon + 1); // Validate credentials (use secure storage in production!) if (userId == "admin" && password == "secret123") { return QHttpServerResponse(QJsonObject{ {"message", "Welcome, authenticated user!"}, {"user", QString::fromUtf8(userId)} }); } } } // Return 401 Unauthorized with WWW-Authenticate header QHttpServerResponse response("text/plain", "Authentication required", QHttpServerResponse::StatusCode::Unauthorized); auto headers = response.headers(); headers.append(QHttpHeaders::WellKnownHeader::WWWAuthenticate, R"(Basic realm="Protected Area", charset="UTF-8")"); response.setHeaders(std::move(headers)); return response; }); // Token-based authentication example httpServer.route("/api/data", [](const QHttpServerRequest &request) { auto authHeader = request.value("authorization"); if (authHeader.startsWith("Bearer ")) { QString token = QString::fromUtf8(authHeader.mid(7)); // Validate token (implement your token validation logic) if (token == "valid-api-token-12345") { return QHttpServerResponse(QJsonObject{{"data", "Secret API data"}}); } } return QHttpServerResponse(QHttpServerResponder::StatusCode::Unauthorized); }); ``` -------------------------------- ### Add Qt HTTP Server Responder Test Source: https://github.com/qt/qthttpserver/blob/dev/tests/auto/qhttpserverresponder/CMakeLists.txt This snippet demonstrates how to add a test target for the qhttpserverresponder using Qt's internal build system. It specifies the source file, required Qt library, and test data directory. ```cmake # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause # Generated from qhttpserverresponder.pro. ##################################################################### ## tst_qhttpserverresponder Test: ##################################################################### # Collect test data list(APPEND test_data "data/") qt_internal_add_test(tst_qhttpserverresponder SOURCES tst_qhttpserverresponder.cpp LIBRARIES Qt::HttpServer TESTDATA ${test_data} ) ```