基于GLib和libsoup的简单Web服务器示例,它可以处理静态HTML文件和动态JSON请求,并展示如何获取URL参数。
步骤:
- 初始化GLib和libsoup。
- 创建一个处理静态HTML文件的处理器。
- 创建一个处理动态JSON请求的处理器。
- 获取URL参数并在JSON响应中返回。
代码:
#include <libsoup/soup.h>
#include <glib.h>
// 处理静态HTML文件请求
static void handle_static_html(SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) {
SoupMessageHeaders *response_headers = msg->response_headers;
soup_message_headers_set_content_type(response_headers, "text/html", NULL);
// 读取静态HTML文件
GError *error = NULL;
gchar *content = NULL;
g_file_get_contents("/path/to/static.html", &content, NULL, &error);
if (error) {
soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
soup_message_body_append(msg->response_body, SOUP_MEMORY_COPY, "Internal Server Error", 21);
g_error_free(error);
} else {
soup_message_set_status(msg, SOUP_STATUS_OK);
soup_message_body_append(msg->response_body, SOUP_MEMORY_COPY, content, strlen(content));
g_free(content);
}
soup_message_body_complete(msg->response_body);
}
// 处理动态JSON请求
static void handle_dynamic_json(SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) {
SoupMessageHeaders *response_headers = msg->response_headers;
soup_message_headers_set_content_type(response_headers, "application/json", NULL);
// 获取URL参数
const char *name = g_hash_table_lookup(query, "name");
if (!name) {
name = "World";
}
// 创建JSON响应
gchar *response = g_strdup_printf("{\"message\": \"Hello, %s!\"}", name);
soup_message_set_status(msg, SOUP_STATUS_OK);
soup_message_body_append(msg->response_body, SOUP_MEMORY_COPY, response, strlen(response));
g_free(response);
soup_message_body_complete(msg->response_body);
}
int main(int argc, char *argv[]) {
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
SoupServer *server = soup_server_new(SOUP_SERVER_SERVER_HEADER, "example-server", NULL);
// 添加处理器
soup_server_add_handler(server, "/static", handle_static_html, NULL, NULL);
soup_server_add_handler(server, "/dynamic", handle_dynamic_json, NULL, NULL);
// 监听端口
soup_server_listen_all(server, 8080, 0, NULL);
g_print("Server running on http://localhost:8080\n");
g_main_loop_run(loop);
// 清理
g_object_unref(server);
g_main_loop_unref(loop);
return 0;
}
编译和运行:
- 确保安装了
glib
和libsoup
库。 - 使用以下命令编译代码:
gcc -o webserver webserver.c `pkg-config --cflags --libs glib-2.0 libsoup-2.4`
- 运行生成的可执行文件:
./webserver
这个示例展示了如何使用libsoup创建一个简单的Web服务器,处理静态HTML文件和动态JSON请求,并获取URL参数。你可以根据需要扩展和修改这个示例。
soup_message_body_append 函数
GitHub Copilot: 在libsoup中,soup_message_body_append
函数用于将数据添加到SoupMessageBody
中。该函数的第二个参数是一个枚举类型,用于指定如何处理传入的数据。这个枚举类型是SoupMemoryUse
,它定义了几种不同的内存管理策略。
SoupMemoryUse
枚举类型
以下是SoupMemoryUse
枚举类型的几种常见值及其含义:
-
SOUP_MEMORY_STATIC:
- 表示传入的数据是静态的,不会被修改或释放。
- 适用于常量字符串或全局变量。
- 例子:
const char *static_data = "Hello, World!"; soup_message_body_append(body, SOUP_MEMORY_STATIC, static_data, strlen(static_data));
-
SOUP_MEMORY_TEMPORARY:
- 表示传入的数据是临时的,libsoup会在内部复制一份。
- 适用于临时变量或局部变量。
- 例子:
char temp_data[] = "Temporary Data"; soup_message_body_append(body, SOUP_MEMORY_TEMPORARY, temp_data, strlen(temp_data));
-
SOUP_MEMORY_COPY:
- 表示传入的数据需要被复制,libsoup会创建一份新的副本。
- 适用于需要确保数据独立于原始数据的情况。
- 例子:
char *dynamic_data = g_strdup("Dynamic Data"); soup_message_body_append(body, SOUP_MEMORY_COPY, dynamic_data, strlen(dynamic_data)); g_free(dynamic_data); // 原始数据可以安全释放
-
SOUP_MEMORY_TAKE:
- 表示传入的数据的所有权将被libsoup接管,libsoup负责释放内存。
- 适用于动态分配的内存,且不再需要手动管理内存释放。
- 例子:
char *dynamic_data = g_strdup("Dynamic Data"); soup_message_body_append(body, SOUP_MEMORY_TAKE, dynamic_data, strlen(dynamic_data)); // 不需要手动释放 dynamic_data,libsoup 会负责
示例代码
以下是一个使用SoupMemoryUse
枚举类型的示例代码:
#include <libsoup/soup.h>
#include <glib.h>
int main() {
SoupMessageBody *body = soup_message_body_new();
// 使用 SOUP_MEMORY_STATIC
const char *static_data = "Static Data";
soup_message_body_append(body, SOUP_MEMORY_STATIC, static_data, strlen(static_data));
// 使用 SOUP_MEMORY_TEMPORARY
char temp_data[] = "Temporary Data";
soup_message_body_append(body, SOUP_MEMORY_TEMPORARY, temp_data, strlen(temp_data));
// 使用 SOUP_MEMORY_COPY
char *dynamic_data_copy = g_strdup("Dynamic Data Copy");
soup_message_body_append(body, SOUP_MEMORY_COPY, dynamic_data_copy, strlen(dynamic_data_copy));
g_free(dynamic_data_copy); // 原始数据可以安全释放
// 使用 SOUP_MEMORY_TAKE
char *dynamic_data_take = g_strdup("Dynamic Data Take");
soup_message_body_append(body, SOUP_MEMORY_TAKE, dynamic_data_take, strlen(dynamic_data_take));
// 不需要手动释放 dynamic_data_take,libsoup 会负责
// 清理
soup_message_body_free(body);
return 0;
}
通过这些枚举值,你可以灵活地管理传入数据的内存,确保在不同场景下的内存安全和效率。