From d5c75ee032c9791f1bb1ad9c0e01163dd4158cc2 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Tue, 20 May 2008 18:07:24 +0000 Subject: + Implement a variant of astman_get_header() to return the first or last match, and possibly skip empty fields. The function is useful (and used here) when a form submits multiple 'Action' fields to the Manager. This change slightly modifies the current behaviour, but only in the case the user supplies multiple 'Action: ' lines and the first ones are empty, so the change is totally harmless. + Fix style on a couple of "if (displayconnects)" statements; + Expand a bit the 'Manager Test' interface, to make it slightly more user friendly. But also comment that the HTML should not be embedded in the C source. None of this stuff needs to be applied to 1.4. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@117297 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/manager.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 9 deletions(-) (limited to 'main/manager.c') diff --git a/main/manager.c b/main/manager.c index 9ad8bd8ca..e0d9f1d02 100644 --- a/main/manager.c +++ b/main/manager.c @@ -799,19 +799,48 @@ static void destroy_session(struct mansession *s) AST_LIST_UNLOCK(&sessions); } -const char *astman_get_header(const struct message *m, char *var) +/* + * Generic function to return either the first or the last matching header + * from a list of variables, possibly skipping empty strings. + * At the moment there is only one use of this function in this file, + * so we make it static. + */ +#define GET_HEADER_FIRST_MATCH 0 +#define GET_HEADER_LAST_MATCH 1 +#define GET_HEADER_SKIP_EMPTY 2 +static const char *__astman_get_header(const struct message *m, char *var, int mode) { int x, l = strlen(var); + const char *result = ""; for (x = 0; x < m->hdrcount; x++) { const char *h = m->headers[x]; - if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') - return h + l + 2; + if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') { + const char *x = h + l + 2; + /* found a potential candidate */ + if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(x)) + continue; /* not interesting */ + if (mode & GET_HEADER_LAST_MATCH) + result = x; /* record the last match so far */ + else + return x; + } } return ""; } +/* + * Return the first matching variable from an array. + * This is the legacy function and is implemented in therms of + * __astman_get_header(). + */ +const char *astman_get_header(const struct message *m, char *var) +{ + return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); +} + + struct ast_variable *astman_get_variables(const struct message *m) { int varlen, x, y; @@ -2789,7 +2818,7 @@ static int process_message(struct mansession *s, const struct message *m) struct manager_action *tmp; const char *user = astman_get_header(m, "Username"); - ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); + ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); ast_debug(1, "Manager received command '%s'\n", action); if (ast_strlen_zero(action)) { @@ -3617,17 +3646,20 @@ static struct ast_str *generic_http_callback(enum output_format format, hdrlen = strlen(v->name) + strlen(v->value) + 3; m.headers[m.hdrcount] = alloca(hdrlen); snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value); + ast_verb(4, "HTTP Manager add header %s\n", m.headers[m.hdrcount]); m.hdrcount = x + 1; } if (process_message(s, &m)) { if (s->authenticated) { - if (manager_displayconnects(s)) + if (manager_displayconnects(s)) { ast_verb(2, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); + } ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); } else { - if (displayconnects) + if (displayconnects) { ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); + } ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); } s->needdestroy = 1; @@ -3644,12 +3676,26 @@ static struct ast_str *generic_http_callback(enum output_format format, if (format == FORMAT_XML) { ast_str_append(&out, 0, "\n"); } else if (format == FORMAT_HTML) { + /* + * When handling AMI-over-HTTP in HTML format, we provide a simple form for + * debugging purposes. This HTML code should not be here, we + * should read from some config file... + */ #define ROW_FMT "%s\r\n" #define TEST_STRING \ - "
action: cmd
\ - user pass
\ -
" + "
\n\ + Action: \n\ + or
\n\ + CLI Command
\n\ + user pass
\n\ + \n
\n" ast_str_append(&out, 0, "Asterisk™ Manager Interface"); ast_str_append(&out, 0, "\r\n"); -- cgit v1.2.3