Download raw body.
slowcgi: preserve PARAMS order in the CGI environment
I fixed the order in httpd ("tail insert during read from conf"
followed by "tail insert" during copying) but still had an incorrect
order because of slowcgi.
env vars were stored on an SLIST via SLIST_INSERT_HEAD and later walked
with SLIST_FOREACH when populating envp[]. Prepending on insert and
iterating head-to-tail reverses the list, so FastCGI PARAMS delivered as
curl -s http://127.0.0.1:8089/env.cgi
FCGI_TEST_BB=BB
FCGI_TEST_E=E
FCGI_TEST_D=D
FCGI_TEST_C=C
FCGI_TEST_B=B
FCGI_TEST_A=A
even httpd provided them in the correct order:
...
fcgi_add_param: HTTP_HOST[9] => 127.0.0.1:8089[14], total_len: 164
fcgi_add_param: HTTP_USER_AGENT[15] => curl/8.21.0[11], total_len: 189
fcgi_add_param: FCGI_TEST_A[11] => A[1], total_len: 217
fcgi_add_param: FCGI_TEST_B[11] => B[1], total_len: 231
fcgi_add_param: FCGI_TEST_C[11] => C[1], total_len: 245
fcgi_add_param: FCGI_TEST_D[11] => D[1], total_len: 259
fcgi_add_param: FCGI_TEST_E[11] => E[1], total_len: 273
fcgi_add_param: FCGI_TEST_BB[12] => BB[2], total_len: 287
fcgi_add_param: REMOTE_ADDR[11] => 127.0.0.1[9], total_len: 303
fcgi_add_param: REMOTE_PORT[11] => 24112[5], total_len: 325
...
Switch the list to STAILQ and insert at the tail so envp[] follows
the order in which parameters arrived.
OK?
diff --git a/usr.sbin/slowcgi/slowcgi.c b/usr.sbin/slowcgi/slowcgi.c
index 1663118ee22..b0e511e095a 100644
--- a/usr.sbin/slowcgi/slowcgi.c
+++ b/usr.sbin/slowcgi/slowcgi.c
@@ -83,10 +83,10 @@ struct listener {
};
struct env_val {
- SLIST_ENTRY(env_val) entry;
+ STAILQ_ENTRY(env_val) entry;
char *val;
};
-SLIST_HEAD(env_head, env_val);
+STAILQ_HEAD(env_head, env_val);
struct fcgi_record_header {
uint8_t version;
@@ -693,7 +693,7 @@ parse_begin_request(uint8_t *buf, uint16_t n, struct request *c, uint16_t id)
c->request_started = 1;
c->id = id;
- SLIST_INIT(&c->env);
+ STAILQ_INIT(&c->env);
c->env_count = 0;
}
@@ -794,7 +794,7 @@ parse_params(uint8_t *buf, uint16_t n, struct request *c, uint16_t id)
buf += val_len;
n -= val_len;
- SLIST_INSERT_HEAD(&c->env, env_entry, entry);
+ STAILQ_INSERT_TAIL(&c->env, env_entry, entry);
ldebug("env[%d], %s", c->env_count, env_entry->val);
c->env_count++;
}
@@ -955,7 +955,7 @@ exec_cgi(struct request *c)
argv[1] = NULL;
if ((env = calloc(c->env_count + 1, sizeof(char*))) == NULL)
_exit(1);
- SLIST_FOREACH(env_entry, &c->env, entry)
+ STAILQ_FOREACH(env_entry, &c->env, entry)
env[i++] = env_entry->val;
env[i++] = NULL;
execve(c->script_name, argv, env);
@@ -1153,9 +1153,9 @@ cleanup_request(struct request *c)
event_del(&c->script_stdin_ev);
}
close(c->fd);
- while (!SLIST_EMPTY(&c->env)) {
- env_entry = SLIST_FIRST(&c->env);
- SLIST_REMOVE_HEAD(&c->env, entry);
+ while (!STAILQ_EMPTY(&c->env)) {
+ env_entry = STAILQ_FIRST(&c->env);
+ STAILQ_REMOVE_HEAD(&c->env, entry);
free(env_entry->val);
free(env_entry);
}
slowcgi: preserve PARAMS order in the CGI environment