GTK+中文社区(gtk.awaysoft.com)

 找回密码
 马上加入

QQ登录

只需一步,快速开始

查看: 4052|回复: 2

使用LibSoup写简单的HTTP服务器

[复制链接]
  • TA的每日心情
    奋斗
    2016-10-11 09:20
  • 签到天数: 271 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2012-2-26 16:30:39 | 显示全部楼层 |阅读模式
    WebkitGtk在Windows下的完成度远远没有达到Linux的水平。
    在Windows下做测试的时候发现了一个很大的问题,WebkitGtk在Windows下居然不能载入磁盘上的文件。
    考虑到它可以载入http协议的文件,而WebkitGtk依赖libsoup,研究了下Libsoup的tests,写了一个简单的http服务器。
    1. #include <libsoup/soup.h>
    2. static void
    3. do_get (SoupServer *server, SoupMessage *msg, const char *path)
    4. {
    5. char *slash;
    6. struct stat st;
    7. int fd;
    8. static char *path2 = NULL;
    9. if (!path2){g_free(path2); path2=NULL;}
    10. path2 = g_build_filename((const gchar *)global_get("htmlhome"), path, NULL);
    11. if (stat (path2, &st) == -1) {
    12. if (errno == EPERM)
    13. soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
    14. else if (errno == ENOENT)
    15. soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
    16. else
    17. soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
    18. return;
    19. }
    20. if (S_ISDIR (st.st_mode)) {
    21. char *index_path;
    22. slash = strrchr (path, '/');
    23. if (!slash || slash[1]) {
    24. char *uri, *redir_uri;
    25. uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
    26. redir_uri = g_strdup_printf ("%s/", uri);
    27. soup_message_headers_append (msg->response_headers,
    28. "Location", redir_uri);
    29. soup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY);
    30. g_free (redir_uri);
    31. g_free (uri);
    32. return;
    33. }
    34. index_path = g_strdup_printf ("%s/index.html", path);
    35. if (stat (index_path, &st) != -1) {
    36. do_get (server, msg, index_path);
    37. g_free (index_path);
    38. return;
    39. }
    40. char *buf = "<title>Forbidden</title><h1>Forbidden</h1>", len[10];
    41. sprintf(len, "%d", strlen(buf));
    42. soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE,
    43. buf, strlen(buf));
    44. soup_message_headers_append (msg->response_headers,
    45. "Content-Length", len);
    46. soup_message_set_status(msg, SOUP_STATUS_FORBIDDEN);
    47. return;
    48. }
    49. fd = open (path2, O_RDONLY);
    50. if (fd == -1) {
    51. soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
    52. return;
    53. }
    54. if (msg->method == SOUP_METHOD_GET) {
    55. char *buf;
    56. buf = g_malloc (st.st_size);
    57. read (fd, buf, st.st_size);
    58. close (fd);
    59. soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE,
    60. buf, st.st_size);
    61. } else /* msg->method == SOUP_METHOD_HEAD */ {
    62. char *length;
    63. /* We could just use the same code for both GET and
    64. * HEAD. But we'll optimize and avoid the extra
    65. * malloc.
    66. */
    67. length = g_strdup_printf ("%lu", (gulong)st.st_size);
    68. soup_message_headers_append (msg->response_headers,
    69. "Content-Length", length);
    70. g_free (length);
    71. }
    72. soup_message_set_status (msg, SOUP_STATUS_OK);
    73. }
    74. static void
    75. do_put (SoupServer *server, SoupMessage *msg, const char *path)
    76. {
    77. struct stat st;
    78. FILE *f;
    79. gboolean created = TRUE;
    80. static char *path2 = NULL;
    81. if (!path2){g_free(path2); path2=NULL;}
    82. path2 = g_build_filename((const gchar *)global_get("htmlhome"), path, NULL);
    83. if (stat (path2, &st) != -1) {
    84. const char *match = soup_message_headers_get_one (msg->request_headers, "If-None-Match");
    85. if (match && !strcmp (match, "*")) {
    86. soup_message_set_status (msg, SOUP_STATUS_CONFLICT);
    87. return;
    88. }
    89. if (!S_ISREG (st.st_mode)) {
    90. soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
    91. return;
    92. }
    93. created = FALSE;
    94. }
    95. f = fopen (path2, "w");
    96. if (!f) {
    97. soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
    98. return;
    99. }
    100. fwrite (msg->request_body->data, 1, msg->request_body->length, f);
    101. fclose (f);
    102. soup_message_set_status (msg, created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK);
    103. }
    104. static void
    105. server_callback (SoupServer *server, SoupMessage *msg,
    106. const char *path, GHashTable *query,
    107. SoupClientContext *context, gpointer data)
    108. {
    109. SoupMessageHeadersIter iter;
    110. soup_message_headers_iter_init (&iter, msg->request_headers);
    111. if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
    112. do_get (server, msg, path);
    113. else if (msg->method == SOUP_METHOD_PUT)
    114. do_put (server, msg, path);
    115. else
    116. soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
    117. }
    118. int init_server()
    119. {
    120. SoupServer *server;
    121. int port = SOUP_ADDRESS_ANY_PORT;
    122. server = soup_server_new (SOUP_SERVER_PORT, port,
    123. SOUP_SERVER_SERVER_HEADER, "AwayFramework ",
    124. NULL);
    125. if (!server) {
    126. g_log("AFR", G_LOG_LEVEL_ERROR, "Unable to bind to server port %d\n", port);
    127. return -1;
    128. }
    129. soup_server_add_handler (server, NULL,
    130. server_callback, NULL, NULL);
    131. g_log("AFR", G_LOG_LEVEL_INFO, "Starting Server on port %d",
    132. soup_server_get_port (server));
    133. soup_server_run_async (server);
    134. return soup_server_get_port (server);
    135. }
    复制代码
    转自:http://www.awaysoft.com/taor/%e6 ... 8a%a1%e5%99%a8.html
  • TA的每日心情
    慵懒
    2013-7-6 15:08
  • 签到天数: 2 天

    连续签到: 2 天

    [LV.1]初来乍到

    发表于 2013-1-12 18:37:10 | 显示全部楼层
    看上去還是有點複雜{:soso_e122:}
  • TA的每日心情
    奋斗
    2016-10-11 09:20
  • 签到天数: 271 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-1-12 22:43:50 | 显示全部楼层
    ekd123 发表于 2013-1-12 18:37
    看上去還是有點複雜

    不到200行还好吧。。。。。仔细看看其实挺简单的
    *滑块验证:
    您需要登录后才可以回帖 登录 | 马上加入

    本版积分规则

    申请友链|Archiver|小黑屋|手机版|GTK+中文社区 ( 粤ICP备13080851号 )

    我要啦免费统计

    GMT+8, 2024-4-26 03:57 , Processed in 0.021686 second(s), 7 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表