mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 01:10:52 +08:00
9697f95b8f
This reverts commit 15d999759e
.
221 lines
4.9 KiB
C
221 lines
4.9 KiB
C
#include "lib_acl.h"
|
||
#include "http_plugin.h"
|
||
|
||
typedef struct {
|
||
ACL_VSTRING *alias;
|
||
ACL_VSTRING *cgi;
|
||
} CGI_MAP;
|
||
|
||
static ACL_HTABLE *__table = NULL;
|
||
|
||
static CGI_MAP *cgi_map_new(const char *alias, const char *cgi)
|
||
{
|
||
CGI_MAP *map = (CGI_MAP*) acl_mycalloc(1, sizeof(CGI_MAP));
|
||
|
||
map->alias = acl_vstring_alloc(256);
|
||
map->cgi = acl_vstring_alloc(256);
|
||
acl_vstring_strcpy(map->alias, alias);
|
||
acl_vstring_strcpy(map->cgi, var_cfg_cgi_bin);
|
||
acl_vstring_strcpy(map->cgi, cgi);
|
||
return (map);
|
||
}
|
||
|
||
static void cgi_map_free(CGI_MAP *map)
|
||
{
|
||
acl_vstring_free(map->alias);
|
||
acl_vstring_free(map->cgi);
|
||
acl_myfree(map);
|
||
}
|
||
|
||
void http_cgi_init()
|
||
{
|
||
__table = acl_htable_create(10, 0);
|
||
}
|
||
|
||
void http_cgi_end()
|
||
{
|
||
acl_htable_free(__table, (void (*)(void*)) cgi_map_free);
|
||
}
|
||
|
||
void http_cgi_add2(const char *alias, const char *cgi)
|
||
{
|
||
CGI_MAP *map;
|
||
|
||
map = (CGI_MAP*) acl_htable_find(__table, alias);
|
||
if (map != NULL) {
|
||
acl_msg_warn("%s(%d): alias(%s) already exist",
|
||
__FUNCTION__, __LINE__, alias);
|
||
return;
|
||
}
|
||
map = cgi_map_new(alias, cgi);
|
||
acl_htable_enter(__table, alias, map);
|
||
}
|
||
|
||
void http_cgi_add1(const ACL_ARGV *args)
|
||
{
|
||
if (args->argc < 2) {
|
||
acl_msg_error("%s(%d): argc(%d) < 2",
|
||
__FUNCTION__, __LINE__, args->argc);
|
||
return;
|
||
}
|
||
|
||
http_cgi_add2(args->argv[0], args->argv[1]);
|
||
}
|
||
|
||
CGI *http_cgi_path(const char *alias)
|
||
{
|
||
CGI *cgi;
|
||
CGI_MAP *map = (CGI_MAP*) acl_htable_find(__table, alias);
|
||
|
||
if (map == NULL)
|
||
return (NULL);
|
||
|
||
cgi = (CGI*) acl_mycalloc(1, sizeof(CGI));
|
||
cgi->alias = acl_mystrdup(alias);
|
||
cgi->cgi = acl_mystrdup(STR(map->cgi));
|
||
return (cgi);
|
||
}
|
||
|
||
static void cgi_free(CGI *cgi)
|
||
{
|
||
if (cgi == NULL)
|
||
return;
|
||
if (cgi->client)
|
||
acl_vstream_close(cgi->client);
|
||
if (cgi->hdr_req)
|
||
http_hdr_req_free(cgi->hdr_req);
|
||
if (cgi->req) {
|
||
cgi->req->hdr_req = NULL;
|
||
http_req_free(cgi->req);
|
||
}
|
||
if (cgi->hdr_res)
|
||
http_hdr_res_free(cgi->hdr_res);
|
||
if (cgi->cgi)
|
||
acl_myfree(cgi->cgi);
|
||
if (cgi->alias)
|
||
acl_myfree(cgi->alias);
|
||
acl_myfree(cgi);
|
||
}
|
||
|
||
static void run_cgi(CGI *cgi, ACL_ARGV *env)
|
||
{
|
||
char *command = cgi->cgi;
|
||
ACL_VSTREAM *stream;
|
||
ACL_VSTRING *vbuf;
|
||
ACL_ARGV *cgi_hdrs;
|
||
char buf[4096];
|
||
int ret, errnum = 200;
|
||
char **cpp;
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CGI<47><49><EFBFBD><EFBFBD><EFBFBD>Ĺܵ<C4B9><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
stream = acl_vstream_popen(O_RDWR,
|
||
ACL_VSTREAM_POPEN_COMMAND, command,
|
||
ACL_VSTREAM_POPEN_ENV, env->argv,
|
||
ACL_VSTREAM_POPEN_END);
|
||
|
||
if (stream == NULL) {
|
||
acl_msg_error("%s(%d): open command(%s) error(%s)",
|
||
__FUNCTION__, __LINE__, command, acl_last_serror());
|
||
return;
|
||
}
|
||
|
||
cgi->req = http_req_new(cgi->hdr_req);
|
||
if (cgi->hdr_req->hdr.content_length > 0) {
|
||
while (1) {
|
||
ret = (int) http_req_body_get_sync(cgi->req, cgi->client,
|
||
buf, sizeof(buf) - 1);
|
||
if (ret <= 0)
|
||
break;
|
||
if (acl_vstream_writen(stream, buf, ret) == ACL_VSTREAM_EOF) {
|
||
acl_vstream_close(stream);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* http_hdr_set_keepalive(cgi->hdr_req, cgi->hdr_res);
|
||
*/
|
||
|
||
cgi_hdrs = acl_argv_alloc(10);
|
||
|
||
/* <20><>CGI<47><49><EFBFBD>͵<EFBFBD><CDB5><EFBFBD>Ӧͷ */
|
||
while (1) {
|
||
char *pname, *ptr;
|
||
|
||
ret = acl_vstream_gets_nonl(stream, buf, sizeof(buf));
|
||
if (ret == ACL_VSTREAM_EOF) {
|
||
acl_msg_error("%s(%d): cgi exit exception",
|
||
__FUNCTION__, __LINE__);
|
||
errnum = 500;
|
||
break;
|
||
}
|
||
if (ret == 0) {
|
||
break;
|
||
}
|
||
ptr = buf;
|
||
pname = acl_mystrtok(&ptr, ":\t ");
|
||
if (ptr == NULL) {
|
||
acl_msg_warn("%s(%d): cgi reply hdr(%s) invalid",
|
||
__FUNCTION__, __LINE__, buf);
|
||
continue;
|
||
}
|
||
acl_argv_add(cgi_hdrs, pname, ptr, NULL);
|
||
}
|
||
|
||
vbuf = acl_vstring_alloc(256);
|
||
|
||
cgi->hdr_res = http_hdr_res_static(errnum);
|
||
|
||
for (cpp = cgi_hdrs->argv; *cpp; cpp += 2) {
|
||
http_hdr_put_str(&cgi->hdr_res->hdr, cpp[0], cpp[1]);
|
||
}
|
||
|
||
http_hdr_entry_replace(&cgi->hdr_res->hdr, "Connection", "close", 1);
|
||
http_hdr_build(&cgi->hdr_res->hdr, vbuf);
|
||
|
||
ret = acl_vstream_writen(cgi->client, STR(vbuf), LEN(vbuf));
|
||
if (ret > 0) {
|
||
/* <20><>CGI<47><49><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>岢<EFBFBD><E5B2A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
while (1) {
|
||
ret = acl_vstream_read(stream, buf, sizeof(buf));
|
||
if (ret == ACL_VSTREAM_EOF)
|
||
break;
|
||
if (acl_vstream_writen(cgi->client, buf, ret) == ACL_VSTREAM_EOF)
|
||
break;
|
||
}
|
||
}
|
||
|
||
acl_vstring_free(vbuf);
|
||
acl_vstream_pclose(stream);
|
||
}
|
||
|
||
void http_cgi_thread(void *ctx)
|
||
{
|
||
CGI *cgi = (CGI*) ctx;
|
||
HTTP_HDR_REQ *hdr_req = cgi->hdr_req;
|
||
ACL_ARGV *env = acl_argv_alloc(10);
|
||
ACL_ITER iter;
|
||
|
||
const char *reply = "HTTP/1.1 200 OK\r\n"
|
||
"Date: Sun, 15 Nov 2009 07:06:22 GMT\r\n"
|
||
"Server: Apache/2.2.9 (Unix)\r\n"
|
||
"Connection: close\r\n"
|
||
"Content-Type: text/html\r\n\r\n";
|
||
acl_foreach(iter, hdr_req->hdr.entry_lnk) {
|
||
HTTP_HDR_ENTRY *entry = (HTTP_HDR_ENTRY*) iter.data;
|
||
|
||
if (entry->off)
|
||
continue;
|
||
acl_argv_add(env, entry->name, entry->value, NULL);
|
||
}
|
||
|
||
if (1)
|
||
run_cgi(cgi, env);
|
||
else {
|
||
acl_vstream_writen(cgi->client, reply, sizeof(reply));
|
||
}
|
||
acl_argv_free(env);
|
||
cgi_free(cgi);
|
||
}
|