libsoup的简单使用

基于GLib和libsoup的简单Web服务器示例,它可以处理静态HTML文件和动态JSON请求,并展示如何获取URL参数。

步骤:

  1. 初始化GLib和libsoup。
  2. 创建一个处理静态HTML文件的处理器。
  3. 创建一个处理动态JSON请求的处理器。
  4. 获取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;
}

编译和运行:

  1. 确保安装了gliblibsoup库。
  2. 使用以下命令编译代码:
    gcc -o webserver webserver.c `pkg-config --cflags --libs glib-2.0 libsoup-2.4`
    
  3. 运行生成的可执行文件:
    ./webserver
    

这个示例展示了如何使用libsoup创建一个简单的Web服务器,处理静态HTML文件和动态JSON请求,并获取URL参数。你可以根据需要扩展和修改这个示例。

soup_message_body_append 函数

GitHub Copilot: 在libsoup中,soup_message_body_append函数用于将数据添加到SoupMessageBody中。该函数的第二个参数是一个枚举类型,用于指定如何处理传入的数据。这个枚举类型是SoupMemoryUse,它定义了几种不同的内存管理策略。

SoupMemoryUse 枚举类型

以下是SoupMemoryUse枚举类型的几种常见值及其含义:

  1. SOUP_MEMORY_STATIC:

    • 表示传入的数据是静态的,不会被修改或释放。
    • 适用于常量字符串或全局变量。
    • 例子:
      const char *static_data = "Hello, World!";
      soup_message_body_append(body, SOUP_MEMORY_STATIC, static_data, strlen(static_data));
      
  2. SOUP_MEMORY_TEMPORARY:

    • 表示传入的数据是临时的,libsoup会在内部复制一份。
    • 适用于临时变量或局部变量。
    • 例子:
      char temp_data[] = "Temporary Data";
      soup_message_body_append(body, SOUP_MEMORY_TEMPORARY, temp_data, strlen(temp_data));
      
  3. 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); // 原始数据可以安全释放
      
  4. 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;
}

通过这些枚举值,你可以灵活地管理传入数据的内存,确保在不同场景下的内存安全和效率。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值