[asterisk-commits] dlee: branch dlee/stasis-http r379374 - in /team/dlee/stasis-http: include/as...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jan 17 09:55:08 CST 2013


Author: dlee
Date: Thu Jan 17 09:55:02 2013
New Revision: 379374

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=379374
Log:
Fixed the API declarations so they are more Swagger friendly.

Modified:
    team/dlee/stasis-http/include/asterisk/stasis_http.h
    team/dlee/stasis-http/include/asterisk/strings.h
    team/dlee/stasis-http/res/res_stasis_http.c
    team/dlee/stasis-http/rest-api/asterisk.json
    team/dlee/stasis-http/rest-api/bridges.json
    team/dlee/stasis-http/rest-api/channels.json
    team/dlee/stasis-http/rest-api/endpoints.json
    team/dlee/stasis-http/rest-api/recordings.json
    team/dlee/stasis-http/rest-api/resources.json
    team/dlee/stasis-http/tests/test_stasis_http.c
    team/dlee/stasis-http/tests/test_strings.c

Modified: team/dlee/stasis-http/include/asterisk/stasis_http.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/stasis_http.h?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/include/asterisk/stasis_http.h (original)
+++ team/dlee/stasis-http/include/asterisk/stasis_http.h Thu Jan 17 09:55:02 2013
@@ -101,7 +101,7 @@
  * Only call from res_stasis_http and test_stasis_http. Only public to allow
  * for unit testing.
  *
- * \param uri HTTP URI.
+ * \param uri HTTP URI, relative to the API path.
  * \param method HTTP method.
  * \param get_params HTTP \c GET parameters.
  * \param headers HTTP headers.
@@ -117,10 +117,10 @@
  * Only call from res_stasis_http and test_stasis_http. Only public to allow
  * for unit testing.
  *
- * \param uri Requested URI.
+ * \param uri Requested URI, relative to the docs path.
  * \param headers HTTP headers.
  * \param[out] response RESTful HTTP response.
  */
-void stasis_http_get_api(const char *uri, struct ast_variable *headers, struct stasis_http_response *response);
+void stasis_http_get_docs(const char *uri, struct ast_variable *headers, struct stasis_http_response *response);
 
 #endif /* _ASTERISK_STASIS_HTTP_H */

Modified: team/dlee/stasis-http/include/asterisk/strings.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/strings.h?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/include/asterisk/strings.h (original)
+++ team/dlee/stasis-http/include/asterisk/strings.h Thu Jan 17 09:55:02 2013
@@ -102,6 +102,33 @@
 }
 )
 
+/*
+  \brief Checks whether a string ends with another.
+  \since 12.0.0
+  \param str String to check.
+  \param suffix Suffix to look for.
+  \param 1 if \a str ends with \a suffix, 0 otherwise.
+ */
+AST_INLINE_API(
+int attribute_pure ast_ends_with(const char *str, const char *suffix),
+{
+	size_t str_len = strlen(str);
+	size_t suffix_len = strlen(suffix);
+
+	ast_assert(str != NULL);
+	ast_assert(suffix != NULL);
+	str_len = strlen(str);
+	suffix_len = strlen(suffix);
+
+	if (suffix_len > str_len) {
+		return 0;
+	}
+
+	return strcmp(str + str_len - suffix_len, suffix) == 0;
+}
+)
+
+
 /*!
   \brief Gets a pointer to the first non-whitespace character in a string.
   \param str the input string

Modified: team/dlee/stasis-http/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/res_stasis_http.c?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_http.c (original)
+++ team/dlee/stasis-http/res/res_stasis_http.c Thu Jan 17 09:55:02 2013
@@ -42,6 +42,7 @@
 #include "asterisk/stasis_http.h"
 
 #include <string.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 /*! WebSocket protocol for Stasis */
@@ -147,14 +148,14 @@
 	}
 }
 
-void stasis_http_get_api(const char *uri, struct ast_variable *headers, struct stasis_http_response *response) {
+void stasis_http_get_docs(const char *uri, struct ast_variable *headers, struct stasis_http_response *response) {
 	RAII_VAR(struct ast_str *, absolute_path_builder, ast_str_create(80), ast_free);
 	RAII_VAR(char *, absolute_api_dirname, NULL, free);
 	RAII_VAR(char *, absolute_filename, NULL, free);
 	struct ast_json *obj = NULL;
-	char *relative_filename = NULL;
 	struct ast_variable *host = NULL;
 	struct ast_json_error error = {};
+	struct stat file_stat;
 
 	ast_log(LOG_DEBUG, "%s(%s)\n", __func__, uri);
 
@@ -174,12 +175,8 @@
 		return;
 	}
 
-	/* Get filename from URI by dropping the first path segment */
-	relative_filename = ast_strdupa(uri);
-	strsep(&relative_filename, "/");
-
 	/* absolute path to the requested file */
-	ast_str_append(&absolute_path_builder, 0, "%s", relative_filename);
+	ast_str_append(&absolute_path_builder, 0, "%s", uri);
 	absolute_filename = realpath(ast_str_buffer(absolute_path_builder), NULL);
 	if (absolute_filename == NULL) {
 		switch (errno) {
@@ -206,6 +203,18 @@
 		return;
 	}
 
+	if (stat(absolute_filename, &file_stat) == 0) {
+		if (!(file_stat.st_mode & S_IFREG)) {
+			/* Not a file */
+			response_error(response, "Invalid access", 403, "Forbidden");
+			return;
+		}
+	} else {
+		/* Does not exist */
+		response_error(response, "Resource not found", 404, "Not Found");
+		return;
+	}
+
 	/* Load resource object from file */
 	obj = ast_json_load_new_file(absolute_filename, &error);
 	if (obj == NULL) {
@@ -262,24 +271,34 @@
 		return -1;
 	}
 
-	if (ast_begins_with(uri, "api/")) {
+	if (ast_ends_with(uri, "/")) {
+		char *slashless = ast_strdupa(uri);
+		slashless[strlen(slashless) - 1] = '\0';
+
+		ast_str_append(&http_headers, 0, "Location: /stasis/%s\r\n", slashless);
+
+		response.message = ast_json_pack("{s: o}", "message", ast_json_stringf("Redirecting to %s", slashless));
+		response.response_code = 302;
+		response.response_text = "Found";
+	} else if (ast_begins_with(uri, "api/")) {
+		/* Other RESTful resources */
+		stasis_http_invoke(uri + 4, method, get_params, headers, &response);
+	} else {
 		/* Serving up API docs */
 		if (method != AST_HTTP_GET) {
 			response.message = ast_json_pack("{s: s}", "message", "Unsupported method");
 			response.response_code = 405;
 			response.response_text = "Method Not Allowed";
 		} else {
-			stasis_http_get_api(uri, headers, &response);
-		}
-	} else {
-		/* Other RESTful resources */
-		stasis_http_invoke(uri, method, get_params, headers, &response);
+			stasis_http_get_docs(uri, headers, &response);
+		}
 	}
 
 	ast_assert(response.message != NULL);
 	ast_assert(response.response_code > 0);
 
-	ast_str_set(&http_headers, 0, "Content-type: application/json\r\nAccess-Control-Allow-Origin: *\r\n");
+	ast_str_append(&http_headers, 0, "Content-type: application/json\r\n");
+	ast_str_append(&http_headers, 0, "Access-Control-Allow-Origin: *\r\n");
 
 	if (ast_json_dump_str(response.message, &response_body) == 0) {
 		ast_http_send(ser, method, response.response_code, response.response_text, http_headers, response_body, 0, 0);

Modified: team/dlee/stasis-http/rest-api/asterisk.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/asterisk.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/asterisk.json (original)
+++ team/dlee/stasis-http/rest-api/asterisk.json Thu Jan 17 09:55:02 2013
@@ -5,10 +5,10 @@
     "apiVersion": "0.0.1",
     "swaggerVersion": "1.1",
     "basePath": "http://localhost:8088/stasis",
-    "resourcePath": "/api/asterisk",
+    "resourcePath": "/asterisk.{format}",
     "apis": [
         {
-            "path": "/asterisk/info",
+            "path": "/api/asterisk/info",
             "description": "Asterisk system information (similar to core show settings)",
             "operations": [
                 {
@@ -37,5 +37,6 @@
                 }
             ]
         }
-    ]
+    ],
+    "models": {}
 }

Modified: team/dlee/stasis-http/rest-api/bridges.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/bridges.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/bridges.json (original)
+++ team/dlee/stasis-http/rest-api/bridges.json Thu Jan 17 09:55:02 2013
@@ -8,7 +8,7 @@
     "resourcePath": "/bridges.json",
     "apis": [
         {
-            "path": "/bridges",
+            "path": "/api/bridges",
             "description": "Active bridges",
             "operations": [
                 {
@@ -26,7 +26,7 @@
              ]
         },
         {
-            "path": "/bridges/{bridgeId}",
+            "path": "/api/bridges/{bridgeId}",
             "description": "Individual bridge",
             "operations": [
                 {
@@ -64,7 +64,7 @@
             ]
         },
         {
-            "path": "/bridges/{bridgeId}/addChannel",
+            "path": "/api/bridges/{bridgeId}/addChannel",
             "description": "Add a channel to a bridge",
             "operations": [
                 {
@@ -94,7 +94,7 @@
             ]
         },
         {
-            "path": "/bridges/{bridgeId}/removeChannel",
+            "path": "/api/bridges/{bridgeId}/removeChannel",
             "description": "Remove a channel from a bridge",
             "operations": [
                 {
@@ -124,7 +124,7 @@
             ]
         },
         {
-            "path": "/bridges/{bridgeId}/record",
+            "path": "/api/bridges/{bridgeId}/record",
             "description": "Record audio to/from a bridge",
             "operations": [
                 {
@@ -207,5 +207,6 @@
                 }
             ]
         }
-    ]
+    ],
+    "models": {}
 }

Modified: team/dlee/stasis-http/rest-api/channels.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/channels.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/channels.json (original)
+++ team/dlee/stasis-http/rest-api/channels.json Thu Jan 17 09:55:02 2013
@@ -8,7 +8,7 @@
     "resourcePath": "/channels",
     "apis": [
         {
-            "path": "/channels",
+            "path": "/api/channels",
             "description": "Active channels",
             "operations": [
                 {
@@ -52,7 +52,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}",
+            "path": "/api/channels/{channelId}",
             "description": "Active channel",
             "operations": [
                 {
@@ -90,7 +90,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/dial",
+            "path": "/api/channels/{channelId}/dial",
             "description": "Create a new channel (originate) and bridge to this channel",
             "operations": [
                 {
@@ -128,7 +128,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/continue",
+            "path": "/api/channels/{channelId}/continue",
             "description": "Exit application; continue execution in the dialplan",
             "operations": [
                 {
@@ -150,7 +150,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/reject",
+            "path": "/api/channels/{channelId}/reject",
             "description": "Reject a channel",
             "operations": [
                 {
@@ -172,7 +172,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/answer",
+            "path": "/api/channels/{channelId}/answer",
             "description": "Answer a channel",
             "operations": [
                 {
@@ -194,7 +194,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/hangup",
+            "path": "/api/channels/{channelId}/hangup",
             "description": "Hangup a channel",
             "operations": [
                 {
@@ -216,7 +216,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/mute",
+            "path": "/api/channels/{channelId}/mute",
             "description": "Mute a channel",
             "operations": [
                 {
@@ -255,7 +255,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/unmute",
+            "path": "/api/channels/{channelId}/unmute",
             "description": "Unmute a channel",
             "operations": [
                 {
@@ -294,7 +294,7 @@
             ]
         },
         {
-            "path": "/channels/{channelId}/record",
+            "path": "/api/channels/{channelId}/record",
             "description": "Record audio to/from a channel",
             "operations": [
                 {
@@ -377,5 +377,6 @@
                 }
             ]
         }
-    ]
+    ],
+    "models": {}
 }

Modified: team/dlee/stasis-http/rest-api/endpoints.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/endpoints.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/endpoints.json (original)
+++ team/dlee/stasis-http/rest-api/endpoints.json Thu Jan 17 09:55:02 2013
@@ -8,7 +8,7 @@
     "resourcePath": "/endpoints",
     "apis": [
         {
-            "path": "/endpoints",
+            "path": "/api/endpoints",
             "description": "Asterisk endpoints",
             "operations": [
                 {
@@ -30,7 +30,7 @@
             ]
         },
         {
-            "path": "/endpoints/{endpointId}",
+            "path": "/api/endpoints/{endpointId}",
             "description": "Single endpoint",
             "operations": [
                 {
@@ -49,5 +49,6 @@
                 }
             ]
         }
-    ]
+    ],
+    "models": {}
 }

Modified: team/dlee/stasis-http/rest-api/recordings.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/recordings.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/recordings.json (original)
+++ team/dlee/stasis-http/rest-api/recordings.json Thu Jan 17 09:55:02 2013
@@ -8,7 +8,7 @@
     "resourcePath": "/recordings",
     "apis": [
         {
-            "path": "/recordings",
+            "path": "/api/recordings",
             "description": "Recordings",
             "operations": [
                 {
@@ -20,7 +20,7 @@
              ]
         },
         {
-            "path": "/recordings/{recordingId}",
+            "path": "/api/recordings/{recordingId}",
             "description": "Individual recording",
             "operations": [
                 {
@@ -58,7 +58,7 @@
             ]
         },
         {
-            "path": "/recordings/{recordingId}/stop",
+            "path": "/api/recordings/{recordingId}/stop",
             "operations": [
                 {
                     "httpMethod": "POST",
@@ -79,7 +79,7 @@
             ]
         },
         {
-            "path": "/recordings/{recordingId}/pause",
+            "path": "/api/recordings/{recordingId}/pause",
             "operations": [
                 {
                     "httpMethod": "POST",
@@ -100,7 +100,7 @@
             ]
         },
         {
-            "path": "/recordings/{recordingId}/unpause",
+            "path": "/api/recordings/{recordingId}/unpause",
             "operations": [
                 {
                     "httpMethod": "POST",
@@ -121,7 +121,7 @@
             ]
         },
         {
-            "path": "/recordings/{recordingId}/mute",
+            "path": "/api/recordings/{recordingId}/mute",
             "operations": [
                 {
                     "httpMethod": "POST",
@@ -142,7 +142,7 @@
             ]
         },
         {
-            "path": "/recordings/{recordingId}/unmute",
+            "path": "/api/recordings/{recordingId}/unmute",
             "operations": [
                 {
                     "httpMethod": "POST",
@@ -162,5 +162,6 @@
                 }
             ]
         }
-    ]
+    ],
+    "models": {}
 }

Modified: team/dlee/stasis-http/rest-api/resources.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/rest-api/resources.json?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/rest-api/resources.json (original)
+++ team/dlee/stasis-http/rest-api/resources.json Thu Jan 17 09:55:02 2013
@@ -7,23 +7,23 @@
     "basePath": "http://localhost:8088/stasis",
     "apis": [
         {
-            "path": "/api/asterisk.{format}",
+            "path": "/asterisk.{format}",
             "description": "Asterisk resources"
         },
         {
-            "path": "/api/endpoints.{format}",
+            "path": "/endpoints.{format}",
             "description": "Endpoint resources"
         },
         {
-            "path": "/api/channels.{format}",
+            "path": "/channels.{format}",
             "description": "Channel resources"
         },
         {
-            "path": "/api/bridges.{format}",
+            "path": "/bridges.{format}",
             "description": "Bridge resources"
         },
         {
-            "path": "/api/recordings.{format}",
+            "path": "/recordings.{format}",
             "description": "Recording resources"
         }
     ]

Modified: team/dlee/stasis-http/tests/test_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/tests/test_stasis_http.c?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/tests/test_stasis_http.c (original)
+++ team/dlee/stasis-http/tests/test_stasis_http.c Thu Jan 17 09:55:02 2013
@@ -190,7 +190,7 @@
 }
 
 
-AST_TEST_DEFINE(get_api)
+AST_TEST_DEFINE(get_docs)
 {
 	RAII_VAR(struct stasis_http_response *, response, response_alloc(), response_free);
 	RAII_VAR(struct ast_variable *, headers, NULL, ast_variables_destroy);
@@ -209,7 +209,7 @@
 	}
 
 	headers = ast_variable_new("Host", "stasis.asterisk.org", __FILE__);
-	stasis_http_get_api("api/resources.json", headers, response);
+	stasis_http_get_docs("resources.json", headers, response);
 	ast_test_validate(test, 200 == response->response_code);
 
 	/* basePath should be relative to the Host header */
@@ -221,7 +221,7 @@
 	return AST_TEST_PASS;
 }
 
-AST_TEST_DEFINE(get_api_nohost)
+AST_TEST_DEFINE(get_docs_nohost)
 {
 	RAII_VAR(struct stasis_http_response *, response, response_alloc(), response_free);
 	struct ast_variable *headers = NULL;
@@ -238,7 +238,7 @@
 		break;
 	}
 
-	stasis_http_get_api("api/resources.json", headers, response);
+	stasis_http_get_docs("resources.json", headers, response);
 	ast_test_validate(test, 200 == response->response_code);
 
 	/* basePath should be relative to the Host header */
@@ -248,7 +248,7 @@
 	return AST_TEST_PASS;
 }
 
-AST_TEST_DEFINE(get_api_notfound)
+AST_TEST_DEFINE(get_docs_notfound)
 {
 	RAII_VAR(struct stasis_http_response *, response, response_alloc(), response_free);
 	struct ast_variable *headers = NULL;
@@ -264,13 +264,13 @@
 		break;
 	}
 
-	stasis_http_get_api("api/i-am-not-a-resource.json", headers, response);
+	stasis_http_get_docs("i-am-not-a-resource.json", headers, response);
 	ast_test_validate(test, 404 == response->response_code);
 
 	return AST_TEST_PASS;
 }
 
-AST_TEST_DEFINE(get_api_hackerz)
+AST_TEST_DEFINE(get_docs_hackerz)
 {
 	RAII_VAR(struct stasis_http_response *, response, response_alloc(), response_free);
 	struct ast_variable *headers = NULL;
@@ -286,7 +286,7 @@
 		break;
 	}
 
-	stasis_http_get_api("api/../../../../sbin/asterisk", headers, response);
+	stasis_http_get_docs("../../../../sbin/asterisk", headers, response);
 	ast_test_validate(test, 404 == response->response_code);
 
 	return AST_TEST_PASS;
@@ -512,10 +512,10 @@
 
 static int unload_module(void)
 {
-	AST_TEST_UNREGISTER(get_api);
-	AST_TEST_UNREGISTER(get_api_nohost);
-	AST_TEST_UNREGISTER(get_api_notfound);
-	AST_TEST_UNREGISTER(get_api_hackerz);
+	AST_TEST_UNREGISTER(get_docs);
+	AST_TEST_UNREGISTER(get_docs_nohost);
+	AST_TEST_UNREGISTER(get_docs_notfound);
+	AST_TEST_UNREGISTER(get_docs_hackerz);
 	AST_TEST_UNREGISTER(invoke_get);
 	AST_TEST_UNREGISTER(invoke_wildcard);
 	AST_TEST_UNREGISTER(invoke_delete);
@@ -527,10 +527,10 @@
 
 static int load_module(void)
 {
-	AST_TEST_REGISTER(get_api);
-	AST_TEST_REGISTER(get_api_nohost);
-	AST_TEST_REGISTER(get_api_notfound);
-	AST_TEST_REGISTER(get_api_hackerz);
+	AST_TEST_REGISTER(get_docs);
+	AST_TEST_REGISTER(get_docs_nohost);
+	AST_TEST_REGISTER(get_docs_notfound);
+	AST_TEST_REGISTER(get_docs_hackerz);
 	AST_TEST_REGISTER(invoke_get);
 	AST_TEST_REGISTER(invoke_wildcard);
 	AST_TEST_REGISTER(invoke_delete);

Modified: team/dlee/stasis-http/tests/test_strings.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/tests/test_strings.c?view=diff&rev=379374&r1=379373&r2=379374
==============================================================================
--- team/dlee/stasis-http/tests/test_strings.c (original)
+++ team/dlee/stasis-http/tests/test_strings.c Thu Jan 17 09:55:02 2013
@@ -280,11 +280,41 @@
 	return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(ends_with_test)
+{
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "ends_with";
+		info->category = "/main/strings/";
+		info->summary = "Test ast_ends_with";
+		info->description = "Test ast_ends_with";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	// prefixes
+	ast_test_validate(test, 1 == ast_ends_with("foobar", "foobar"));
+	ast_test_validate(test, 1 == ast_ends_with("foobar", "bar"));
+	ast_test_validate(test, 1 == ast_ends_with("foobar", ""));
+	ast_test_validate(test, 1 == ast_ends_with("", ""));
+
+	// not suffixes
+	ast_test_validate(test, 0 == ast_ends_with("bar", "bbar"));
+	ast_test_validate(test, 0 == ast_ends_with("foobar", "bang"));
+	ast_test_validate(test, 0 == ast_ends_with("foobar", "foobat"));
+	ast_test_validate(test, 0 == ast_ends_with("boo", "boom"));
+	ast_test_validate(test, 0 == ast_ends_with("", "blitz"));
+
+	// nothing failed; we're all good!
+	return AST_TEST_PASS;
+}
 
 static int unload_module(void)
 {
 	AST_TEST_UNREGISTER(str_test);
 	AST_TEST_UNREGISTER(begins_with_test);
+	AST_TEST_UNREGISTER(ends_with_test);
 	return 0;
 }
 
@@ -292,6 +322,7 @@
 {
 	AST_TEST_REGISTER(str_test);
 	AST_TEST_REGISTER(begins_with_test);
+	AST_TEST_REGISTER(ends_with_test);
 	return AST_MODULE_LOAD_SUCCESS;
 }
 




More information about the asterisk-commits mailing list