Android

Android native web / httpd server with directory indexer.

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’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 did the job that:

  • was single threaded (to avoid issues with threads / forks etc)
  • supported basic file browsing so I could download files just using a web browser

The advantage is that you can share anything from your phone, as long as there’s WiFi available (the other phone doesn’t need to be an Android, anything with WiFi and a browser that can download content).

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’ve located one which seemed to do the job, and also came free under BSD License.

Download

webserver-1.1.zip

Archive contents:

  • webserver – Android binary
  • LICENSE – initial BSD License
  • android_port.patch – BSD licensed patch for webserver.c
  • README.txt – description on how to install / compile.

The original webserver.c source code is not included, please download it from the creator’s web site.

Change log

v1.0 – 21 Aug 2011
Initial port to Android
v1.1 – 23 Aug 2011
Added command line options
Added listing of all local IPs (helps a lot to find out the WiFi IP)
Added Basic HTTP authentication for security

Installing

Phone needs to be rooted. Also, since most mobile carriers block incoming traffic, you won’t probably be able to access your phone via GSM/3G data connection, only over WiFi.

You need to unpack the archive, and extract the webserver binary to a directory of your choice. Then:

adb push webserver /sdcard/
adb shell
su
cd /system/bin
cp /sdcard/webserver .
chmod 755 webserver
./webserver -u  -p  -s 

If you still want to access your phone remotely even when connected to GSM/3G data only, a much more advanced configuration is needed: http://hex.ro/wp/blog/administer-your-android-phone-from-internet-root-needed/.
There are other software alternatives to access your phone remotely but they also use 3rd party servers which are maintained by their producers.

Stopping the server

a) open a different terminal
b) ps | grep webserver
c) kill

Compiling the server

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
b) download webserver.c from here: http://www.jbox.dk/sanos/webserver.htm
c) apply the included patch.
d) build it.

Porting process

The contents of the patch are shown below and discussed afterwards:

5a6,10
> // viulian (http://hex.ro) changes for Android - 21 Aug 2011
> //  * changed headers
> //  * using strcasecmp
> //  * workaround strict dirent wich doesn't have d_namlen on Android
> //  * fixed 2 small bugs (file size showed 0 and a peb reference was not found)
7d11
< #include 
12a17,20
> #include 
> #include 
> #include  // inet_ntoa
> #include  // close
106c114
<   if (stricmp(method, "GET") != 0)
---
>   if (strcasecmp(method, "GET") != 0)
150c158,159
<           if (de->d_namlen < 32) fprintf(f, "%*s", 32 - de->d_namlen, "");
---
>           int namlen = strlen(de->d_name); // viulian
>           if (namlen < 32) fprintf(f, "%*s", 32 - namlen, "");
155c164
<             fprintf(f, "%s %10d\r\n", timebuf, statbuf.st_size);
---
>             fprintf(f, "%s %10llu\r\n", timebuf, statbuf.st_size);
182c191
<   printf("HTTP server listening on port %d at %s\n", PORT, inet_ntoa(peb->ipaddr));
---
>   printf("HTTP server listening on port %d at %s\n", PORT, inet_ntoa(sin.sin_addr)); 

Porting involves many things, but among them:

  • Header files. If the build process reports an error
    warning: implicit declaration of function 'close'

    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 unistd.h had to be imported.

  • Adapt functions / structs. On Android, method stricmp does not exists, you need to use strcasecmp for this. Also, struct dirent is missing the d_namlen memeber, and by checking the documentation, that represented the length of the folder name. Length has to be computed ‘manually’
  • Pay attention to warnings reported by the compilers! In the case above, compiler complained about the size of statbuf.st_size not fitting inside the %10d of the printf method. Adjusting that to %10llu fixed the problem, and size were correctly shown, instead of 0

Improvements

There are two major things that I would like to add in the future:

  1. File upload
  2. Sorting alphabetically and folders first

Happy native Android trips 🙂

1 Comment

  1. Hi viulian. Thank you for the great effort. Unfortunately, it’s not working on my Note 3 (Android 5). The error message is: “only position independent executables (pie) are supported”. Is there any chance you can rebuild it to work with newer OS versions? Or, perhaps, you have found an alternative binary for the same task? My intent is to serve local files just locally for apps that can embed and process http/ftp/email text links only.

    All the best,
    Alex.

Leave a Reply