{"id":846,"date":"2012-02-09T22:30:47","date_gmt":"2012-02-09T14:30:47","guid":{"rendered":"http:\/\/www.awaysoft.com\/taor\/?p=846"},"modified":"2013-12-23T11:00:23","modified_gmt":"2013-12-23T03:00:23","slug":"%e6%af%95%e8%ae%be%e7%ac%94%e8%ae%b0-%e4%bd%bf%e7%94%a8libsoup%e5%86%99%e7%ae%80%e5%8d%95%e7%9a%84http%e6%9c%8d%e5%8a%a1%e5%99%a8","status":"publish","type":"post","link":"https:\/\/actom.me\/blog\/%e6%af%95%e8%ae%be%e7%ac%94%e8%ae%b0-%e4%bd%bf%e7%94%a8libsoup%e5%86%99%e7%ae%80%e5%8d%95%e7%9a%84http%e6%9c%8d%e5%8a%a1%e5%99%a8.html","title":{"rendered":"\u6bd5\u8bbe\u7b14\u8bb0 \u4f7f\u7528LibSoup\u5199\u7b80\u5355\u7684HTTP\u670d\u52a1\u5668"},"content":{"rendered":"<p>WebkitGtk\u5728Windows\u4e0b\u7684\u5b8c\u6210\u5ea6\u8fdc\u8fdc\u6ca1\u6709\u8fbe\u5230Linux\u7684\u6c34\u5e73\u3002<br \/>\n\u5728Windows\u4e0b\u505a\u6d4b\u8bd5\u7684\u65f6\u5019\u53d1\u73b0\u4e86\u4e00\u4e2a\u5f88\u5927\u7684\u95ee\u9898\uff0cWebkitGtk\u5728Windows\u4e0b\u5c45\u7136\u4e0d\u80fd\u8f7d\u5165\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6\u3002<br \/>\n\u8003\u8651\u5230\u5b83\u53ef\u4ee5\u8f7d\u5165http\u534f\u8bae\u7684\u6587\u4ef6\uff0c\u800cWebkitGtk\u4f9d\u8d56libsoup\uff0c\u7814\u7a76\u4e86\u4e0bLibsoup\u7684tests\uff0c\u5199\u4e86\u4e00\u4e2a\u7b80\u5355\u7684http\u670d\u52a1\u5668\u3002<\/p>\n<pre class=\"lang:c decode:true crayon-selected\">#include &lt;libsoup\/soup.h&gt;\r\n\r\nstatic void\r\ndo_get (SoupServer *server, SoupMessage *msg, const char *path)\r\n{\r\nchar *slash;\r\nstruct stat st;\r\nint fd;\r\nstatic char *path2 = NULL;\r\n\r\nif (!path2){g_free(path2); path2=NULL;}\r\npath2 = g_build_filename((const gchar *)global_get(\"htmlhome\"), path, NULL);\r\n\r\nif (stat (path2, &amp;st) == -1) {\r\nif (errno == EPERM)\r\nsoup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);\r\nelse if (errno == ENOENT)\r\nsoup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);\r\nelse\r\nsoup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);\r\nreturn;\r\n}\r\n\r\nif (S_ISDIR (st.st_mode)) {\r\nchar *index_path;\r\n\r\nslash = strrchr (path, '\/');\r\nif (!slash || slash[1]) {\r\nchar *uri, *redir_uri;\r\n\r\nuri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);\r\nredir_uri = g_strdup_printf (\"%s\/\", uri);\r\nsoup_message_headers_append (msg-&gt;response_headers,\r\n\"Location\", redir_uri);\r\nsoup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY);\r\ng_free (redir_uri);\r\ng_free (uri);\r\nreturn;\r\n}\r\n\r\nindex_path = g_strdup_printf (\"%s\/index.html\", path);\r\nif (stat (index_path, &amp;st) != -1) {\r\ndo_get (server, msg, index_path);\r\ng_free (index_path);\r\nreturn;\r\n}\r\n\r\nchar *buf = \"&lt;title&gt;Forbidden&lt;\/title&gt;&lt;h1&gt;Forbidden&lt;\/h1&gt;\", len[10];\r\nsprintf(len, \"%d\", strlen(buf));\r\n\r\nsoup_message_body_append (msg-&gt;response_body, SOUP_MEMORY_TAKE,\r\nbuf, strlen(buf));\r\nsoup_message_headers_append (msg-&gt;response_headers,\r\n\"Content-Length\", len);\r\nsoup_message_set_status(msg, SOUP_STATUS_FORBIDDEN);\r\nreturn;\r\n}\r\n\r\nfd = open (path2, O_RDONLY);\r\nif (fd == -1) {\r\nsoup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);\r\nreturn;\r\n}\r\n\r\nif (msg-&gt;method == SOUP_METHOD_GET) {\r\nchar *buf;\r\n\r\nbuf = g_malloc (st.st_size);\r\nread (fd, buf, st.st_size);\r\nclose (fd);\r\nsoup_message_body_append (msg-&gt;response_body, SOUP_MEMORY_TAKE,\r\nbuf, st.st_size);\r\n} else \/* msg-&gt;method == SOUP_METHOD_HEAD *\/ {\r\nchar *length;\r\n\r\n\/* We could just use the same code for both GET and\r\n* HEAD. But we'll optimize and avoid the extra\r\n* malloc.\r\n*\/\r\nlength = g_strdup_printf (\"%lu\", (gulong)st.st_size);\r\nsoup_message_headers_append (msg-&gt;response_headers,\r\n\"Content-Length\", length);\r\ng_free (length);\r\n}\r\n\r\nsoup_message_set_status (msg, SOUP_STATUS_OK);\r\n}\r\n\r\nstatic void\r\ndo_put (SoupServer *server, SoupMessage *msg, const char *path)\r\n{\r\nstruct stat st;\r\nFILE *f;\r\ngboolean created = TRUE;\r\nstatic char *path2 = NULL;\r\n\r\nif (!path2){g_free(path2); path2=NULL;}\r\n\r\npath2 = g_build_filename((const gchar *)global_get(\"htmlhome\"), path, NULL);\r\n\r\nif (stat (path2, &amp;st) != -1) {\r\nconst char *match = soup_message_headers_get_one (msg-&gt;request_headers, \"If-None-Match\");\r\nif (match &amp;&amp; !strcmp (match, \"*\")) {\r\nsoup_message_set_status (msg, SOUP_STATUS_CONFLICT);\r\nreturn;\r\n}\r\n\r\nif (!S_ISREG (st.st_mode)) {\r\nsoup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);\r\nreturn;\r\n}\r\n\r\ncreated = FALSE;\r\n}\r\n\r\nf = fopen (path2, \"w\");\r\nif (!f) {\r\nsoup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);\r\nreturn;\r\n}\r\n\r\nfwrite (msg-&gt;request_body-&gt;data, 1, msg-&gt;request_body-&gt;length, f);\r\nfclose (f);\r\n\r\nsoup_message_set_status (msg, created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK);\r\n}\r\n\r\nstatic void\r\nserver_callback (SoupServer *server, SoupMessage *msg,\r\nconst char *path, GHashTable *query,\r\nSoupClientContext *context, gpointer data)\r\n{\r\nSoupMessageHeadersIter iter;\r\n\r\nsoup_message_headers_iter_init (&amp;iter, msg-&gt;request_headers);\r\n\r\nif (msg-&gt;method == SOUP_METHOD_GET || msg-&gt;method == SOUP_METHOD_HEAD)\r\ndo_get (server, msg, path);\r\nelse if (msg-&gt;method == SOUP_METHOD_PUT)\r\ndo_put (server, msg, path);\r\nelse\r\nsoup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);\r\n}\r\n\r\nint init_server()\r\n{\r\nSoupServer *server;\r\nint port = SOUP_ADDRESS_ANY_PORT;\r\n\r\nserver = soup_server_new (SOUP_SERVER_PORT, port,\r\nSOUP_SERVER_SERVER_HEADER, \"AwayFramework \",\r\nNULL);\r\nif (!server) {\r\ng_log(\"AFR\", G_LOG_LEVEL_ERROR, \"Unable to bind to server port %d\\n\", port);\r\nreturn -1;\r\n}\r\n\r\nsoup_server_add_handler (server, NULL,\r\nserver_callback, NULL, NULL);\r\ng_log(\"AFR\", G_LOG_LEVEL_INFO, \"Starting Server on port %d\",\r\nsoup_server_get_port (server));\r\nsoup_server_run_async (server);\r\n\r\nreturn soup_server_get_port (server);\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>WebkitGtk\u5728Windows\u4e0b\u7684\u5b8c\u6210\u5ea6\u8fdc\u8fdc\u6ca1\u6709\u8fbe\u5230Linux\u7684\u6c34\u5e73\u3002 \u5728W &#8230; <a class=\"more-link\" href=\"https:\/\/actom.me\/blog\/%e6%af%95%e8%ae%be%e7%ac%94%e8%ae%b0-%e4%bd%bf%e7%94%a8libsoup%e5%86%99%e7%ae%80%e5%8d%95%e7%9a%84http%e6%9c%8d%e5%8a%a1%e5%99%a8.html\">Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,1,6],"tags":[],"_links":{"self":[{"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/posts\/846"}],"collection":[{"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/comments?post=846"}],"version-history":[{"count":3,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/posts\/846\/revisions"}],"predecessor-version":[{"id":905,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/posts\/846\/revisions\/905"}],"wp:attachment":[{"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/media?parent=846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/categories?post=846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/actom.me\/blog\/wp-json\/wp\/v2\/tags?post=846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}