mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 19:19:00 +08:00
Added ability to set "0" as listening port. Exported local_ip and local_port to the client.
This commit is contained in:
parent
037fdbcccb
commit
8ae0400b0d
18
mongoose.c
18
mongoose.c
@ -275,6 +275,7 @@ struct mg_server {
|
||||
mg_handler_t error_handler;
|
||||
mg_handler_t auth_handler;
|
||||
char *config_options[NUM_OPTIONS];
|
||||
char local_ip[48];
|
||||
void *server_data;
|
||||
#ifdef MONGOOSE_USE_SSL
|
||||
SSL_CTX *ssl_ctx; // Server SSL context
|
||||
@ -1214,6 +1215,7 @@ static void forward_post_data(struct connection *conn) {
|
||||
|
||||
// 'sa' must be an initialized address to bind to
|
||||
static sock_t open_listening_socket(union socket_address *sa) {
|
||||
socklen_t len = sizeof(*sa);
|
||||
sock_t on = 1, sock = INVALID_SOCKET;
|
||||
|
||||
if ((sock = socket(sa->sa.sa_family, SOCK_STREAM, 6)) != INVALID_SOCKET &&
|
||||
@ -1222,6 +1224,8 @@ static sock_t open_listening_socket(union socket_address *sa) {
|
||||
sizeof(sa->sin) : sizeof(sa->sa)) &&
|
||||
!listen(sock, SOMAXCONN)) {
|
||||
set_non_blocking_mode(sock);
|
||||
// In case port was set to 0, get the real port number
|
||||
(void) getsockname(sock, &sa->sa, &len);
|
||||
} else if (sock != INVALID_SOCKET) {
|
||||
closesocket(sock);
|
||||
sock = INVALID_SOCKET;
|
||||
@ -1329,6 +1333,8 @@ static struct connection *accept_new_connection(struct mg_server *server) {
|
||||
sizeof(conn->mg_conn.remote_ip), &sa);
|
||||
conn->mg_conn.remote_port = ntohs(sa.sin.sin_port);
|
||||
conn->mg_conn.server_param = server->server_data;
|
||||
conn->mg_conn.local_ip = server->local_ip;
|
||||
conn->mg_conn.local_port = ntohs(server->lsa.sin.sin_port);
|
||||
LINKED_LIST_ADD_TO_FRONT(&server->active_connections, &conn->link);
|
||||
DBG(("added conn %p", conn));
|
||||
}
|
||||
@ -4067,7 +4073,7 @@ static int parse_port_string(const char *str, union socket_address *sa) {
|
||||
port = 0; // Parsing failure. Make port invalid.
|
||||
}
|
||||
|
||||
return port > 0 && port < 0xffff && str[len] == '\0';
|
||||
return port <= 0xffff && str[len] == '\0';
|
||||
}
|
||||
|
||||
const char *mg_set_option(struct mg_server *server, const char *name,
|
||||
@ -4092,6 +4098,16 @@ const char *mg_set_option(struct mg_server *server, const char *name,
|
||||
server->listening_sock = open_listening_socket(&server->lsa);
|
||||
if (server->listening_sock == INVALID_SOCKET) {
|
||||
error_msg = "Cannot bind to port";
|
||||
} else {
|
||||
sockaddr_to_string(server->local_ip, sizeof(server->local_ip),
|
||||
&server->lsa);
|
||||
if (!strcmp(value, "0")) {
|
||||
char buf[10];
|
||||
mg_snprintf(buf, sizeof(buf), "%d",
|
||||
(int) ntohs(server->lsa.sin.sin_port));
|
||||
free(server->config_options[ind]);
|
||||
server->config_options[ind] = mg_strdup(buf);
|
||||
}
|
||||
}
|
||||
#ifndef _WIN32
|
||||
} else if (ind == RUN_AS_USER) {
|
||||
|
@ -38,6 +38,8 @@ struct mg_connection {
|
||||
|
||||
char remote_ip[48]; // Max IPv6 string length is 45 characters
|
||||
int remote_port; // Client's port
|
||||
const char *local_ip; // Local IP address
|
||||
int local_port; // Local port number
|
||||
|
||||
int num_headers; // Number of HTTP headers
|
||||
struct mg_header {
|
||||
|
12
unit_test.c
12
unit_test.c
@ -289,7 +289,7 @@ static const char *test_parse_port_string(void) {
|
||||
NULL
|
||||
};
|
||||
static const char *invalid[] = {
|
||||
"0", "99999", "1k", "1.2.3", "1.2.3.4:", "1.2.3.4:2p", NULL
|
||||
"99999", "1k", "1.2.3", "1.2.3.4:", "1.2.3.4:2p", NULL
|
||||
};
|
||||
union socket_address sa;
|
||||
int i;
|
||||
@ -301,6 +301,7 @@ static const char *test_parse_port_string(void) {
|
||||
for (i = 0; invalid[i] != NULL; i++) {
|
||||
ASSERT(parse_port_string(invalid[i], &sa) == 0);
|
||||
}
|
||||
ASSERT(parse_port_string("0", &sa) != 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -577,6 +578,14 @@ static const char *test_ssl(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *test_mg_set_option(void) {
|
||||
struct mg_server *server = mg_create_server(NULL);
|
||||
ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
|
||||
ASSERT(mg_get_option(server, "listening_port")[0] != '\0');
|
||||
mg_destroy_server(&server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *run_all_tests(void) {
|
||||
RUN_TEST(test_should_keep_alive);
|
||||
RUN_TEST(test_match_prefix);
|
||||
@ -592,6 +601,7 @@ static const char *run_all_tests(void) {
|
||||
RUN_TEST(test_parse_multipart);
|
||||
RUN_TEST(test_server);
|
||||
RUN_TEST(test_mg_connect);
|
||||
RUN_TEST(test_mg_set_option);
|
||||
#ifdef MONGOOSE_USE_SSL
|
||||
RUN_TEST(test_ssl);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user