mirror of
https://github.com/graygnuorg/pound.git
synced 2026-10-28 11:35:07 +03:00
Identify listeners and services by their names (labels) as well as indices
* src/config.c (parse_listen_http) (parse_listen_https): Handle optional listener name. Make sure it is unique. (parse_service): Make sure service name is unique. * src/pound.h (LISTENER): New field: name. * src/poundctl.tmpl: Show listener name, if available. * svc.c (get_nth_listener, get_nth_service) (get_nth_backend,ctl_getnum): Remove. (IDENT): New data type. (ctl_getident,locate_listener,locate_service) (locate_backend): New functions. (service_serialize): Represent NULL service name as null. (listener_serialize): Add listener name. (ctl_service,ctl_listener): Identify objects by their ids or numbers. * NEWS: Document changes. * doc/pound.8: Likewise. * doc/poundctl.8: Likewise.
This commit is contained in:
29
NEWS
29
NEWS
@@ -1,4 +1,4 @@
|
||||
Pound -- history of user-visible changes. 2023-02-20
|
||||
Pound -- history of user-visible changes. 2023-03-03
|
||||
See the end of file for copying conditions.
|
||||
|
||||
Pound is a continuation of the software originally developed by
|
||||
@@ -113,6 +113,33 @@ Request accessor can be used in all strings where the use of
|
||||
backreferences is allowed: i.e. arguments to Redirect, ACME,
|
||||
Error directives, and to all request modification directives described
|
||||
above.
|
||||
|
||||
* Listener labels
|
||||
|
||||
Listeners can be assigned symbolic labels. The syntax is:
|
||||
|
||||
ListenHTTP "name"
|
||||
or
|
||||
ListenHTTPS "name"
|
||||
|
||||
The "name" must be unique among all listeners defined in the
|
||||
configuration.
|
||||
|
||||
This symbolic name can be used to identify listener in poundctl
|
||||
requests (see below).
|
||||
|
||||
* Service labels
|
||||
|
||||
Service labels must be unique among all services within the
|
||||
listener (or in the configuration file, for global ones).
|
||||
|
||||
* Use of listener and service labels in poundctl
|
||||
|
||||
Listeners and services can be identified both by their numbers and
|
||||
labels. For example:
|
||||
|
||||
poundctl list /main/static/1
|
||||
|
||||
|
||||
Version 4.5, 2023-02-12
|
||||
|
||||
|
||||
41
doc/pound.8
41
doc/pound.8
@@ -14,7 +14,7 @@
|
||||
.\"
|
||||
.\" You should have received a copy of the GNU General Public License
|
||||
.\" along with pound. If not, see <http://www.gnu.org/licenses/>.
|
||||
.TH POUND 8 "February 19, 2023" "pound" "System Manager's Manual"
|
||||
.TH POUND 8 "March 3, 2023" "pound" "System Manager's Manual"
|
||||
.SH NAME
|
||||
pound \- HTTP/HTTPS reverse-proxy and load-balancer
|
||||
.SH SYNOPSIS
|
||||
@@ -144,6 +144,13 @@ Normally, the connection between
|
||||
and
|
||||
.I backends
|
||||
is via plain HTTP. It is, however, possible to use HTTPS as well.
|
||||
.PP
|
||||
A working
|
||||
.B pound
|
||||
configuration may define multiple listeners and services. They can be
|
||||
identified either by 0-based ordinal number within the configuration
|
||||
(or, for services, within the listener) or by their symbolic name.
|
||||
Backends are identified by their ordinal number within service.
|
||||
.SH WORKER MODEL
|
||||
Each incoming request is processed by a specific \fIworker\fR, i.e. a
|
||||
thread in the running program. The number of running workers is
|
||||
@@ -549,12 +556,18 @@ the PID file will remain on disk after termination of the program.
|
||||
.SH "HTTP Listener"
|
||||
An HTTP listener defines an address and port that
|
||||
.B pound
|
||||
will listen on for HTTP requests. All configuration directives enclosed
|
||||
between
|
||||
will listen on for HTTP requests. The listener declaration begins with
|
||||
the keyword
|
||||
.B ListenHTTP
|
||||
on a separate line. The keyword may be followed by a quoted string
|
||||
supplying listener name. This name is a unique label that identifies
|
||||
the listener.
|
||||
.PP
|
||||
All configuration directives enclosed between
|
||||
.B ListenHTTP
|
||||
and
|
||||
.B End
|
||||
are specific to a single HTTP listener. At the very least you must specify
|
||||
are specific to a single HTTP listener. At the very least you must specify
|
||||
and address and a port for each listener. The following directives are
|
||||
available:
|
||||
.TP
|
||||
@@ -673,10 +686,12 @@ value.
|
||||
.TP
|
||||
\fBService\fR [ "name" ]
|
||||
This defines a private service (see below for service definition
|
||||
syntax). This service will be used only by this listener. The service
|
||||
may be optionally named, with the name showing in the
|
||||
syntax). This service will be used only by this listener. Optional
|
||||
\fIname\fR supplies the label, that can be used in
|
||||
.BR poundctl (8)
|
||||
listings.
|
||||
requests to identify the service. This label must be unique among all
|
||||
services within the enclosing listener, or, for global services,
|
||||
within the configuration.
|
||||
.TP
|
||||
\fBACME\fR "directory"
|
||||
Serve ACME challenge requests from the given
|
||||
@@ -777,8 +792,14 @@ Same as \fBDeleteHeader\fR.
|
||||
.SH "HTTPS Listener"
|
||||
An HTTPS listener defines an address and port that
|
||||
.B pound
|
||||
will listen on for HTTPS requests. All configuration directives enclosed
|
||||
between
|
||||
will listen on for HTTPS requests. The listener declaration begins with
|
||||
the keyword
|
||||
.B ListenHTTPS
|
||||
on a separate line. The keyword may be followed by a quoted string
|
||||
supplying listener name. This name is a unique label that identifies
|
||||
the listener.
|
||||
.PP
|
||||
All configuration directives enclosed between
|
||||
.B ListenHTTPS
|
||||
and
|
||||
.B End
|
||||
@@ -1124,7 +1145,7 @@ statement. Numbering of subexpressions starts at 1 (\fB$0\fR refers
|
||||
to the entire matching string). Numbering of matches starts
|
||||
at 0.
|
||||
.IP
|
||||
For example, given the following statements
|
||||
For example, given the following statements
|
||||
.IP
|
||||
.EX
|
||||
Host -re "www\\.(.+)"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
.\"
|
||||
.\" You should have received a copy of the GNU General Public License
|
||||
.\" along with pound. If not, see <http://www.gnu.org/licenses/>.
|
||||
.TH POUNDCTL 8 "January 13, 2023" "poundctl" "System Manager's Manual"
|
||||
.TH POUNDCTL 8 "March 3, 2023" "poundctl" "System Manager's Manual"
|
||||
.SH NAME
|
||||
poundctl \- control the pound daemon
|
||||
.SH SYNOPSIS
|
||||
@@ -62,8 +62,22 @@ All commands take the \fB/\fIL\fB/\fIS\fB/\fIB\fR argument, which
|
||||
specifies the
|
||||
.B pound
|
||||
object to apply the command to. Here, \fIL\fR, \fIS\fR, and \fIB\fR
|
||||
stand for the numbers of \fIlistener\fR, \fIservice\fR and
|
||||
\fIbackend\fR, correspondingly. Depending on the command, either
|
||||
stand for the identifiers of \fIlistener\fR, \fIservice\fR and
|
||||
\fIbackend\fR, correspondingly. For listeners and services, both
|
||||
numeric identifiers or symbolic names are allowed. Numeric
|
||||
identifiers refer to the ordinal number of the listener in the
|
||||
configuration file, or service within the enclosing listener
|
||||
(or in the configuration file, if \fIL\fR is \fB\-\fR, see below).
|
||||
Symbolic names refer to the names assigned with the corresponding
|
||||
.BR ListenHTTP ,
|
||||
.BR ListenHTTPS ,
|
||||
or
|
||||
.B Service
|
||||
statement in the configuration file. The identifier \fIB\fR is
|
||||
always numeric and refers to the ordinal number of the backend in
|
||||
the service.
|
||||
.PP
|
||||
Depending on the command, either
|
||||
\fIB\fR or both /\fIS\fR/\fIB\fR/ may be omitted. For example,
|
||||
the following command will disable backend 2 in service 1 of listener 0:
|
||||
.PP
|
||||
|
||||
65
src/config.c
65
src/config.c
@@ -45,7 +45,7 @@ typedef unsigned TOKENMASK;
|
||||
#define T_MASK_ISSET(m,t) ((m) & T_BIT(t))
|
||||
#define T_ANY 0 /* any token, inlcuding newline */
|
||||
/* Unquoted character sequence */
|
||||
#define T_UNQ (T_BIT (T_IDENT) | T_BIT (T_NUMBER) | T_BIT(T_LITERAL))
|
||||
#define T_UNQ (T_BIT (T_IDENT) | T_BIT (T_NUMBER) | T_BIT (T_LITERAL))
|
||||
|
||||
/* Locations in the source file */
|
||||
struct locus_point
|
||||
@@ -2650,6 +2650,18 @@ static PARSER_TABLE service_parsetab[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
find_service_ident (SERVICE_HEAD *svc_head, char const *name)
|
||||
{
|
||||
SERVICE *svc;
|
||||
SLIST_FOREACH (svc, svc_head, next)
|
||||
{
|
||||
if (svc->name && strcmp (svc->name, name) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_service (void *call_data, void *section_data)
|
||||
{
|
||||
@@ -2672,7 +2684,14 @@ parse_service (void *call_data, void *section_data)
|
||||
return PARSER_FAIL;
|
||||
|
||||
if (tok->type == T_STRING)
|
||||
svc->name = xstrdup (tok->str);
|
||||
{
|
||||
if (find_service_ident (head, tok->str))
|
||||
{
|
||||
conf_error ("%s", "service name is not unique");
|
||||
return PARSER_FAIL;
|
||||
}
|
||||
svc->name = xstrdup (tok->str);
|
||||
}
|
||||
else
|
||||
putback_tkn (tok);
|
||||
|
||||
@@ -3055,6 +3074,18 @@ listener_alloc (POUND_DEFAULTS *dfl)
|
||||
return lst;
|
||||
}
|
||||
|
||||
static int
|
||||
find_listener_ident (LISTENER_HEAD *list_head, char const *name)
|
||||
{
|
||||
LISTENER *lstn;
|
||||
SLIST_FOREACH (lstn, list_head, next)
|
||||
{
|
||||
if (lstn->name && strcmp (lstn->name, name) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_listen_http (void *call_data, void *section_data)
|
||||
{
|
||||
@@ -3062,10 +3093,25 @@ parse_listen_http (void *call_data, void *section_data)
|
||||
LISTENER_HEAD *list_head = call_data;
|
||||
POUND_DEFAULTS *dfl = section_data;
|
||||
struct locus_range range;
|
||||
struct token *tok;
|
||||
|
||||
if ((lst = listener_alloc (dfl)) == NULL)
|
||||
return PARSER_FAIL;
|
||||
|
||||
if ((tok = gettkn_any ()) == NULL)
|
||||
return PARSER_FAIL;
|
||||
else if (tok->type == T_STRING)
|
||||
{
|
||||
if (find_listener_ident (list_head, tok->str))
|
||||
{
|
||||
conf_error ("%s", "listener name is not unique");
|
||||
return PARSER_FAIL;
|
||||
}
|
||||
lst->name = xstrdup (tok->str);
|
||||
}
|
||||
else
|
||||
putback_tkn (tok);
|
||||
|
||||
if (parser_loop (http_parsetab, lst, section_data, &range))
|
||||
return PARSER_FAIL;
|
||||
|
||||
@@ -3585,10 +3631,25 @@ parse_listen_https (void *call_data, void *section_data)
|
||||
struct locus_range range;
|
||||
POUND_CTX *pc;
|
||||
struct stringbuf sb;
|
||||
struct token *tok;
|
||||
|
||||
if ((lst = listener_alloc (dfl)) == NULL)
|
||||
return PARSER_FAIL;
|
||||
|
||||
if ((tok = gettkn_any ()) == NULL)
|
||||
return PARSER_FAIL;
|
||||
else if (tok->type == T_STRING)
|
||||
{
|
||||
if (find_listener_ident (list_head, tok->str))
|
||||
{
|
||||
conf_error ("%s", "listener name is not unique");
|
||||
return PARSER_FAIL;
|
||||
}
|
||||
lst->name = xstrdup (tok->str);
|
||||
}
|
||||
else
|
||||
putback_tkn (tok);
|
||||
|
||||
lst->ssl_op_enable = SSL_OP_ALL;
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
lst->ssl_op_enable |= SSL_OP_NO_COMPRESSION;
|
||||
|
||||
@@ -613,6 +613,7 @@ typedef SLIST_HEAD (,_pound_ctx) POUND_CTX_HEAD;
|
||||
/* Listener definition */
|
||||
typedef struct _listener
|
||||
{
|
||||
char *name; /* symbolic name */
|
||||
struct addrinfo addr; /* IPv4/6 address */
|
||||
int sock; /* listening socket */
|
||||
POUND_CTX_HEAD ctx_head; /* CTX for SSL connections */
|
||||
|
||||
@@ -54,12 +54,12 @@ Listeners:
|
||||
|
||||
{{range $lno,$lstn = .listeners -}}
|
||||
{{printf "%3d" $lno}}. {{block "default.print_listener" $lstn -}}
|
||||
Listener {{.protocol}}://{{.address}} {{if .enabled}}enabled{{else}}disabled{{end}}
|
||||
Listener {{if .name}}"{{.name}}" {{end}}{{.protocol}}://{{.address}} {{if .enabled}}enabled{{else}}disabled{{end}}
|
||||
{{- /* For each listener, show all its services */ -}}
|
||||
{{block "default.print_services" .services}}
|
||||
{{- range $sno,$svc = .}}
|
||||
{{printf "%3d" $sno}}. {{block "default.print_service" $svc -}}
|
||||
Service "{{.name}}" {{if .enabled}}active{{else}}disabled{{end}} ({{.tot_pri}})
|
||||
Service {{if .name}}"{{.name}}" {{end}}{{if .enabled}}active{{else}}disabled{{end}} ({{.tot_pri}})
|
||||
{{- /* List each backend in service */ -}}
|
||||
{{- range $bno,$backend = .backends}}
|
||||
{{printf "%3d" $bno}}. {{block "default.print_backend" $backend -}}
|
||||
@@ -125,7 +125,7 @@ Global services:
|
||||
{{- /* Iterate over all listeners */ -}}
|
||||
{{- range $lno,$lstn = .listeners }}
|
||||
{{block "xml.print_listener" $lstn -}}
|
||||
<listener index="{{ $lno }}" protocol="{{ .protocol }}" address="{{ .address }}" status="{{if .enabled}}active{{else}}DISABLED{{end}}>
|
||||
<listener name="{{ .name }}" index="{{ $lno }}" protocol="{{ .protocol }}" address="{{ .address }}" status="{{if .enabled}}active{{else}}DISABLED{{end}}>
|
||||
{{- block "xml.print_services" .services}}
|
||||
{{- range $sno,$svc = . }}
|
||||
{{block "xml.print_service" $svc -}}
|
||||
|
||||
218
src/svc.c
218
src/svc.c
@@ -1503,57 +1503,6 @@ get_param (char const *url, char const *param, size_t *ret_len)
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* return listener by its number
|
||||
*/
|
||||
static LISTENER *
|
||||
get_nth_listener (int n)
|
||||
{
|
||||
LISTENER *lstn;
|
||||
|
||||
SLIST_FOREACH (lstn, &listeners, next)
|
||||
{
|
||||
if (n == 0)
|
||||
break;
|
||||
n--;
|
||||
}
|
||||
return lstn;
|
||||
}
|
||||
|
||||
/*
|
||||
* return service by its number
|
||||
*/
|
||||
static SERVICE *
|
||||
get_nth_service (LISTENER *lstn, int n)
|
||||
{
|
||||
SERVICE *svc;
|
||||
SERVICE_HEAD *head = lstn ? &lstn->services : &services;
|
||||
SLIST_FOREACH (svc, head, next)
|
||||
{
|
||||
if (n == 0)
|
||||
break;
|
||||
n--;
|
||||
}
|
||||
return svc;
|
||||
}
|
||||
|
||||
/*
|
||||
* select a back-end by number
|
||||
*/
|
||||
static BACKEND *
|
||||
get_nth_backend (SERVICE *svc, int n)
|
||||
{
|
||||
BACKEND *be;
|
||||
|
||||
SLIST_FOREACH (be, &svc->backends, next)
|
||||
{
|
||||
if (n == 0)
|
||||
break;
|
||||
n--;
|
||||
}
|
||||
return be;
|
||||
}
|
||||
|
||||
static int
|
||||
session_backend_index (SESSION *sess)
|
||||
{
|
||||
@@ -1821,7 +1770,7 @@ service_serialize (SERVICE *svc)
|
||||
pthread_mutex_lock (&svc->mut);
|
||||
|
||||
typename = sess_type_to_str (svc->sess_type);
|
||||
if (json_object_set (obj, "name", json_new_string (svc->name ? svc->name : ""))
|
||||
if ((svc->name && json_object_set (obj, "name", json_new_string (svc->name)))
|
||||
|| json_object_set (obj, "enabled", json_new_bool (!svc->disabled))
|
||||
|| json_object_set (obj, "tot_pri", json_new_integer (svc->tot_pri))
|
||||
|| json_object_set (obj, "abs_pri", json_new_integer (svc->abs_pri))
|
||||
@@ -1850,7 +1799,9 @@ listener_serialize (LISTENER *lstn)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
err = json_object_set (obj, "address", addrinfo_serialize (&lstn->addr));
|
||||
if (lstn->name)
|
||||
err = json_object_set (obj, "name", json_new_string (lstn->name));
|
||||
err |= json_object_set (obj, "address", addrinfo_serialize (&lstn->addr));
|
||||
|
||||
is_https = !SLIST_EMPTY (&lstn->ctx_head);
|
||||
err |= json_object_set (obj, "protocol",
|
||||
@@ -2050,26 +2001,139 @@ control_list_all (BIO *c, char const *url)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
ctl_getnum (char const **url)
|
||||
/*
|
||||
* Type of object identifier.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
IDTYPE_ERR = -1,
|
||||
IDTYPE_NUM, /* Numeric identifier (index). */
|
||||
IDTYPE_STR /* String identifier (name). */
|
||||
};
|
||||
|
||||
/*
|
||||
* Object identifier.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int type; /* Identifier type. */
|
||||
union
|
||||
{
|
||||
int n; /* Index value (IDTYPE_NUM). */
|
||||
struct /* String value (IDTYPE_STR). */
|
||||
{
|
||||
int len; /* Name length. */
|
||||
char const *name; /* Pointer to the name. */
|
||||
} s;
|
||||
};
|
||||
} IDENT;
|
||||
|
||||
/*
|
||||
* Get single identifier from the URL (must point to a /, on entry).
|
||||
* On success, advance URL to the point past the end of the identifier
|
||||
* (normally next / or end of URL).
|
||||
* On error, return ident with its type set to IDTYPE_ERR.
|
||||
*/
|
||||
static IDENT
|
||||
ctl_getident (char const **url)
|
||||
{
|
||||
IDENT retval = { IDTYPE_ERR };
|
||||
long n;
|
||||
char *end;
|
||||
|
||||
if (**url == '/')
|
||||
++*url;
|
||||
else
|
||||
return -1;
|
||||
errno = 0;
|
||||
n = strtol (*url, &end, 10);
|
||||
if (errno || n > INT_MAX)
|
||||
return -1;
|
||||
if (*end != 0 && *end != '/' && *end != '?')
|
||||
return -1;
|
||||
*url = end;
|
||||
return n;
|
||||
{
|
||||
++*url;
|
||||
errno = 0;
|
||||
n = strtol (*url, &end, 10);
|
||||
if (*end != 0 && *end != '/' && *end != '?')
|
||||
{
|
||||
end = (char*) *url + strcspn (*url, "/?");
|
||||
retval.s.name = *url;
|
||||
retval.s.len = end - *url;
|
||||
retval.type = IDTYPE_STR;
|
||||
*url = end;
|
||||
}
|
||||
else if (errno == 0 && n <= INT_MAX)
|
||||
{
|
||||
retval.type = IDTYPE_NUM;
|
||||
retval.n = n;
|
||||
*url = end;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate listener identified by ID.
|
||||
*/
|
||||
static LISTENER *
|
||||
locate_listener (IDENT id)
|
||||
{
|
||||
LISTENER *lstn = NULL;
|
||||
|
||||
if (id.type != IDTYPE_ERR)
|
||||
{
|
||||
long n = 0;
|
||||
SLIST_FOREACH (lstn, &listeners, next)
|
||||
{
|
||||
if ((id.type == IDTYPE_NUM && n == id.n) ||
|
||||
(lstn->name && strlen (lstn->name) == id.s.len &&
|
||||
memcmp (lstn->name, id.s.name, id.s.len) == 0))
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return lstn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate service identified by ID. If LSTN is null, look it up in the
|
||||
* global service list.
|
||||
*/
|
||||
static SERVICE *
|
||||
locate_service (LISTENER *lstn, IDENT id)
|
||||
{
|
||||
SERVICE *svc = 0;
|
||||
|
||||
if (id.type != IDTYPE_ERR)
|
||||
{
|
||||
int n = 0;
|
||||
SERVICE_HEAD *head = lstn ? &lstn->services : &services;
|
||||
|
||||
SLIST_FOREACH (svc, head, next)
|
||||
{
|
||||
if ((id.type == IDTYPE_NUM && n == id.n) ||
|
||||
(svc->name && strlen (svc->name) == id.s.len &&
|
||||
memcmp (svc->name, id.s.name, id.s.len) == 0))
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return svc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate backend identified by ID. Only IDTYPE_NUM is supported.
|
||||
*/
|
||||
static BACKEND *
|
||||
locate_backend (SERVICE *svc, IDENT id)
|
||||
{
|
||||
BACKEND *be = NULL;
|
||||
|
||||
if (id.type == IDTYPE_NUM)
|
||||
{
|
||||
long n = 0;
|
||||
SLIST_FOREACH (be, &svc->backends, next)
|
||||
{
|
||||
if (n == id.n)
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return be;
|
||||
}
|
||||
|
||||
enum object_type
|
||||
{
|
||||
OBJ_LISTENER,
|
||||
@@ -2093,12 +2157,9 @@ typedef int (*OBJHANDLER) (BIO *, OBJECT *, char const *, void *);
|
||||
static int
|
||||
ctl_backend (OBJHANDLER func, void *data, BIO *c, char const *url, SERVICE *svc)
|
||||
{
|
||||
int n;
|
||||
OBJECT obj = { .type = OBJ_BACKEND };
|
||||
|
||||
if ((n = ctl_getnum (&url)) < 0)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
if ((obj.be = get_nth_backend (svc, n)) == NULL)
|
||||
if ((obj.be = locate_backend (svc, ctl_getident (&url))) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
return func (c, &obj, url, data);
|
||||
}
|
||||
@@ -2106,13 +2167,9 @@ ctl_backend (OBJHANDLER func, void *data, BIO *c, char const *url, SERVICE *svc)
|
||||
static int
|
||||
ctl_service (OBJHANDLER func, void *data, BIO *c, char const *url, LISTENER *lstn)
|
||||
{
|
||||
int n;
|
||||
OBJECT obj = { .type = OBJ_SERVICE };
|
||||
|
||||
if ((n = ctl_getnum (&url)) < 0)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
if ((obj.svc = get_nth_service (lstn, n)) == NULL)
|
||||
if ((obj.svc = locate_service (lstn, ctl_getident (&url))) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
if (*url && *url != '?')
|
||||
@@ -2123,7 +2180,6 @@ ctl_service (OBJHANDLER func, void *data, BIO *c, char const *url, LISTENER *lst
|
||||
static int
|
||||
ctl_listener (OBJHANDLER func, void *data, BIO *c, char const *url)
|
||||
{
|
||||
int n;
|
||||
OBJECT obj = { .type = OBJ_LISTENER };
|
||||
size_t len = strcspn (url, "?");
|
||||
|
||||
@@ -2137,14 +2193,8 @@ ctl_listener (OBJHANDLER func, void *data, BIO *c, char const *url)
|
||||
obj.lstn = NULL;
|
||||
url += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((n = ctl_getnum (&url)) < 0)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
if ((obj.lstn = get_nth_listener (n)) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
}
|
||||
else if ((obj.lstn = locate_listener (ctl_getident (&url))) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
if (*url && *url != '?')
|
||||
return ctl_service (func, data, c, url, obj.lstn);
|
||||
|
||||
Reference in New Issue
Block a user