mirror of
https://github.com/transmission/transmission
synced 2024-12-24 08:43:27 +00:00
(shttpd) remove the cgi source files that we don't use
This commit is contained in:
parent
be78f38309
commit
f8efe41e44
2 changed files with 0 additions and 349 deletions
227
third-party/shttpd/cgi.c
vendored
227
third-party/shttpd/cgi.c
vendored
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* Sergey Lyubka wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#if !defined(NO_CGI)
|
||||
struct env_block {
|
||||
char buf[ENV_MAX]; /* Environment buffer */
|
||||
int len; /* Space taken */
|
||||
char *vars[CGI_ENV_VARS]; /* Point into the buffer */
|
||||
int nvars; /* Number of variables */
|
||||
};
|
||||
|
||||
static void
|
||||
addenv(struct env_block *block, const char *fmt, ...)
|
||||
{
|
||||
int n, space;
|
||||
va_list ap;
|
||||
|
||||
space = sizeof(block->buf) - block->len - 2;
|
||||
assert(space >= 0);
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(block->buf + block->len, space, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n > 0 && n < space && block->nvars < CGI_ENV_VARS - 2) {
|
||||
block->vars[block->nvars++] = block->buf + block->len;
|
||||
block->len += n + 1; /* Include \0 terminator */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_http_headers_to_env(struct env_block *b, const char *s, int len)
|
||||
{
|
||||
const char *p, *v, *e = s + len;
|
||||
int space, n, i, ch;
|
||||
|
||||
/* Loop through all headers in the request */
|
||||
while (s < e) {
|
||||
|
||||
/* Find where this header ends. Remember where value starts */
|
||||
for (p = s, v = NULL; p < e && *p != '\n'; p++)
|
||||
if (v == NULL && *p == ':')
|
||||
v = p;
|
||||
|
||||
/* 2 null terminators and "HTTP_" */
|
||||
space = (sizeof(b->buf) - b->len) - (2 + 5);
|
||||
assert(space >= 0);
|
||||
|
||||
/* Copy header if enough space in the environment block */
|
||||
if (v > s && p > v + 2 && space > p - s) {
|
||||
|
||||
/* Store var */
|
||||
if (b->nvars < (int) NELEMS(b->vars) - 1)
|
||||
b->vars[b->nvars++] = b->buf + b->len;
|
||||
|
||||
(void) memcpy(b->buf + b->len, "HTTP_", 5);
|
||||
b->len += 5;
|
||||
|
||||
/* Copy header name. Substitute '-' to '_' */
|
||||
n = v - s;
|
||||
for (i = 0; i < n; i++) {
|
||||
ch = s[i] == '-' ? '_' : s[i];
|
||||
b->buf[b->len++] = toupper(ch);
|
||||
}
|
||||
|
||||
b->buf[b->len++] = '=';
|
||||
|
||||
/* Copy header value */
|
||||
v += 2;
|
||||
n = p[-1] == '\r' ? (p - v) - 1 : p - v;
|
||||
for (i = 0; i < n; i++)
|
||||
b->buf[b->len++] = v[i];
|
||||
|
||||
/* Null-terminate */
|
||||
b->buf[b->len++] = '\0';
|
||||
}
|
||||
|
||||
s = p + 1; /* Shift to the next header */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_environment(const struct conn *c, const char *prog,
|
||||
struct env_block *blk)
|
||||
{
|
||||
const struct headers *h = &c->ch;
|
||||
const char *s, *fname, *root = c->ctx->options[OPT_ROOT];
|
||||
size_t len;
|
||||
|
||||
blk->len = blk->nvars = 0;
|
||||
|
||||
/* SCRIPT_FILENAME */
|
||||
fname = prog;
|
||||
if ((s = strrchr(prog, '/')))
|
||||
fname = s + 1;
|
||||
|
||||
/* Prepare the environment block */
|
||||
addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
|
||||
addenv(blk, "%s", "SERVER_PROTOCOL=HTTP/1.1");
|
||||
addenv(blk, "%s", "REDIRECT_STATUS=200"); /* PHP */
|
||||
addenv(blk, "SERVER_PORT=%d", c->loc_port);
|
||||
addenv(blk, "SERVER_NAME=%s", c->ctx->options[OPT_AUTH_REALM]);
|
||||
addenv(blk, "SERVER_ROOT=%s", root);
|
||||
addenv(blk, "DOCUMENT_ROOT=%s", root);
|
||||
addenv(blk, "REQUEST_METHOD=%s", known_http_methods[c->method].ptr);
|
||||
addenv(blk, "REMOTE_ADDR=%s", inet_ntoa(c->sa.u.sin.sin_addr));
|
||||
addenv(blk, "REMOTE_PORT=%hu", ntohs(c->sa.u.sin.sin_port));
|
||||
addenv(blk, "REQUEST_URI=%s", c->uri);
|
||||
addenv(blk, "SCRIPT_NAME=%s", prog + strlen(root));
|
||||
addenv(blk, "SCRIPT_FILENAME=%s", fname); /* PHP */
|
||||
addenv(blk, "PATH_TRANSLATED=%s", prog);
|
||||
|
||||
if (h->ct.v_vec.len > 0)
|
||||
addenv(blk, "CONTENT_TYPE=%.*s",
|
||||
h->ct.v_vec.len, h->ct.v_vec.ptr);
|
||||
|
||||
if (c->query != NULL)
|
||||
addenv(blk, "QUERY_STRING=%s", c->query);
|
||||
|
||||
if (c->path_info != NULL)
|
||||
addenv(blk, "PATH_INFO=/%s", c->path_info);
|
||||
|
||||
if (h->cl.v_big_int > 0)
|
||||
addenv(blk, "CONTENT_LENGTH=%lu", h->cl.v_big_int);
|
||||
|
||||
if ((s = getenv("PATH")) != NULL)
|
||||
addenv(blk, "PATH=%s", s);
|
||||
|
||||
#ifdef _WIN32
|
||||
if ((s = getenv("COMSPEC")) != NULL)
|
||||
addenv(blk, "COMSPEC=%s", s);
|
||||
if ((s = getenv("SYSTEMROOT")) != NULL)
|
||||
addenv(blk, "SYSTEMROOT=%s", s);
|
||||
#else
|
||||
if ((s = getenv("LD_LIBRARY_PATH")) != NULL)
|
||||
addenv(blk, "LD_LIBRARY_PATH=%s", s);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if ((s = getenv("PERLLIB")) != NULL)
|
||||
addenv(blk, "PERLLIB=%s", s);
|
||||
|
||||
if (h->user.v_vec.len > 0) {
|
||||
addenv(blk, "REMOTE_USER=%.*s",
|
||||
h->user.v_vec.len, h->user.v_vec.ptr);
|
||||
addenv(blk, "%s", "AUTH_TYPE=Digest");
|
||||
}
|
||||
|
||||
/* Add user-specified variables */
|
||||
s = c->ctx->options[OPT_CGI_ENVIRONMENT];
|
||||
FOR_EACH_WORD_IN_LIST(s, len)
|
||||
addenv(blk, "%.*s", len, s);
|
||||
|
||||
/* Add all headers as HTTP_* variables */
|
||||
add_http_headers_to_env(blk, c->headers,
|
||||
c->rem.headers_len - (c->headers - c->request));
|
||||
|
||||
blk->vars[blk->nvars++] = NULL;
|
||||
blk->buf[blk->len++] = '\0';
|
||||
|
||||
assert(blk->nvars < CGI_ENV_VARS);
|
||||
assert(blk->len > 0);
|
||||
assert(blk->len < (int) sizeof(blk->buf));
|
||||
|
||||
/* Debug stuff to view passed environment */
|
||||
DBG(("%s: %d vars, %d env size", prog, blk->nvars, blk->len));
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < blk->nvars; i++)
|
||||
DBG(("[%s]", blk->vars[i] ? blk->vars[i] : "null"));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
run_cgi(struct conn *c, const char *prog)
|
||||
{
|
||||
struct env_block blk;
|
||||
char dir[FILENAME_MAX], *p;
|
||||
int ret, pair[2];
|
||||
|
||||
prepare_environment(c, prog, &blk);
|
||||
pair[0] = pair[1] = -1;
|
||||
|
||||
/* CGI must be executed in its own directory */
|
||||
(void) my_snprintf(dir, sizeof(dir), "%s", prog);
|
||||
for (p = dir + strlen(dir) - 1; p > dir; p--)
|
||||
if (*p == '/') {
|
||||
*p++ = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (shttpd_socketpair(pair) != 0) {
|
||||
ret = -1;
|
||||
} else if (spawn_process(c, prog, blk.buf, blk.vars, pair[1], dir)) {
|
||||
ret = -1;
|
||||
(void) closesocket(pair[0]);
|
||||
(void) closesocket(pair[1]);
|
||||
} else {
|
||||
ret = 0;
|
||||
c->loc.chan.sock = pair[0];
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
do_cgi(struct conn *c)
|
||||
{
|
||||
DBG(("running CGI: [%s]", c->uri));
|
||||
assert(c->loc.io.size > CGI_REPLY_LEN);
|
||||
memcpy(c->loc.io.buf, CGI_REPLY, CGI_REPLY_LEN);
|
||||
c->loc.io.head = c->loc.io.tail = c->loc.io.total = CGI_REPLY_LEN;
|
||||
c->loc.io_class = &io_cgi;
|
||||
c->loc.flags = FLAG_R;
|
||||
if (c->method == METHOD_POST)
|
||||
c->loc.flags |= FLAG_W;
|
||||
}
|
||||
|
||||
#endif /* !NO_CGI */
|
122
third-party/shttpd/io_cgi.c
vendored
122
third-party/shttpd/io_cgi.c
vendored
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* Sergey Lyubka wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
static int
|
||||
write_cgi(struct stream *stream, const void *buf, size_t len)
|
||||
{
|
||||
assert(stream->chan.sock != -1);
|
||||
assert(stream->flags & FLAG_W);
|
||||
|
||||
return (send(stream->chan.sock, buf, len, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
read_cgi(struct stream *stream, void *buf, size_t len)
|
||||
{
|
||||
struct headers parsed;
|
||||
char status[4];
|
||||
int n;
|
||||
|
||||
assert(stream->chan.sock != -1);
|
||||
assert(stream->flags & FLAG_R);
|
||||
|
||||
stream->flags &= ~FLAG_DONT_CLOSE;
|
||||
|
||||
n = recv(stream->chan.sock, buf, len, 0);
|
||||
|
||||
if (stream->flags & FLAG_HEADERS_PARSED)
|
||||
return (n);
|
||||
|
||||
if (n <= 0 && ERRNO != EWOULDBLOCK) {
|
||||
send_server_error(stream->conn, 500, "Error running CGI");
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* CGI script may output Status: and Location: headers, which
|
||||
* may alter the status code. Buffer in headers, parse
|
||||
* them, send correct status code and then forward all data
|
||||
* from CGI script back to the remote end.
|
||||
* Reply line was alredy appended to the IO buffer in
|
||||
* decide_what_to_do(), with blank status code.
|
||||
*/
|
||||
|
||||
stream->flags |= FLAG_DONT_CLOSE;
|
||||
io_inc_head(&stream->io, n);
|
||||
|
||||
stream->headers_len = get_headers_len(stream->io.buf, stream->io.head);
|
||||
if (stream->headers_len < 0) {
|
||||
stream->flags &= ~FLAG_DONT_CLOSE;
|
||||
send_server_error(stream->conn, 500, "Bad headers sent");
|
||||
elog(E_LOG, stream->conn, "CGI script sent invalid headers: "
|
||||
"[%.*s]", stream->io.head - CGI_REPLY_LEN,
|
||||
stream->io.buf + CGI_REPLY_LEN);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we did not received full headers yet, we must not send any
|
||||
* data read from the CGI back to the client. Suspend sending by
|
||||
* setting tail = head, which tells that there is no data in IO buffer
|
||||
*/
|
||||
|
||||
if (stream->headers_len == 0) {
|
||||
stream->io.tail = stream->io.head;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Received all headers. Set status code for the connection. */
|
||||
(void) memset(&parsed, 0, sizeof(parsed));
|
||||
parse_headers(stream->io.buf, stream->headers_len, &parsed);
|
||||
stream->content_len = parsed.cl.v_big_int;
|
||||
stream->conn->status = (int) parsed.status.v_big_int;
|
||||
|
||||
/* If script outputs 'Location:' header, set status code to 302 */
|
||||
if (parsed.location.v_vec.len > 0)
|
||||
stream->conn->status = 302;
|
||||
|
||||
/*
|
||||
* If script did not output neither 'Location:' nor 'Status' headers,
|
||||
* set the default status code 200, which means 'success'.
|
||||
*/
|
||||
if (stream->conn->status == 0)
|
||||
stream->conn->status = 200;
|
||||
|
||||
/* Append the status line to the beginning of the output */
|
||||
(void) my_snprintf(status, sizeof(status), "%3d", stream->conn->status);
|
||||
(void) memcpy(stream->io.buf + 9, status, 3);
|
||||
DBG(("read_cgi: content len %lu status %s",
|
||||
stream->content_len, status));
|
||||
|
||||
/* Next time, pass output directly back to the client */
|
||||
assert((big_int_t) stream->headers_len <= stream->io.total);
|
||||
stream->io.total -= stream->headers_len;
|
||||
stream->io.tail = 0;
|
||||
stream->flags |= FLAG_HEADERS_PARSED;
|
||||
|
||||
/* Return 0 because we've already shifted the head */
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
close_cgi(struct stream *stream)
|
||||
{
|
||||
assert(stream->chan.sock != -1);
|
||||
(void) closesocket(stream->chan.sock);
|
||||
}
|
||||
|
||||
const struct io_class io_cgi = {
|
||||
"cgi",
|
||||
read_cgi,
|
||||
write_cgi,
|
||||
close_cgi
|
||||
};
|
Loading…
Reference in a new issue