WebkitGtk在Windows下的完成度远远没有达到Linux的水平。
在Windows下做测试的时候发现了一个很大的问题,WebkitGtk在Windows下居然不能载入磁盘上的文件。
考虑到它可以载入http协议的文件,而WebkitGtk依赖libsoup,研究了下Libsoup的tests,写了一个简单的http服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
#include <libsoup/soup.h> static void do_get (SoupServer *server, SoupMessage *msg, const char *path) { char *slash; struct stat st; int fd; static char *path2 = NULL; if (!path2){g_free(path2); path2=NULL;} path2 = g_build_filename((const gchar *)global_get("htmlhome"), path, NULL); if (stat (path2, &st) == -1) { if (errno == EPERM) soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); else if (errno == ENOENT) soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); else soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } if (S_ISDIR (st.st_mode)) { char *index_path; slash = strrchr (path, '/'); if (!slash || slash[1]) { char *uri, *redir_uri; uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE); redir_uri = g_strdup_printf ("%s/", uri); soup_message_headers_append (msg->response_headers, "Location", redir_uri); soup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY); g_free (redir_uri); g_free (uri); return; } index_path = g_strdup_printf ("%s/index.html", path); if (stat (index_path, &st) != -1) { do_get (server, msg, index_path); g_free (index_path); return; } char *buf = "<title>Forbidden</title><h1>Forbidden</h1>", len[10]; sprintf(len, "%d", strlen(buf)); soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE, buf, strlen(buf)); soup_message_headers_append (msg->response_headers, "Content-Length", len); soup_message_set_status(msg, SOUP_STATUS_FORBIDDEN); return; } fd = open (path2, O_RDONLY); if (fd == -1) { soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } if (msg->method == SOUP_METHOD_GET) { char *buf; buf = g_malloc (st.st_size); read (fd, buf, st.st_size); close (fd); soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE, buf, st.st_size); } else /* msg->method == SOUP_METHOD_HEAD */ { char *length; /* We could just use the same code for both GET and * HEAD. But we'll optimize and avoid the extra * malloc. */ length = g_strdup_printf ("%lu", (gulong)st.st_size); soup_message_headers_append (msg->response_headers, "Content-Length", length); g_free (length); } soup_message_set_status (msg, SOUP_STATUS_OK); } static void do_put (SoupServer *server, SoupMessage *msg, const char *path) { struct stat st; FILE *f; gboolean created = TRUE; static char *path2 = NULL; if (!path2){g_free(path2); path2=NULL;} path2 = g_build_filename((const gchar *)global_get("htmlhome"), path, NULL); if (stat (path2, &st) != -1) { const char *match = soup_message_headers_get_one (msg->request_headers, "If-None-Match"); if (match && !strcmp (match, "*")) { soup_message_set_status (msg, SOUP_STATUS_CONFLICT); return; } if (!S_ISREG (st.st_mode)) { soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); return; } created = FALSE; } f = fopen (path2, "w"); if (!f) { soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } fwrite (msg->request_body->data, 1, msg->request_body->length, f); fclose (f); soup_message_set_status (msg, created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK); } static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SoupMessageHeadersIter iter; soup_message_headers_iter_init (&iter, msg->request_headers); if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) do_get (server, msg, path); else if (msg->method == SOUP_METHOD_PUT) do_put (server, msg, path); else soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); } int init_server() { SoupServer *server; int port = SOUP_ADDRESS_ANY_PORT; server = soup_server_new (SOUP_SERVER_PORT, port, SOUP_SERVER_SERVER_HEADER, "AwayFramework ", NULL); if (!server) { g_log("AFR", G_LOG_LEVEL_ERROR, "Unable to bind to server port %d\n", port); return -1; } soup_server_add_handler (server, NULL, server_callback, NULL, NULL); g_log("AFR", G_LOG_LEVEL_INFO, "Starting Server on port %d", soup_server_get_port (server)); soup_server_run_async (server); return soup_server_get_port (server); } |
这是在win下编译的吗
恩啦。~已经毕业了啊。。
看起来好像很强大。博主也是今年毕业?
哈哈 不行~~~~
– – 就不能用 codebox 缩进下么 评论个要拉下去好长 好纠结…
本来是有的,到了wp就没有了。。。
连个缩进都没有么。。