|
@@ -396,101 +396,3 @@ variable is visible in the block that follows.
|
|
To force Civetweb to use `__stdcall` convention, add `/Gz` compilation
|
|
To force Civetweb to use `__stdcall` convention, add `/Gz` compilation
|
|
flag in Visual Studio compiler.
|
|
flag in Visual Studio compiler.
|
|
|
|
|
|
-# Embedding
|
|
|
|
-
|
|
|
|
-See [Embedding.md](https://github.com/sunsetbrew/civetweb/blob/master/docs/Embedding.md) for more information.
|
|
|
|
-
|
|
|
|
-# Build on Android
|
|
|
|
-
|
|
|
|
-This is a small guide to help you run civetweb on Android. Currently it is
|
|
|
|
-tested on the HTC Wildfire. If you have managed to run it on other devices
|
|
|
|
-as well, please comment or drop an email in the mailing list.
|
|
|
|
-Note : You dont need root access to run civetweb on Android.
|
|
|
|
-
|
|
|
|
-- Download the source from the Downloads page.
|
|
|
|
-- Download the Android NDK from [http://developer.android.com/tools/sdk/ndk/index.html](http://developer.android.com/tools/sdk/ndk/index.html)
|
|
|
|
-- Run `/path-to-ndk/ndk-build -C /path-to-civetweb/build`
|
|
|
|
- That should generate civetweb/lib/armeabi/civetweb
|
|
|
|
-- Using the adb tool (you need to have Android SDK installed for that),
|
|
|
|
- push the generated civetweb binary to `/data/local` folder on device.
|
|
|
|
-- From adb shell, navigate to `/data/local` and execute `./civetweb`.
|
|
|
|
-- To test if the server is running fine, visit your web-browser and
|
|
|
|
- navigate to `http://127.0.0.1:8080` You should see the `Index of /` page.
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Notes:
|
|
|
|
-
|
|
|
|
-- `jni` stands for Java Native Interface. Read up on Android NDK if you want
|
|
|
|
- to know how to interact with the native C functions of civetweb in Android
|
|
|
|
- Java applications.
|
|
|
|
-- TODO: A Java application that interacts with the native binary or a
|
|
|
|
- shared library.
|
|
|
|
-
|
|
|
|
-# Civetweb internals
|
|
|
|
-
|
|
|
|
-Civetweb is multithreaded web server. `mg_start()` function allocates
|
|
|
|
-web server context (`struct mg_context`), which holds all information
|
|
|
|
-about web server instance:
|
|
|
|
-
|
|
|
|
-- configuration options. Note that civetweb makes internal copies of
|
|
|
|
- passed options.
|
|
|
|
-- SSL context, if any
|
|
|
|
-- user-defined callbacks
|
|
|
|
-- opened listening sockets
|
|
|
|
-- a queue for accepted sockets
|
|
|
|
-- mutexes and condition variables for inter-thread synchronization
|
|
|
|
-
|
|
|
|
-When `mg_start()` returns, all initialization is quaranteed to be complete
|
|
|
|
-(e.g. listening ports are opened, SSL is initialized, etc). `mg_start()` starts
|
|
|
|
-two threads: a master thread, that accepts new connections, and several
|
|
|
|
-worker threads, that process accepted connections. The number of worker threads
|
|
|
|
-is configurable via `num_threads` configuration option. That number puts a
|
|
|
|
-limit on number of simultaneous requests that can be handled by civetweb.
|
|
|
|
-
|
|
|
|
-When master thread accepts new connection, a new accepted socket (described by
|
|
|
|
-`struct socket`) it placed into the accepted sockets queue,
|
|
|
|
-which has size of 20 (see [code](https://github.com/sunsetbrew/civetweb/blob/3892e0199e6ca9613b160535d9d107ede09daa43/civetweb.c#L486)). Any idle worker thread
|
|
|
|
-can grab accepted sockets from that queue. If all worker threads are busy,
|
|
|
|
-master thread can accept and queue up to 20 more TCP connections,
|
|
|
|
-filling up the queue.
|
|
|
|
-In the attempt to queue next accepted connection, master thread blocks
|
|
|
|
-until there is space in a queue. When master thread is blocked on a
|
|
|
|
-full queue, TCP layer in OS can also queue incoming connection.
|
|
|
|
-The number is limited by the `listen()` call parameter on listening socket,
|
|
|
|
-which is `SOMAXCONN` in case of Civetweb, and depends on a platform.
|
|
|
|
-
|
|
|
|
-Worker threads are running in an infinite loop, which in simplified form
|
|
|
|
-looks something like this:
|
|
|
|
-
|
|
|
|
- static void *worker_thread() {
|
|
|
|
- while (consume_socket()) {
|
|
|
|
- process_new_connection();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-Function `consume_socket()` gets new accepted socket from the civetweb socket
|
|
|
|
-queue, atomically removing it from the queue. If the queue is empty,
|
|
|
|
-`consume_socket()` blocks and waits until new sockets are placed in a queue
|
|
|
|
-by the master thread. `process_new_connection()` actually processes the
|
|
|
|
-connection, i.e. reads the request, parses it, and performs appropriate action
|
|
|
|
-depending on a parsed request.
|
|
|
|
-
|
|
|
|
-Master thread uses `poll()` and `accept()` to accept new connections on
|
|
|
|
-listening sockets. `poll()` is used to avoid `FD_SETSIZE` limitation of
|
|
|
|
-`select()`. Since there are only a few listening sockets, there is no reason
|
|
|
|
-to use hi-performance alternatives like `epoll()` or `kqueue()`. Worker
|
|
|
|
-threads use blocking IO on accepted sockets for reading and writing data.
|
|
|
|
-All accepted sockets have `SO_RCVTIMEO` and `SO_SNDTIMEO` socket options set
|
|
|
|
-(controlled by `request_timeout_ms` civetweb option, 30 seconds default) which
|
|
|
|
-specify read/write timeout on client connection.
|
|
|
|
-
|
|
|
|
-# Other Resources
|
|
|
|
-- Presentation made by Arnout Vandecappelle at FOSDEM 2011 on 2011-02-06
|
|
|
|
- in Brussels, Belgium, called
|
|
|
|
- "Creating secure web based user interfaces for Embedded Devices"
|
|
|
|
- ([pdf](http://mind.be/content/110206_Web-ui.pdf) |
|
|
|
|
- [odp](http://mind.be/content/110206_Web-ui.odp))
|
|
|
|
-- Linux Journal article by Michel J.Hammel, 2010-04-01, called
|
|
|
|
- [Civetweb: an Embeddable Web Server in C](http://www.linuxjournal.com/article/10680)
|
|
|