{"id":1116,"date":"2011-08-21T11:10:20","date_gmt":"2011-08-21T09:10:20","guid":{"rendered":"http:\/\/hex.ro\/wp\/?p=1116"},"modified":"2011-09-22T19:53:37","modified_gmt":"2011-09-22T17:53:37","slug":"android-native-web-httpd-server-with-directory-indexer","status":"publish","type":"post","link":"https:\/\/hex.ro\/wp\/blog\/android-native-web-httpd-server-with-directory-indexer\/","title":{"rendered":"Android native web \/ httpd server with directory indexer."},"content":{"rendered":"<p><strong>Introduction<\/strong><\/p>\n<p>Having a fully fledged natively built web server on Android is not possible because of issues with fork() and pthread inherent to the slim libc implementation from Google, that is bionic. For more details about these Android&#8217;s limitations please start here: http:\/\/groups.google.com\/group\/android-ndk\/browse_thread\/thread\/1dfa066e20175c5a\/e4c79372d365f5e3.<\/p>\n<p>I was looking to find a small web server \/ httpd that did the job  that:<\/p>\n<ul>\n<li>was single threaded (to avoid issues with threads \/ forks etc)<\/li>\n<li>supported basic file browsing so I could download files just using a web browser<\/li>\n<\/ul>\n<p>The <strong>advantage<\/strong> is that you can share anything from your phone, as long as there&#8217;s WiFi available (the other phone doesn&#8217;t need to be an Android, anything with WiFi and a browser that can download content).<\/p>\n<p>There are a LOT of basic C httpd servers out there written for demo purposes but they can only serve .html files. With some Google foo, I&#8217;ve located <a href=\"http:\/\/www.jbox.dk\/sanos\/webserver.htm\">one<\/a> which seemed to do the job, and also came free under <a href=\"http:\/\/www.jbox.dk\/sanos\/copying.txt\">BSD License<\/a>.<\/p>\n<p><strong>Download<\/strong><\/p>\n<p><a href=\"http:\/\/hex.ro\/tracker\/EasyTracker.php?id=32\">webserver-1.1.zip<\/a><\/p>\n<p>Archive contents:<\/p>\n<ul>\n<li>webserver &#8211; Android binary<\/li>\n<li>LICENSE  &#8211; initial BSD License<\/li>\n<li>android_port.patch &#8211; BSD licensed patch for webserver.c<\/li>\n<li>README.txt &#8211; description on how to install \/ compile.<\/li>\n<\/ul>\n<p>The original webserver.c source code is not included, please download it from the creator&#8217;s <a href=\"http:\/\/www.jbox.dk\/sanos\/webserver.htm\">web site<\/a>.<\/p>\n<p><strong>Change log<\/strong><\/p>\n<p>v1.0 &#8211; 21 Aug 2011<br \/>\n   Initial port to Android<br \/>\nv1.1 &#8211; 23 Aug 2011<br \/>\n   Added command line options<br \/>\n   Added listing of all local IPs (helps a lot to find out the WiFi IP)<br \/>\n   Added Basic HTTP authentication for security <\/p>\n<p><strong>Installing<\/strong><\/p>\n<p>Phone needs to be rooted. Also, since most mobile carriers block incoming traffic, you won&#8217;t probably be able to access your phone via GSM\/3G data connection, only over WiFi.<\/p>\n<p>You need to unpack the archive, and extract the webserver binary to a directory of your choice. Then:<\/p>\n<pre class=\"lang: bash\">\r\nadb push webserver \/sdcard\/\r\nadb shell\r\nsu\r\ncd \/system\/bin\r\ncp \/sdcard\/webserver .\r\nchmod 755 webserver\r\n.\/webserver -u <username> -p <password> -s <port>\r\n<\/pre>\n<p>If you still want to access your phone remotely even when connected to GSM\/3G data only, a much more advanced configuration is needed:<a href=\"http:\/\/hex.ro\/wp\/blog\/administer-your-android-phone-from-internet-root-needed\/\"> http:\/\/hex.ro\/wp\/blog\/administer-your-android-phone-from-internet-root-needed\/<\/a>.<br \/>\nThere are other software alternatives to access your phone remotely but they also use 3rd party servers which are maintained by their producers.<\/p>\n<p><strong>Stopping the server<\/strong><\/p>\n<p>a) open a different terminal<br \/>\nb) ps | grep webserver<br \/>\nc) kill <pid_of_webserver>\n<p><strong>Compiling the server<\/strong><\/p>\n<p>a) you need to have a build system which is able to generate native ARM code. For starting, please check this web site: http:\/\/betelco.blogspot.com\/2010\/01\/buildingdebugging-android-native-c.html<br \/>\nb) download webserver.c from here: http:\/\/www.jbox.dk\/sanos\/webserver.htm<br \/>\nc) apply the included patch.<br \/>\nd) build it.<\/p>\n<p><strong>Porting process<\/strong><\/p>\n<p>The contents of the patch are shown below and discussed afterwards:<\/p>\n<pre class=\"lang: cpp\">5a6,10\r\n> \/\/ viulian (http:\/\/hex.ro) changes for Android - 21 Aug 2011\r\n> \/\/  * changed headers\r\n> \/\/  * using strcasecmp\r\n> \/\/  * workaround strict dirent wich doesn't have d_namlen on Android\r\n> \/\/  * fixed 2 small bugs (file size showed 0 and a peb reference was not found)\r\n7d11\r\n< #include <os.h>\r\n12a17,20\r\n> #include <sys\/socket.h>\r\n> #include <linux\/in.h>\r\n> #include <arpa\/inet.h> \/\/ inet_ntoa\r\n> #include <unistd.h> \/\/ close\r\n106c114\r\n<   if (stricmp(method, \"GET\") != 0)\r\n---\r\n>   if (strcasecmp(method, \"GET\") != 0)\r\n150c158,159\r\n<           if (de->d_namlen < 32) fprintf(f, \"%*s\", 32 - de->d_namlen, \"\");\r\n---\r\n>           int namlen = strlen(de->d_name); \/\/ viulian\r\n>           if (namlen < 32) fprintf(f, \"%*s\", 32 - namlen, \"\");\r\n155c164\r\n<             fprintf(f, \"%s %10d\\r\\n\", timebuf, statbuf.st_size);\r\n---\r\n>             fprintf(f, \"%s %10llu\\r\\n\", timebuf, statbuf.st_size);\r\n182c191\r\n<   printf(\"HTTP server listening on port %d at %s\\n\", PORT, inet_ntoa(peb->ipaddr));\r\n---\r\n>   printf(\"HTTP server listening on port %d at %s\\n\", PORT, inet_ntoa(sin.sin_addr)); <\/pre>\n<p>Porting involves many things, but among them:<\/p>\n<ul>\n<li><em>Header files<\/em>. If the build process reports an error\n<pre class=\"lang: bash\">warning: implicit declaration of function 'close'<\/pre>\n<p>then you need to search the includes folders for which header contains the definition, and add that to the source file. For the error above, the file <code>unistd.h<\/code> had to be imported.<\/li>\n<li><em>Adapt functions \/ structs<\/em>. On Android, method <code>stricmp<\/code> does not exists, you need to use <code>strcasecmp<\/code> for this. Also, <code>struct dirent<\/code> is missing the <code>d_namlen<\/code> memeber, and by checking the documentation, that represented the length of the folder name. Length has to be computed &#8216;manually&#8217;<\/li>\n<li>Pay attention to <em>warnings<\/em> reported by the compilers! In the case above, compiler complained about the size of <code>statbuf.st_size<\/code> not fitting inside the <code>%10d<\/code> of the printf method. Adjusting that to <code>%10llu<\/code> fixed the problem, and size were correctly shown, instead of 0<\/li>\n<\/ul>\n<p><strong>Improvements<\/strong><\/p>\n<p>There are two major things that I would like to add in the future:<\/p>\n<ol>\n<li>File upload<\/li>\n<li>Sorting alphabetically and folders first<\/li>\n<\/ol>\n<p>Happy native Android trips \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Having a fully fledged natively built web server on Android is not possible because of issues with fork() and pthread inherent to the slim libc implementation from Google, that is bionic. For more details about these Android&#8217;s limitations please start here: http:\/\/groups.google.com\/group\/android-ndk\/browse_thread\/thread\/1dfa066e20175c5a\/e4c79372d365f5e3. I was looking to find a small web server \/ httpd that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33],"tags":[],"class_list":["post-1116","post","type-post","status-publish","format-standard","hentry","category-android"],"_links":{"self":[{"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/posts\/1116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/comments?post=1116"}],"version-history":[{"count":2,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/posts\/1116\/revisions"}],"predecessor-version":[{"id":1118,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/posts\/1116\/revisions\/1118"}],"wp:attachment":[{"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/media?parent=1116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/categories?post=1116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hex.ro\/wp\/wp-json\/wp\/v2\/tags?post=1116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}