parent
c40fcccd95
commit
5f4f6e0d97
|
@ -29,6 +29,7 @@ A Lightweight and fully asynchronous HTTP server library based on [libev] and [h
|
|||
* Lightweight and fully asynchronous
|
||||
* Use [libev] as its event backend
|
||||
* Support HTTPS - OpenSSL, mbedtls and CyaSSl(wolfssl)
|
||||
* Support plugin
|
||||
* Flexible - you can easily extend your application to have HTTP/HTTPS services
|
||||
* Code structure is concise and understandable, also suitable for learning
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* 轻量、全异步
|
||||
* 使用[libev]作为其事件后端
|
||||
* 支持HTTPS - OpenSSL, mbedtls 和 CyaSSl(wolfssl)
|
||||
* 支持插件
|
||||
* 可伸缩 - 你可以非常方便的扩展你的应用程序,使之具备HTTP/HTTPS服务
|
||||
* 代码结构简洁通俗易懂,亦适合学习
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ int main(int argc, char **argv)
|
|||
|
||||
srv->on_request = on_request;
|
||||
|
||||
srv->load_plugin(srv, "/usr/local/lib/uhttpd/test.so");
|
||||
|
||||
uh_log_info("Listen on: *:%d\n", port);
|
||||
|
||||
ev_signal_init(&signal_watcher, signal_cb, SIGINT);
|
||||
|
|
|
@ -97,6 +97,8 @@ target_link_libraries(uhttpd_s ${EXTRA_LIBS})
|
|||
# configure a header file to pass some of the CMake settings to the source code
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
add_subdirectory(plugins)
|
||||
|
||||
install(
|
||||
FILES
|
||||
uhttpd.h
|
||||
|
|
|
@ -252,16 +252,32 @@ static int on_body_cb(struct http_parser *parser, const char *at, size_t length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool run_plugins(struct uh_connection *conn)
|
||||
{
|
||||
struct uh_plugin *p = conn->srv->plugins;
|
||||
|
||||
while (p) {
|
||||
if (!strcmp(conn->get_url(conn), p->path)) {
|
||||
p->handler(conn);
|
||||
return true;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int on_message_complete_cb(struct http_parser *parser)
|
||||
{
|
||||
struct uh_connection *conn = (struct uh_connection *)parser->data;
|
||||
struct uh_request *req = &conn->req;
|
||||
int i;
|
||||
|
||||
if (!run_plugins(conn)) {
|
||||
if (conn->srv->on_request)
|
||||
conn->srv->on_request(conn);
|
||||
else
|
||||
conn_error(conn, 404, NULL);
|
||||
}
|
||||
|
||||
buffer_pull(&conn->rb, NULL, buffer_length(&conn->rb));
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
option(BUILD_TEST_PLUGIN "Build test plugin" ON)
|
||||
|
||||
set(PLUGINS "")
|
||||
|
||||
if(BUILD_TEST_PLUGIN)
|
||||
set(PLUGINS ${PLUGINS} test_plugin)
|
||||
add_library(test_plugin MODULE test.c)
|
||||
set_target_properties(test_plugin PROPERTIES OUTPUT_NAME test PREFIX "")
|
||||
endif()
|
||||
|
||||
install(
|
||||
TARGETS ${PLUGINS}
|
||||
LIBRARY DESTINATION lib/uhttpd
|
||||
)
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2019 Jianhui Zhao <zhaojh329@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uhttpd.h"
|
||||
|
||||
static void test_handler(struct uh_connection *conn)
|
||||
{
|
||||
conn->send_head(conn, 200, -1, NULL);
|
||||
conn->chunk_printf(conn, "Url: %s\n", conn->get_url(conn));
|
||||
conn->chunk_end(conn);
|
||||
}
|
||||
|
||||
struct uh_plugin uh_plugin = {
|
||||
.path = "/test",
|
||||
.handler = test_handler
|
||||
};
|
38
src/uhttpd.c
38
src/uhttpd.c
|
@ -26,7 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
@ -111,6 +111,40 @@ static int uh_server_ssl_init(struct uh_server *srv, const char *cert, const cha
|
|||
}
|
||||
#endif
|
||||
|
||||
static int uh_load_plugin(struct uh_server *srv, const char *path)
|
||||
{
|
||||
struct uh_plugin *p;
|
||||
void *dlh;
|
||||
|
||||
dlh = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!dlh) {
|
||||
uh_log_err("dlopen fail: %s\n", dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = dlsym(dlh, "uh_plugin");
|
||||
if (!p) {
|
||||
uh_log_err("not found symbol 'uh_plugin'\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!p->path || !p->path[0] || !p->handler) {
|
||||
uh_log_err("invalid plugin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!srv->plugins) {
|
||||
srv->plugins = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->next = srv->plugins;
|
||||
srv->plugins->prev = p;
|
||||
srv->plugins = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host, int port)
|
||||
{
|
||||
struct sockaddr_in addr = {
|
||||
|
@ -150,6 +184,8 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
|
|||
srv->ssl_init = uh_server_ssl_init;
|
||||
#endif
|
||||
|
||||
srv->load_plugin = uh_load_plugin;
|
||||
|
||||
ev_io_init(&srv->ior, uh_accept_cb, sock, EV_READ);
|
||||
ev_io_start(srv->loop, &srv->ior);
|
||||
|
||||
|
|
|
@ -31,6 +31,13 @@
|
|||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
||||
struct uh_plugin {
|
||||
const char *path;
|
||||
void (*handler)(struct uh_connection *conn);
|
||||
struct uh_plugin *prev;
|
||||
struct uh_plugin *next;
|
||||
};
|
||||
|
||||
struct uh_server {
|
||||
int sock;
|
||||
struct ev_loop *loop;
|
||||
|
@ -42,6 +49,8 @@ struct uh_server {
|
|||
void *ssl_ctx;
|
||||
int (*ssl_init)(struct uh_server *srv, const char *cert, const char *key);
|
||||
#endif
|
||||
struct uh_plugin *plugins;
|
||||
int (*load_plugin)(struct uh_server *srv, const char *path);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue