Explorar o código

Add new interface to get listening ports (deprecate old interface)

bel %!s(int64=9) %!d(string=hai) anos
pai
achega
ac3e0d8292
Modificáronse 3 ficheiros con 75 adicións e 10 borrados
  1. 14 4
      examples/embedded_c/embedded_c.c
  2. 23 6
      include/civetweb.h
  3. 38 0
      src/civetweb.c

+ 14 - 4
examples/embedded_c/embedded_c.c

@@ -250,6 +250,8 @@ int main(int argc, char *argv[])
                              };
     struct mg_callbacks callbacks;
     struct mg_context *ctx;
+    struct mg_server_ports ports[32];
+    size_t port_cnt, n;
 
     memset(&callbacks, 0, sizeof(callbacks));
     ctx = mg_start(&callbacks, 0, options);
@@ -277,10 +279,18 @@ int main(int argc, char *argv[])
     /* WS site for the websocket connection */
     mg_set_websocket_handler(ctx, "/websocket", WebSocketConnectHandler, WebSocketReadyHandler, WebsocketDataHandler, WebSocketCloseHandler, 0);
 #endif
-
-    printf("Browse files at http://localhost:%s/\n", PORT);
-    printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI);
-    printf("Exit at http://localhost:%s%s\n", PORT, EXIT_URI);
+    
+    memset(ports, 0, sizeof(ports));    
+    port_cnt = mg_get_server_ports(ctx, 32, ports);
+
+    for (n=0; n<port_cnt && n<32; n++) {
+        const char *proto = ports[n].is_ssl ? "https" : "http";
+        const char *host = ports[n].protocol==2 ? "[::1]" : "127.0.0.1";
+        printf("Browse files at %s://%s:%i/\n", proto, host, ports[n].port);
+        printf("Run example at %s://%s:%i%s\n", proto, host, ports[n].port, EXAMPLE_URI);
+        printf("Exit at %s://%s:%i%s\n", proto, host, ports[n].port, EXIT_URI);
+        printf("\n");
+    }
 
     while (!exitNow) {
 #ifdef _WIN32

+ 23 - 6
include/civetweb.h

@@ -386,16 +386,33 @@ enum {
    The array is terminated by a NULL name option. */
 CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
 
+
+struct mg_server_ports {
+	int protocol;    /* 1 = IPv4, 2 = IPv6 */
+	int port;        /* port number */
+	int is_ssl;      /* https port: 0 = no, 1 = yes */
+	int is_redirect; /* redirect all requests: 0 = no, 1 = yes */
+	int _reserved1;
+	int _reserved2;
+	int _reserved3;
+	int _reserved4;
+};
+
 /* Get the list of ports that civetweb is listening on.
-   size is the size of the ports int array and ssl int array to fill.
-   It is the caller's responsibility to make sure ports and ssl each
-   contain at least size int elements worth of memory to write into.
-   Return value is the number of ports and ssl information filled in.
-   The value returned is read-only. Civetweb does not allow changing
-   configuration at run time. */
+   The parameter size is the size of the ports array in elements.
+   The caller is responsibility to allocate the required memory.
+   This function returns the number of struct mg_server_ports elements
+   filled in, or <0 in case of an error. */
+CIVETWEB_API int mg_get_server_ports(const struct mg_context *ctx,
+                                     int size,
+                                     struct mg_server_ports *ports);
+
+
+/* Deprecated. Use mg_get_server_ports instead. */
 CIVETWEB_API size_t
 mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl);
 
+
 /* Add, edit or delete the entry in the passwords file.
 
    This function allows an application to manipulate .htpasswd files on the

+ 38 - 0
src/civetweb.c

@@ -1578,6 +1578,44 @@ mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl)
 }
 
 
+int mg_get_server_ports(const struct mg_context *ctx,
+                        int size,
+                        struct mg_server_ports *ports)
+{
+	int i, cnt = 0;
+
+	if (size <= 0) {
+		return -1;
+	}
+	memset(ports, 0, sizeof(*ports) * size);
+	if (!ctx) {
+		return -1;
+	}
+	if (!ctx->listening_sockets || !ctx->listening_ports) {
+		return -1;
+	}
+
+	for (i = 0; (i < size) && (i < (int)ctx->num_listening_sockets); i++) {
+
+		ports[cnt].port = ctx->listening_ports[i];
+		ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl;
+		ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir;
+
+		if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET) {
+			/* IPv4 */
+			ports[cnt].protocol = 1;
+			cnt++;
+		} else if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) {
+			/* IPv6 */
+			ports[cnt].protocol = 2;
+			cnt++;
+		}
+	}
+
+	return cnt;
+}
+
+
 static void sockaddr_to_string(char *buf, size_t len, const union usa *usa)
 {
 	buf[0] = '\0';