Commit 2ac970fa authored by Sergey Lyubka's avatar Sergey Lyubka

Moving to event-based API, temporary breaking tests

parent de35a353
...@@ -339,20 +339,17 @@ static const char *test_next_option(void) { ...@@ -339,20 +339,17 @@ static const char *test_next_option(void) {
return NULL; return NULL;
} }
static int cb1(struct mg_connection *conn) { static int evh1(struct mg_connection *conn, enum mg_event ev) {
int result = MG_REQUEST_NOT_PROCESSED; if (ev == MG_HTTP_ERROR) {
if (!strcmp(conn->uri, "/cb1")) { mg_printf(conn, "HTTP/1.0 404 NF\r\n\r\nERR: %d", conn->status_code);
return MG_TRUE;
} else if (ev == MG_REQ_BEGIN && !strcmp(conn->uri, "/cb1")) {
mg_printf(conn, "%s %s %s", mg_printf(conn, "%s %s %s",
conn->server_param == NULL ? "?" : (char *) conn->server_param, conn->server_param == NULL ? "?" : (char *) conn->server_param,
conn->connection_param == NULL ? "?" : "!", conn->remote_ip); conn->connection_param == NULL ? "?" : "!", conn->remote_ip);
result = MG_REQUEST_PROCESSED; return MG_TRUE;
} }
return result; return MG_FALSE;
}
static int error_handler(struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.0 404 NF\r\n\r\nERR: %d", conn->status_code);
return MG_ERROR_PROCESSED;
} }
static int ts1(struct mg_connection *conn) { static int ts1(struct mg_connection *conn) {
...@@ -379,16 +376,14 @@ static int ts2(struct mg_connection *conn) { ...@@ -379,16 +376,14 @@ static int ts2(struct mg_connection *conn) {
static const char *test_server(void) { static const char *test_server(void) {
char buf1[100] = "", buf2[100] = ""; char buf1[100] = "", buf2[100] = "";
struct mg_server *server = mg_create_server((void *) "foo"); struct mg_server *server = mg_create_server((void *) "foo", evh1);
ASSERT(server != NULL); ASSERT(server != NULL);
ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL); ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL);
ASSERT(mg_set_option(server, "document_root", ".") == NULL); ASSERT(mg_set_option(server, "document_root", ".") == NULL);
mg_set_request_handler(server, cb1);
mg_set_http_error_handler(server, error_handler);
ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, ts1, buf1) == 1); ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, buf1) == 1);
ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, ts2, buf2) == 1); ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, buf2) == 1);
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); } { int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
ASSERT(strcmp(buf1, "foo ? 127.0.0.1") == 0); ASSERT(strcmp(buf1, "foo ? 127.0.0.1") == 0);
...@@ -464,15 +459,14 @@ static int cb3(struct mg_connection *conn) { ...@@ -464,15 +459,14 @@ static int cb3(struct mg_connection *conn) {
static const char *test_mg_connect(void) { static const char *test_mg_connect(void) {
char buf2[40] = "", buf3[40] = "", buf4[40] = ""; char buf2[40] = "", buf3[40] = "", buf4[40] = "";
struct mg_server *server = mg_create_server(NULL); struct mg_server *server = mg_create_server(NULL, NULL); // cb4h
ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL); ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL);
ASSERT(mg_set_option(server, "document_root", ".") == NULL); ASSERT(mg_set_option(server, "document_root", ".") == NULL);
mg_set_request_handler(server, cb4h);
ASSERT(mg_connect(server, "", 0, 0, NULL, NULL) == 0); ASSERT(mg_connect(server, "", 0, 0, NULL, NULL) == 0);
ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, cb2, buf2) == 1); ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, buf2) == 1);
ASSERT(mg_connect(server, "127.0.0.1", 29, 0, cb3, buf3) == 1); ASSERT(mg_connect(server, "127.0.0.1", 29, 0, cb3, buf3) == 1);
ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, cb4, buf4) == 1); ASSERT(mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0, buf4) == 1);
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); } { int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
...@@ -562,7 +556,7 @@ static const char *test_ssl(void) { ...@@ -562,7 +556,7 @@ static const char *test_ssl(void) {
#endif #endif
static const char *test_mg_set_option(void) { static const char *test_mg_set_option(void) {
struct mg_server *server = mg_create_server(NULL); struct mg_server *server = mg_create_server(NULL, NULL);
ASSERT(mg_set_option(server, "listening_port", "0") == NULL); ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
ASSERT(mg_get_option(server, "listening_port")[0] != '\0'); ASSERT(mg_get_option(server, "listening_port")[0] != '\0');
mg_destroy_server(&server); mg_destroy_server(&server);
...@@ -571,7 +565,7 @@ static const char *test_mg_set_option(void) { ...@@ -571,7 +565,7 @@ static const char *test_mg_set_option(void) {
static const char *test_rewrites(void) { static const char *test_rewrites(void) {
char buf1[100] = "xx"; char buf1[100] = "xx";
struct mg_server *server = mg_create_server(NULL); struct mg_server *server = mg_create_server(NULL, NULL);
ASSERT(mg_set_option(server, "listening_port", "0") == NULL); ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
ASSERT(mg_set_option(server, "document_root", ".") == NULL); ASSERT(mg_set_option(server, "document_root", ".") == NULL);
......
...@@ -325,14 +325,14 @@ void *ns_start_thread(void *(*f)(void *), void *p) { ...@@ -325,14 +325,14 @@ void *ns_start_thread(void *(*f)(void *), void *p) {
} }
#endif // NS_DISABLE_THREADS #endif // NS_DISABLE_THREADS
static void add_connection(struct ns_server *server, struct ns_connection *c) { static void ns_add_conn(struct ns_server *server, struct ns_connection *c) {
c->next = server->active_connections; c->next = server->active_connections;
server->active_connections = c; server->active_connections = c;
c->prev = NULL; c->prev = NULL;
if (c->next != NULL) c->next->prev = c; if (c->next != NULL) c->next->prev = c;
} }
static void remove_connection(struct ns_connection *conn) { static void ns_remove_conn(struct ns_connection *conn) {
if (conn->prev == NULL) conn->server->active_connections = conn->next; if (conn->prev == NULL) conn->server->active_connections = conn->next;
if (conn->prev) conn->prev->next = conn->next; if (conn->prev) conn->prev->next = conn->next;
if (conn->next) conn->next->prev = conn->prev; if (conn->next) conn->next->prev = conn->prev;
...@@ -341,7 +341,7 @@ static void remove_connection(struct ns_connection *conn) { ...@@ -341,7 +341,7 @@ static void remove_connection(struct ns_connection *conn) {
// Print message to buffer. If buffer is large enough to hold the message, // Print message to buffer. If buffer is large enough to hold the message,
// return buffer. If buffer is to small, allocate large enough buffer on heap, // return buffer. If buffer is to small, allocate large enough buffer on heap,
// and return allocated buffer. // and return allocated buffer.
static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap) { static int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
va_list ap_copy; va_list ap_copy;
int len; int len;
...@@ -380,7 +380,7 @@ int ns_vprintf(struct ns_connection *conn, const char *fmt, va_list ap) { ...@@ -380,7 +380,7 @@ int ns_vprintf(struct ns_connection *conn, const char *fmt, va_list ap) {
char mem[2000], *buf = mem; char mem[2000], *buf = mem;
int len; int len;
if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) { if ((len = ns_avprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
iobuf_append(&conn->send_iobuf, buf, len); iobuf_append(&conn->send_iobuf, buf, len);
} }
if (buf != mem && buf != NULL) { if (buf != mem && buf != NULL) {
...@@ -399,14 +399,14 @@ int ns_printf(struct ns_connection *conn, const char *fmt, ...) { ...@@ -399,14 +399,14 @@ int ns_printf(struct ns_connection *conn, const char *fmt, ...) {
return len; return len;
} }
static void call_user(struct ns_connection *conn, enum ns_event ev, void *p) { static void ns_call(struct ns_connection *conn, enum ns_event ev, void *p) {
if (conn->server->callback) conn->server->callback(conn, ev, p); if (conn->server->callback) conn->server->callback(conn, ev, p);
} }
static void close_conn(struct ns_connection *conn) { static void ns_close_conn(struct ns_connection *conn) {
DBG(("%p %d", conn, conn->flags)); DBG(("%p %d", conn, conn->flags));
call_user(conn, NS_CLOSE, NULL); ns_call(conn, NS_CLOSE, NULL);
remove_connection(conn); ns_remove_conn(conn);
closesocket(conn->sock); closesocket(conn->sock);
iobuf_free(&conn->recv_iobuf); iobuf_free(&conn->recv_iobuf);
iobuf_free(&conn->send_iobuf); iobuf_free(&conn->send_iobuf);
...@@ -421,7 +421,7 @@ void ns_set_close_on_exec(sock_t sock) { ...@@ -421,7 +421,7 @@ void ns_set_close_on_exec(sock_t sock) {
#endif #endif
} }
static void set_non_blocking_mode(sock_t sock) { static void ns_set_non_blocking_mode(sock_t sock) {
#ifdef _WIN32 #ifdef _WIN32
unsigned long on = 1; unsigned long on = 1;
ioctlsocket(sock, FIONBIO, &on); ioctlsocket(sock, FIONBIO, &on);
...@@ -467,7 +467,7 @@ int ns_socketpair(sock_t sp[2]) { ...@@ -467,7 +467,7 @@ int ns_socketpair(sock_t sp[2]) {
#endif // NS_DISABLE_SOCKETPAIR #endif // NS_DISABLE_SOCKETPAIR
// Valid listening port spec is: [ip_address:]port, e.g. "80", "127.0.0.1:3128" // Valid listening port spec is: [ip_address:]port, e.g. "80", "127.0.0.1:3128"
static int parse_port_string(const char *str, union socket_address *sa) { static int ns_parse_port_string(const char *str, union socket_address *sa) {
unsigned int a, b, c, d, port; unsigned int a, b, c, d, port;
int len = 0; int len = 0;
#ifdef NS_ENABLE_IPV6 #ifdef NS_ENABLE_IPV6
...@@ -502,7 +502,7 @@ static int parse_port_string(const char *str, union socket_address *sa) { ...@@ -502,7 +502,7 @@ static int parse_port_string(const char *str, union socket_address *sa) {
} }
// 'sa' must be an initialized address to bind to // 'sa' must be an initialized address to bind to
static sock_t open_listening_socket(union socket_address *sa) { static sock_t ns_open_listening_socket(union socket_address *sa) {
socklen_t len = sizeof(*sa); socklen_t len = sizeof(*sa);
sock_t on = 1, sock = INVALID_SOCKET; sock_t on = 1, sock = INVALID_SOCKET;
...@@ -511,7 +511,7 @@ static sock_t open_listening_socket(union socket_address *sa) { ...@@ -511,7 +511,7 @@ static sock_t open_listening_socket(union socket_address *sa) {
!bind(sock, &sa->sa, sa->sa.sa_family == AF_INET ? !bind(sock, &sa->sa, sa->sa.sa_family == AF_INET ?
sizeof(sa->sin) : sizeof(sa->sa)) && sizeof(sa->sin) : sizeof(sa->sa)) &&
!listen(sock, SOMAXCONN)) { !listen(sock, SOMAXCONN)) {
set_non_blocking_mode(sock); ns_set_non_blocking_mode(sock);
// In case port was set to 0, get the real port number // In case port was set to 0, get the real port number
(void) getsockname(sock, &sa->sa, &len); (void) getsockname(sock, &sa->sa, &len);
} else if (sock != INVALID_SOCKET) { } else if (sock != INVALID_SOCKET) {
...@@ -541,11 +541,11 @@ int ns_set_ssl_cert(struct ns_server *server, const char *cert) { ...@@ -541,11 +541,11 @@ int ns_set_ssl_cert(struct ns_server *server, const char *cert) {
} }
int ns_bind(struct ns_server *server, const char *str) { int ns_bind(struct ns_server *server, const char *str) {
parse_port_string(str, &server->listening_sa); ns_parse_port_string(str, &server->listening_sa);
if (server->listening_sock != INVALID_SOCKET) { if (server->listening_sock != INVALID_SOCKET) {
closesocket(server->listening_sock); closesocket(server->listening_sock);
} }
server->listening_sock = open_listening_socket(&server->listening_sa); server->listening_sock = ns_open_listening_socket(&server->listening_sa);
return server->listening_sock == INVALID_SOCKET ? -1 : return server->listening_sock == INVALID_SOCKET ? -1 :
(int) ntohs(server->listening_sa.sin.sin_port); (int) ntohs(server->listening_sa.sin.sin_port);
} }
...@@ -574,13 +574,13 @@ static struct ns_connection *accept_conn(struct ns_server *server) { ...@@ -574,13 +574,13 @@ static struct ns_connection *accept_conn(struct ns_server *server) {
#endif #endif
} else { } else {
ns_set_close_on_exec(sock); ns_set_close_on_exec(sock);
set_non_blocking_mode(sock); ns_set_non_blocking_mode(sock);
c->server = server; c->server = server;
c->sock = sock; c->sock = sock;
c->flags |= NSF_ACCEPTED; c->flags |= NSF_ACCEPTED;
add_connection(server, c); ns_add_conn(server, c);
call_user(c, NS_ACCEPT, &sa); ns_call(c, NS_ACCEPT, &sa);
DBG(("%p %d %p %p", c, c->sock, c->ssl, server->ssl_ctx)); DBG(("%p %d %p %p", c, c->sock, c->ssl, server->ssl_ctx));
} }
...@@ -598,8 +598,8 @@ static int ns_is_error(int n) { ...@@ -598,8 +598,8 @@ static int ns_is_error(int n) {
} }
#ifdef NS_ENABLE_HEXDUMP #ifdef NS_ENABLE_HEXDUMP
static void hexdump(const struct ns_connection *conn, const void *buf, static void ns_hexdump(const struct ns_connection *conn, const void *buf,
int len, const char *marker) { int len, const char *marker) {
const unsigned char *p = (const unsigned char *) buf; const unsigned char *p = (const unsigned char *) buf;
char path[500], date[100], ascii[17]; char path[500], date[100], ascii[17];
FILE *fp; FILE *fp;
...@@ -641,7 +641,7 @@ static void hexdump(const struct ns_connection *conn, const void *buf, ...@@ -641,7 +641,7 @@ static void hexdump(const struct ns_connection *conn, const void *buf,
} }
#endif #endif
static void read_from_socket(struct ns_connection *conn) { static void ns_read_from_socket(struct ns_connection *conn) {
char buf[2048]; char buf[2048];
int n = 0; int n = 0;
...@@ -671,7 +671,7 @@ static void read_from_socket(struct ns_connection *conn) { ...@@ -671,7 +671,7 @@ static void read_from_socket(struct ns_connection *conn) {
if (ok != 0) { if (ok != 0) {
conn->flags |= NSF_CLOSE_IMMEDIATELY; conn->flags |= NSF_CLOSE_IMMEDIATELY;
} }
call_user(conn, NS_CONNECT, &ok); ns_call(conn, NS_CONNECT, &ok);
return; return;
} }
...@@ -692,7 +692,7 @@ static void read_from_socket(struct ns_connection *conn) { ...@@ -692,7 +692,7 @@ static void read_from_socket(struct ns_connection *conn) {
} }
#ifdef NS_ENABLE_HEXDUMP #ifdef NS_ENABLE_HEXDUMP
hexdump(conn, buf, n, "<-"); ns_hexdump(conn, buf, n, "<-");
#endif #endif
DBG(("%p <- %d bytes [%.*s%s]", DBG(("%p <- %d bytes [%.*s%s]",
...@@ -702,11 +702,11 @@ static void read_from_socket(struct ns_connection *conn) { ...@@ -702,11 +702,11 @@ static void read_from_socket(struct ns_connection *conn) {
conn->flags |= NSF_CLOSE_IMMEDIATELY; conn->flags |= NSF_CLOSE_IMMEDIATELY;
} else if (n > 0) { } else if (n > 0) {
iobuf_append(&conn->recv_iobuf, buf, n); iobuf_append(&conn->recv_iobuf, buf, n);
call_user(conn, NS_RECV, &n); ns_call(conn, NS_RECV, &n);
} }
} }
static void write_to_socket(struct ns_connection *conn) { static void ns_write_to_socket(struct ns_connection *conn) {
struct iobuf *io = &conn->send_iobuf; struct iobuf *io = &conn->send_iobuf;
int n = 0; int n = 0;
...@@ -719,7 +719,7 @@ static void write_to_socket(struct ns_connection *conn) { ...@@ -719,7 +719,7 @@ static void write_to_socket(struct ns_connection *conn) {
#ifdef NS_ENABLE_HEXDUMP #ifdef NS_ENABLE_HEXDUMP
hexdump(conn, io->buf, n, "->"); ns_hexdump(conn, io->buf, n, "->");
#endif #endif
DBG(("%p -> %d bytes [%.*s%s]", conn, n, io->len < 40 ? io->len : 40, DBG(("%p -> %d bytes [%.*s%s]", conn, n, io->len < 40 ? io->len : 40,
...@@ -736,14 +736,14 @@ static void write_to_socket(struct ns_connection *conn) { ...@@ -736,14 +736,14 @@ static void write_to_socket(struct ns_connection *conn) {
conn->flags |= NSF_CLOSE_IMMEDIATELY; conn->flags |= NSF_CLOSE_IMMEDIATELY;
} }
call_user(conn, NS_SEND, NULL); ns_call(conn, NS_SEND, NULL);
} }
int ns_send(struct ns_connection *conn, const void *buf, int len) { int ns_send(struct ns_connection *conn, const void *buf, int len) {
return iobuf_append(&conn->send_iobuf, buf, len); return iobuf_append(&conn->send_iobuf, buf, len);
} }
static void add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) { static void ns_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) {
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
FD_SET(sock, set); FD_SET(sock, set);
if (*max_fd == INVALID_SOCKET || sock > *max_fd) { if (*max_fd == INVALID_SOCKET || sock > *max_fd) {
...@@ -765,19 +765,19 @@ int ns_server_poll(struct ns_server *server, int milli) { ...@@ -765,19 +765,19 @@ int ns_server_poll(struct ns_server *server, int milli) {
FD_ZERO(&read_set); FD_ZERO(&read_set);
FD_ZERO(&write_set); FD_ZERO(&write_set);
add_to_set(server->listening_sock, &read_set, &max_fd); ns_add_to_set(server->listening_sock, &read_set, &max_fd);
for (conn = server->active_connections; conn != NULL; conn = tmp_conn) { for (conn = server->active_connections; conn != NULL; conn = tmp_conn) {
tmp_conn = conn->next; tmp_conn = conn->next;
call_user(conn, NS_POLL, &current_time); ns_call(conn, NS_POLL, &current_time);
add_to_set(conn->sock, &read_set, &max_fd); ns_add_to_set(conn->sock, &read_set, &max_fd);
if (conn->flags & NSF_CONNECTING) { if (conn->flags & NSF_CONNECTING) {
add_to_set(conn->sock, &write_set, &max_fd); ns_add_to_set(conn->sock, &write_set, &max_fd);
} }
if (conn->send_iobuf.len > 0 && !(conn->flags & NSF_BUFFER_BUT_DONT_SEND)) { if (conn->send_iobuf.len > 0 && !(conn->flags & NSF_BUFFER_BUT_DONT_SEND)) {
add_to_set(conn->sock, &write_set, &max_fd); ns_add_to_set(conn->sock, &write_set, &max_fd);
} else if (conn->flags & NSF_CLOSE_IMMEDIATELY) { } else if (conn->flags & NSF_CLOSE_IMMEDIATELY) {
close_conn(conn); ns_close_conn(conn);
} }
} }
...@@ -786,7 +786,7 @@ int ns_server_poll(struct ns_server *server, int milli) { ...@@ -786,7 +786,7 @@ int ns_server_poll(struct ns_server *server, int milli) {
if (select((int) max_fd + 1, &read_set, &write_set, NULL, &tv) > 0) { if (select((int) max_fd + 1, &read_set, &write_set, NULL, &tv) > 0) {
// Accept new connections // Accept new connections
if (server->listening_sock >= 0 && if (server->listening_sock != INVALID_SOCKET &&
FD_ISSET(server->listening_sock, &read_set)) { FD_ISSET(server->listening_sock, &read_set)) {
// We're not looping here, and accepting just one connection at // We're not looping here, and accepting just one connection at
// a time. The reason is that eCos does not respect non-blocking // a time. The reason is that eCos does not respect non-blocking
...@@ -800,14 +800,14 @@ int ns_server_poll(struct ns_server *server, int milli) { ...@@ -800,14 +800,14 @@ int ns_server_poll(struct ns_server *server, int milli) {
tmp_conn = conn->next; tmp_conn = conn->next;
if (FD_ISSET(conn->sock, &read_set)) { if (FD_ISSET(conn->sock, &read_set)) {
conn->last_io_time = current_time; conn->last_io_time = current_time;
read_from_socket(conn); ns_read_from_socket(conn);
} }
if (FD_ISSET(conn->sock, &write_set)) { if (FD_ISSET(conn->sock, &write_set)) {
if (conn->flags & NSF_CONNECTING) { if (conn->flags & NSF_CONNECTING) {
read_from_socket(conn); ns_read_from_socket(conn);
} else if (!(conn->flags & NSF_BUFFER_BUT_DONT_SEND)) { } else if (!(conn->flags & NSF_BUFFER_BUT_DONT_SEND)) {
conn->last_io_time = current_time; conn->last_io_time = current_time;
write_to_socket(conn); ns_write_to_socket(conn);
} }
} }
} }
...@@ -817,7 +817,7 @@ int ns_server_poll(struct ns_server *server, int milli) { ...@@ -817,7 +817,7 @@ int ns_server_poll(struct ns_server *server, int milli) {
tmp_conn = conn->next; tmp_conn = conn->next;
num_active_connections++; num_active_connections++;
if (conn->flags & NSF_CLOSE_IMMEDIATELY) { if (conn->flags & NSF_CLOSE_IMMEDIATELY) {
close_conn(conn); ns_close_conn(conn);
} }
} }
//DBG(("%d active connections", num_active_connections)); //DBG(("%d active connections", num_active_connections));
...@@ -846,7 +846,7 @@ struct ns_connection *ns_connect(struct ns_server *server, const char *host, ...@@ -846,7 +846,7 @@ struct ns_connection *ns_connect(struct ns_server *server, const char *host,
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons((uint16_t) port); sin.sin_port = htons((uint16_t) port);
sin.sin_addr = * (struct in_addr *) he->h_addr_list[0]; sin.sin_addr = * (struct in_addr *) he->h_addr_list[0];
set_non_blocking_mode(sock); ns_set_non_blocking_mode(sock);
connect_ret_val = connect(sock, (struct sockaddr *) &sin, sizeof(sin)); connect_ret_val = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
if (ns_is_error(connect_ret_val)) { if (ns_is_error(connect_ret_val)) {
...@@ -871,7 +871,7 @@ struct ns_connection *ns_connect(struct ns_server *server, const char *host, ...@@ -871,7 +871,7 @@ struct ns_connection *ns_connect(struct ns_server *server, const char *host,
} }
#endif #endif
add_connection(server, conn); ns_add_conn(server, conn);
DBG(("%p %s:%d %d %p", conn, host, port, conn->sock, conn->ssl)); DBG(("%p %s:%d %d %p", conn, host, port, conn->sock, conn->ssl));
return conn; return conn;
...@@ -881,12 +881,12 @@ struct ns_connection *ns_add_sock(struct ns_server *s, sock_t sock, void *p) { ...@@ -881,12 +881,12 @@ struct ns_connection *ns_add_sock(struct ns_server *s, sock_t sock, void *p) {
struct ns_connection *conn; struct ns_connection *conn;
if ((conn = (struct ns_connection *) NS_MALLOC(sizeof(*conn))) != NULL) { if ((conn = (struct ns_connection *) NS_MALLOC(sizeof(*conn))) != NULL) {
memset(conn, 0, sizeof(*conn)); memset(conn, 0, sizeof(*conn));
set_non_blocking_mode(sock); ns_set_non_blocking_mode(sock);
conn->sock = sock; conn->sock = sock;
conn->connection_data = p; conn->connection_data = p;
conn->server = s; conn->server = s;
conn->last_io_time = time(NULL); conn->last_io_time = time(NULL);
add_connection(s, conn); ns_add_conn(s, conn);
DBG(("%p %d", conn, sock)); DBG(("%p %d", conn, sock));
} }
return conn; return conn;
...@@ -935,7 +935,7 @@ void ns_server_free(struct ns_server *s) { ...@@ -935,7 +935,7 @@ void ns_server_free(struct ns_server *s) {
for (conn = s->active_connections; conn != NULL; conn = tmp_conn) { for (conn = s->active_connections; conn != NULL; conn = tmp_conn) {
tmp_conn = conn->next; tmp_conn = conn->next;
close_conn(conn); ns_close_conn(conn);
} }
#ifndef NS_DISABLE_SOCKETPAIR #ifndef NS_DISABLE_SOCKETPAIR
...@@ -1122,10 +1122,7 @@ static const char *static_config_options[] = { ...@@ -1122,10 +1122,7 @@ static const char *static_config_options[] = {
struct mg_server { struct mg_server {
struct ns_server ns_server; struct ns_server ns_server;
union socket_address lsa; // Listening socket address union socket_address lsa; // Listening socket address
mg_handler_t request_handler; mg_handler_t event_handler;
mg_handler_t http_close_handler;
mg_handler_t error_handler;
mg_handler_t auth_handler;
char *config_options[NUM_OPTIONS]; char *config_options[NUM_OPTIONS];
char local_ip[48]; char local_ip[48];
}; };
...@@ -1155,7 +1152,7 @@ struct connection { ...@@ -1155,7 +1152,7 @@ struct connection {
int64_t cl; // Reply content length, for Range support int64_t cl; // Reply content length, for Range support
int request_len; // Request length, including last \r\n after last header int request_len; // Request length, including last \r\n after last header
//int flags; // CONN_* flags: CONN_CLOSE, CONN_SPOOL_DONE, etc //int flags; // CONN_* flags: CONN_CLOSE, CONN_SPOOL_DONE, etc
mg_handler_t handler; // Callback for HTTP client //mg_handler_t handler; // Callback for HTTP client
}; };
#define MG_CONN_2_CONN(c) ((struct connection *) ((char *) (c) - \ #define MG_CONN_2_CONN(c) ((struct connection *) ((char *) (c) - \
...@@ -1433,6 +1430,12 @@ static const char *status_code_to_str(int status_code) { ...@@ -1433,6 +1430,12 @@ static const char *status_code_to_str(int status_code) {
} }
} }
static int call_user(struct connection *conn, enum mg_event ev) {
return conn != NULL && conn->server != NULL &&
conn->server->event_handler != NULL ?
conn->server->event_handler(&conn->mg_conn, ev) : MG_FALSE;
}
static void send_http_error(struct connection *conn, int code, static void send_http_error(struct connection *conn, int code,
const char *fmt, ...) { const char *fmt, ...) {
const char *message = status_code_to_str(code); const char *message = status_code_to_str(code);
...@@ -1445,8 +1448,7 @@ static void send_http_error(struct connection *conn, int code, ...@@ -1445,8 +1448,7 @@ static void send_http_error(struct connection *conn, int code,
conn->mg_conn.status_code = code; conn->mg_conn.status_code = code;
// Invoke error handler if it is set // Invoke error handler if it is set
if (conn->server->error_handler != NULL && if (call_user(conn, MG_HTTP_ERROR) == MG_TRUE) {
conn->server->error_handler(&conn->mg_conn) == MG_ERROR_PROCESSED) {
close_local_endpoint(conn); close_local_endpoint(conn);
return; return;
} }
...@@ -2505,7 +2507,7 @@ static int deliver_websocket_frame(struct connection *conn) { ...@@ -2505,7 +2507,7 @@ static int deliver_websocket_frame(struct connection *conn) {
} }
// Call the handler and remove frame from the iobuf // Call the handler and remove frame from the iobuf
if (conn->server->request_handler(&conn->mg_conn) == MG_CLIENT_CLOSE) { if (call_user(conn, MG_REQ_BEGIN) == MG_FALSE) {
conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA; conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
} }
iobuf_remove(&conn->ns_conn->recv_iobuf, frame_len); iobuf_remove(&conn->ns_conn->recv_iobuf, frame_len);
...@@ -2581,15 +2583,11 @@ static void write_terminating_chunk(struct connection *conn) { ...@@ -2581,15 +2583,11 @@ static void write_terminating_chunk(struct connection *conn) {
static int call_request_handler(struct connection *conn) { static int call_request_handler(struct connection *conn) {
int result; int result;
conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf; conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
switch ((result = conn->server->request_handler(&conn->mg_conn))) { if ((result = call_user(conn, MG_REQ_BEGIN)) == MG_TRUE) {
case MG_REQUEST_CALL_AGAIN: conn->ns_conn->flags |= MG_LONG_RUNNING; break; if (conn->ns_conn->flags & MG_HEADERS_SENT) {
case MG_REQUEST_NOT_PROCESSED: break; write_terminating_chunk(conn);
default: }
if (conn->ns_conn->flags & MG_HEADERS_SENT) { close_local_endpoint(conn);
write_terminating_chunk(conn);
}
close_local_endpoint(conn);
break;
} }
return result; return result;
} }
...@@ -3554,8 +3552,7 @@ static int check_password(const char *method, const char *ha1, const char *uri, ...@@ -3554,8 +3552,7 @@ static int check_password(const char *method, const char *ha1, const char *uri,
mg_md5(expected_response, ha1, ":", nonce, ":", nc, mg_md5(expected_response, ha1, ":", nonce, ":", nc,
":", cnonce, ":", qop, ":", ha2, NULL); ":", cnonce, ":", qop, ":", ha2, NULL);
return mg_strcasecmp(response, expected_response) == 0 ? return mg_strcasecmp(response, expected_response) == 0 ? MG_TRUE : MG_FALSE;
MG_AUTH_OK : MG_AUTH_FAIL;
} }
...@@ -3585,14 +3582,14 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp) { ...@@ -3585,14 +3582,14 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp) {
return check_password(c->request_method, ha1, uri, return check_password(c->request_method, ha1, uri,
nonce, nc, cnonce, qop, resp); nonce, nc, cnonce, qop, resp);
} }
return MG_AUTH_FAIL; return MG_FALSE;
} }
// Return 1 if request is authorised, 0 otherwise. // Return 1 if request is authorised, 0 otherwise.
static int is_authorized(struct connection *conn, const char *path) { static int is_authorized(struct connection *conn, const char *path) {
FILE *fp; FILE *fp;
int authorized = MG_AUTH_OK; int authorized = MG_TRUE;
if ((fp = open_auth_file(conn, path)) != NULL) { if ((fp = open_auth_file(conn, path)) != NULL) {
authorized = mg_authorize_digest(&conn->mg_conn, fp); authorized = mg_authorize_digest(&conn->mg_conn, fp);
...@@ -3605,7 +3602,7 @@ static int is_authorized(struct connection *conn, const char *path) { ...@@ -3605,7 +3602,7 @@ static int is_authorized(struct connection *conn, const char *path) {
static int is_authorized_for_dav(struct connection *conn) { static int is_authorized_for_dav(struct connection *conn) {
const char *auth_file = conn->server->config_options[DAV_AUTH_FILE]; const char *auth_file = conn->server->config_options[DAV_AUTH_FILE];
FILE *fp; FILE *fp;
int authorized = MG_AUTH_FAIL; int authorized = MG_FALSE;
if (auth_file != NULL && (fp = fopen(auth_file, "r")) != NULL) { if (auth_file != NULL && (fp = fopen(auth_file, "r")) != NULL) {
authorized = mg_authorize_digest(&conn->mg_conn, fp); authorized = mg_authorize_digest(&conn->mg_conn, fp);
...@@ -3952,16 +3949,14 @@ static void open_local_endpoint(struct connection *conn, int skip_user) { ...@@ -3952,16 +3949,14 @@ static void open_local_endpoint(struct connection *conn, int skip_user) {
#endif #endif
#ifndef MONGOOSE_NO_AUTH #ifndef MONGOOSE_NO_AUTH
// Call auth handler if (conn->server->event_handler && call_user(conn, MG_AUTH) == MG_FALSE) {
if (conn->server->auth_handler != NULL &&
conn->server->auth_handler(&conn->mg_conn) == MG_AUTH_FAIL) {
mg_send_digest_auth_request(&conn->mg_conn); mg_send_digest_auth_request(&conn->mg_conn);
return; return;
} }
#endif #endif
// Call URI handler if one is registered for this URI // Call URI handler if one is registered for this URI
if (skip_user == 0 && conn->server->request_handler != NULL) { if (skip_user == 0 && conn->server->event_handler != NULL) {
conn->endpoint_type = EP_USER; conn->endpoint_type = EP_USER;
#if MONGOOSE_POST_SIZE_LIMIT > 1 #if MONGOOSE_POST_SIZE_LIMIT > 1
{ {
...@@ -4130,7 +4125,7 @@ static void call_http_client_handler(struct connection *conn, int code) { ...@@ -4130,7 +4125,7 @@ static void call_http_client_handler(struct connection *conn, int code) {
conn->mg_conn.content_len = conn->ns_conn->recv_iobuf.len; conn->mg_conn.content_len = conn->ns_conn->recv_iobuf.len;
} }
conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf; conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
if (conn->handler(&conn->mg_conn) || code == MG_CONNECT_FAILURE || if (call_user(conn, -1) || code == MG_CONNECT_FAILURE ||
code == MG_DOWNLOAD_FAILURE) { code == MG_DOWNLOAD_FAILURE) {
conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY; conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY;
} }
...@@ -4156,12 +4151,12 @@ static void process_response(struct connection *conn) { ...@@ -4156,12 +4151,12 @@ static void process_response(struct connection *conn) {
} }
} }
int mg_connect(struct mg_server *server, const char *host, int port, struct mg_connection *mg_connect(struct mg_server *server, const char *host,
int use_ssl, mg_handler_t handler, void *param) { int port, int use_ssl) {
struct ns_connection *nsconn; struct ns_connection *nsconn;
struct connection *conn; struct connection *conn;
nsconn = ns_connect(&server->ns_server, host, port, use_ssl, param); nsconn = ns_connect(&server->ns_server, host, port, use_ssl, NULL);
if (nsconn == NULL) return 0; if (nsconn == NULL) return 0;
if ((conn = (struct connection *) calloc(1, sizeof(*conn))) == NULL) { if ((conn = (struct connection *) calloc(1, sizeof(*conn))) == NULL) {
...@@ -4175,14 +4170,13 @@ int mg_connect(struct mg_server *server, const char *host, int port, ...@@ -4175,14 +4170,13 @@ int mg_connect(struct mg_server *server, const char *host, int port,
conn->server = server; conn->server = server;
conn->endpoint_type = EP_CLIENT; conn->endpoint_type = EP_CLIENT;
conn->handler = handler; //conn->handler = handler;
conn->mg_conn.server_param = server->ns_server.server_data; conn->mg_conn.server_param = server->ns_server.server_data;
conn->mg_conn.connection_param = param;
conn->birth_time = time(NULL); conn->birth_time = time(NULL);
conn->ns_conn->flags = NSF_CONNECTING; conn->ns_conn->flags = NSF_CONNECTING;
conn->mg_conn.status_code = MG_CONNECT_FAILURE; conn->mg_conn.status_code = MG_CONNECT_FAILURE;
return 1; return &conn->mg_conn;
} }
#ifndef MONGOOSE_NO_LOGGING #ifndef MONGOOSE_NO_LOGGING
...@@ -4311,21 +4305,20 @@ struct mg_iterator { ...@@ -4311,21 +4305,20 @@ struct mg_iterator {
mg_handler_t cb; mg_handler_t cb;
void *param; void *param;
}; };
union variant { mg_handler_t cb; void *p; };
static void iter(struct ns_connection *nsconn, enum ns_event ev, void *param) { static void iter(struct ns_connection *nsconn, enum ns_event ev, void *param) {
if (ev == NS_POLL) { if (ev == NS_POLL) {
struct mg_iterator *it = (struct mg_iterator *) param; union variant *variant = (union variant *) param;
struct connection *c = (struct connection *) nsconn->connection_data; struct connection *c = (struct connection *) nsconn->connection_data;
c->mg_conn.callback_param = it->param; variant->cb(&c->mg_conn, MG_POLL);
it->cb(&c->mg_conn);
} }
} }
// Apply function to all active connections. // Apply function to all active connections.
void mg_iterate_over_connections(struct mg_server *server, mg_handler_t handler, void mg_iterate_over_connections(struct mg_server *server, mg_handler_t cb) {
void *param) { union variant variant = { cb };
struct mg_iterator it = { handler, param }; ns_iterate(&server->ns_server, iter, &variant);
ns_iterate(&server->ns_server, iter, &it);
} }
static int get_var(const char *data, size_t data_len, const char *name, static int get_var(const char *data, size_t data_len, const char *name,
...@@ -4550,7 +4543,7 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) { ...@@ -4550,7 +4543,7 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
int ok = * (int *) p; int ok = * (int *) p;
conn->mg_conn.status_code = ok == 0 ? conn->mg_conn.status_code = ok == 0 ?
MG_CONNECT_SUCCESS : MG_CONNECT_FAILURE; MG_CONNECT_SUCCESS : MG_CONNECT_FAILURE;
if (conn->handler(&conn->mg_conn) != 0 || ok != 0) { if (call_user(conn, MG_CONNECT) != 0 || ok != 0) {
nc->flags |= NSF_CLOSE_IMMEDIATELY; nc->flags |= NSF_CLOSE_IMMEDIATELY;
} }
} }
...@@ -4585,10 +4578,7 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) { ...@@ -4585,10 +4578,7 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
call_http_client_handler(conn, MG_DOWNLOAD_SUCCESS); call_http_client_handler(conn, MG_DOWNLOAD_SUCCESS);
} }
if (conn->server->http_close_handler) { call_user(conn, MG_CLOSE);
conn->server->http_close_handler(&conn->mg_conn);
}
close_local_endpoint(conn); close_local_endpoint(conn);
free(conn); free(conn);
} }
...@@ -4619,22 +4609,6 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) { ...@@ -4619,22 +4609,6 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
} }
} }
void mg_set_request_handler(struct mg_server *server, mg_handler_t handler) {
server->request_handler = handler;
}
void mg_set_http_close_handler(struct mg_server *server, mg_handler_t handler) {
server->http_close_handler = handler;
}
void mg_set_http_error_handler(struct mg_server *server, mg_handler_t handler) {
server->error_handler = handler;
}
void mg_set_auth_handler(struct mg_server *server, mg_handler_t handler) {
server->auth_handler = handler;
}
void mg_set_listening_socket(struct mg_server *server, int sock) { void mg_set_listening_socket(struct mg_server *server, int sock) {
if (server->ns_server.listening_sock != INVALID_SOCKET) { if (server->ns_server.listening_sock != INVALID_SOCKET) {
closesocket(server->ns_server.listening_sock); closesocket(server->ns_server.listening_sock);
...@@ -4652,9 +4626,10 @@ const char *mg_get_option(const struct mg_server *server, const char *name) { ...@@ -4652,9 +4626,10 @@ const char *mg_get_option(const struct mg_server *server, const char *name) {
return i == -1 ? NULL : opts[i] == NULL ? "" : opts[i]; return i == -1 ? NULL : opts[i] == NULL ? "" : opts[i];
} }
struct mg_server *mg_create_server(void *server_data) { struct mg_server *mg_create_server(void *server_data, mg_handler_t handler) {
struct mg_server *server = (struct mg_server *) calloc(1, sizeof(*server)); struct mg_server *server = (struct mg_server *) calloc(1, sizeof(*server));
ns_server_init(&server->ns_server, server_data, mg_ev_handler); ns_server_init(&server->ns_server, server_data, mg_ev_handler);
set_default_option_values(server->config_options); set_default_option_values(server->config_options);
server->event_handler = handler;
return server; return server;
} }
...@@ -55,26 +55,31 @@ struct mg_connection { ...@@ -55,26 +55,31 @@ struct mg_connection {
int wsbits; // First byte of the websocket frame int wsbits; // First byte of the websocket frame
void *server_param; // Parameter passed to mg_add_uri_handler() void *server_param; // Parameter passed to mg_add_uri_handler()
void *connection_param; // Placeholder for connection-specific data void *connection_param; // Placeholder for connection-specific data
void *callback_param; // Used by mg_iterate_over_connections()
}; };
struct mg_server; // Opaque structure describing server instance struct mg_server; // Opaque structure describing server instance
typedef int (*mg_handler_t)(struct mg_connection *); enum mg_result { MG_FALSE, MG_TRUE };
enum mg_event {
MG_POLL, // Callback return value is ignored
MG_AUTH, // If callback returns MG_FALSE, authentication fails
MG_REQ_BEGIN, // If callback returns MG_FALSE, Mongoose continues with req
MG_REQ_END, // Callback return value is ignored
MG_CLOSE, // Connection is closed
MG_CONNECT, // If callback returns MG_FALSE, connect fails
MG_HTTP_ERROR // If callback returns MG_FALSE, Mongoose continues with err
};
typedef int (*mg_handler_t)(struct mg_connection *, enum mg_event);
// Server management functions // Server management functions
struct mg_server *mg_create_server(void *server_param); struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
void mg_destroy_server(struct mg_server **); void mg_destroy_server(struct mg_server **);
const char *mg_set_option(struct mg_server *, const char *opt, const char *val); const char *mg_set_option(struct mg_server *, const char *opt, const char *val);
int mg_poll_server(struct mg_server *, int milliseconds); int mg_poll_server(struct mg_server *, int milliseconds);
void mg_set_request_handler(struct mg_server *, mg_handler_t);
void mg_set_http_close_handler(struct mg_server *, mg_handler_t);
void mg_set_http_error_handler(struct mg_server *, mg_handler_t);
void mg_set_auth_handler(struct mg_server *, mg_handler_t);
const char **mg_get_valid_option_names(void); const char **mg_get_valid_option_names(void);
const char *mg_get_option(const struct mg_server *server, const char *name); const char *mg_get_option(const struct mg_server *server, const char *name);
void mg_set_listening_socket(struct mg_server *, int sock); void mg_set_listening_socket(struct mg_server *, int sock);
int mg_get_listening_socket(struct mg_server *); int mg_get_listening_socket(struct mg_server *);
void mg_iterate_over_connections(struct mg_server *, mg_handler_t, void *); void mg_iterate_over_connections(struct mg_server *, mg_handler_t);
// Connection management functions // Connection management functions
void mg_send_status(struct mg_connection *, int status_code); void mg_send_status(struct mg_connection *, int status_code);
...@@ -115,8 +120,7 @@ enum { ...@@ -115,8 +120,7 @@ enum {
MG_CONNECT_SUCCESS, MG_CONNECT_FAILURE, MG_CONNECT_SUCCESS, MG_CONNECT_FAILURE,
MG_DOWNLOAD_SUCCESS, MG_DOWNLOAD_FAILURE MG_DOWNLOAD_SUCCESS, MG_DOWNLOAD_FAILURE
}; };
int mg_connect(struct mg_server *, const char *host, int port, int use_ssl, struct mg_connection *mg_connect(struct mg_server *, const char *, int, int);
mg_handler_t handler, void *param);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment