mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
cc05b877a2
first commit acl to github
304 lines
6.1 KiB
C
304 lines
6.1 KiB
C
#include "lib_acl.h"
|
|
#include "lib_protocol.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
typedef struct {
|
|
ACL_VSTREAM *stream;
|
|
int flag;
|
|
#define FLAG_CLOSE 1
|
|
} CONN;
|
|
|
|
static void init(void)
|
|
{
|
|
acl_init();
|
|
}
|
|
|
|
static void end(void)
|
|
{
|
|
acl_end();
|
|
}
|
|
|
|
static void thread_run(void *arg)
|
|
{
|
|
CONN *conn = (CONN*) arg;
|
|
ACL_VSTREAM *client = conn->stream;
|
|
const char *reply_200 = "HTTP/1.1 200 OK\r\n"
|
|
"Server: nginx/0.6.32\r\n"
|
|
"Date: Tue, 29 Dec 2009 02:18:25 GMT\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: 43\r\n"
|
|
"Last-Modified: Mon, 16 Nov 2009 02:18:14 GMT\r\n"
|
|
"Connection: keep-alive\r\n"
|
|
"Accept-Ranges: bytes\r\n\r\n"
|
|
"<html>\n"
|
|
"<body>\n"
|
|
"hello world!\n"
|
|
"</body>\n"
|
|
"</html>\n";
|
|
int ret, keep_alive;
|
|
char buf[4096];
|
|
|
|
while (0) {
|
|
ret = read(ACL_VSTREAM_SOCK(client), buf, sizeof(buf));
|
|
if (ret == ACL_VSTREAM_EOF)
|
|
break;
|
|
ret = acl_vstream_writen(client, reply_200, strlen(reply_200));
|
|
if (ret == ACL_VSTREAM_EOF)
|
|
break;
|
|
}
|
|
|
|
while (0) {
|
|
ret = acl_vstream_read(client, buf, sizeof(buf));
|
|
if (ret == ACL_VSTREAM_EOF)
|
|
break;
|
|
ret = acl_vstream_writen(client, reply_200, strlen(reply_200));
|
|
if (ret == ACL_VSTREAM_EOF)
|
|
break;
|
|
}
|
|
|
|
while (0) {
|
|
/*
|
|
HTTP_REQ *req;
|
|
*/
|
|
HTTP_HDR_REQ *hdr_req = http_hdr_req_new();
|
|
|
|
ret = http_hdr_req_get_sync(hdr_req, client, 300);
|
|
if (ret < 0) {
|
|
http_hdr_req_free(hdr_req);
|
|
break;
|
|
}
|
|
if (http_hdr_req_parse(hdr_req) < 0) {
|
|
http_hdr_req_free(hdr_req);
|
|
printf("parse error\n");
|
|
break;
|
|
}
|
|
|
|
/*
|
|
keep_alive = hdr_req->hdr.keep_alive;
|
|
|
|
if (hdr_req->hdr.content_length > 0) {
|
|
req = http_req_new(hdr_req);
|
|
ret = (int) http_req_body_get_sync(req, client, buf, sizeof(buf));
|
|
if (ret < 0) {
|
|
http_req_free(req);
|
|
break;
|
|
}
|
|
http_req_free(req);
|
|
} else {
|
|
http_hdr_req_free(hdr_req);
|
|
}
|
|
*/
|
|
|
|
http_hdr_req_free(hdr_req);
|
|
ret = acl_vstream_writen(client, reply_200, strlen(reply_200));
|
|
if (ret == ACL_VSTREAM_EOF) {
|
|
break;
|
|
}
|
|
/*
|
|
if (!keep_alive)
|
|
break;
|
|
*/
|
|
}
|
|
|
|
while (1) {
|
|
HTTP_REQ *req;
|
|
HTTP_HDR_REQ *hdr_req = http_hdr_req_new();
|
|
|
|
ret = http_hdr_req_get_sync(hdr_req, client, 0);
|
|
if (ret < 0) {
|
|
http_hdr_req_free(hdr_req);
|
|
break;
|
|
}
|
|
if (http_hdr_req_parse(hdr_req) < 0) {
|
|
http_hdr_req_free(hdr_req);
|
|
printf("parse error\n");
|
|
break;
|
|
}
|
|
|
|
keep_alive = hdr_req->hdr.keep_alive;
|
|
|
|
if (hdr_req->hdr.content_length > 0) {
|
|
req = http_req_new(hdr_req);
|
|
ret = (int) http_req_body_get_sync(req, client, buf, sizeof(buf));
|
|
if (ret < 0) {
|
|
http_req_free(req);
|
|
break;
|
|
}
|
|
http_req_free(req);
|
|
} else {
|
|
http_hdr_req_free(hdr_req);
|
|
}
|
|
|
|
ret = acl_vstream_writen(client, reply_200, strlen(reply_200));
|
|
if (ret == ACL_VSTREAM_EOF) {
|
|
break;
|
|
}
|
|
if (!keep_alive)
|
|
break;
|
|
}
|
|
|
|
acl_vstream_close(client);
|
|
acl_myfree(conn);
|
|
printf("thread(%ld) exit\n", (long) acl_pthread_self());
|
|
}
|
|
|
|
static void *thread_main(void* arg)
|
|
{
|
|
thread_run(arg);
|
|
return (NULL);
|
|
}
|
|
|
|
static void run_server(const char *addr)
|
|
{
|
|
ACL_VSTREAM *sstream = acl_vstream_listen(addr, 128);
|
|
acl_pthread_pool_t *pool;
|
|
CONN *conn;
|
|
acl_pthread_t tid;
|
|
acl_pthread_attr_t attr;
|
|
ACL_VSTREAM *client;
|
|
|
|
if (sstream == NULL) {
|
|
acl_msg_error("listen %s error(%s)", addr, acl_last_serror());
|
|
return;
|
|
}
|
|
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
printf("listening on %s ...\n", addr);
|
|
pool = acl_thread_pool_create(10, 10);
|
|
while (1) {
|
|
acl_mem_slice_delay_destroy();
|
|
if (acl_read_wait(ACL_VSTREAM_SOCK(sstream), 5) == -1)
|
|
continue;
|
|
client = acl_vstream_accept(sstream, NULL, 0);
|
|
if (client == NULL) {
|
|
acl_msg_error("accept error(%s)", acl_last_serror());
|
|
break;
|
|
}
|
|
acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(client));
|
|
conn = acl_mycalloc(1, sizeof(CONN));
|
|
conn->stream = client;
|
|
|
|
if (0)
|
|
thread_run(conn);
|
|
else if (1)
|
|
acl_pthread_create(&tid, &attr, thread_main, conn);
|
|
else
|
|
acl_pthread_pool_add(pool, thread_run, conn);
|
|
}
|
|
|
|
acl_vstream_close(sstream);
|
|
}
|
|
|
|
static void run_client(const char *addr, const char *filename)
|
|
{
|
|
char *request = acl_vstream_loadfile(filename);
|
|
ACL_VSTREAM *client;
|
|
int ret;
|
|
char buf[1024];
|
|
|
|
if (request == NULL) {
|
|
printf("load file(%s) error(%s)\n", filename, acl_last_serror());
|
|
return;
|
|
}
|
|
|
|
client = acl_vstream_connect(addr, ACL_BLOCKING,
|
|
0, 0, 4096);
|
|
if (client == NULL) {
|
|
printf("connect addr(%s) error(%s)\n", addr, acl_last_serror());
|
|
acl_myfree(request);
|
|
return;
|
|
}
|
|
|
|
acl_tcp_set_sndbuf(ACL_VSTREAM_SOCK(client), 10);
|
|
if (acl_vstream_writen(client, request, strlen(request)) == ACL_VSTREAM_EOF) {
|
|
printf("write to addr(%s) error(%s)\n", addr, acl_last_serror());
|
|
acl_vstream_close(client);
|
|
acl_myfree(request);
|
|
return;
|
|
}
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
while (1) {
|
|
ret = acl_vstream_read(client, buf, sizeof(buf) - 1);
|
|
if (ret == ACL_VSTREAM_EOF)
|
|
break;
|
|
buf[ret] = 0;
|
|
usleep(100000);
|
|
printf(">>>%s\n", buf);
|
|
}
|
|
|
|
printf(">>>last data(%s)\n", buf);
|
|
acl_vstream_close(client);
|
|
acl_myfree(request);
|
|
}
|
|
|
|
static void usage(const char *procname)
|
|
{
|
|
printf("usage: %s -h [help] -s listen_addr[IP:PORT] -c request_hdr\n", procname);
|
|
}
|
|
|
|
static void *thread_test(void *arg acl_unused)
|
|
{
|
|
char *p = acl_mymalloc(1000);
|
|
acl_myfree(p);
|
|
printf("call slice destroy\n");
|
|
acl_mem_slice_destroy();
|
|
return (NULL);
|
|
}
|
|
|
|
static void test(void)
|
|
{
|
|
acl_pthread_t tid;
|
|
acl_pthread_attr_t attr;
|
|
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
acl_pthread_create(&tid, &attr, thread_test, 0);
|
|
while (1) {
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char addr[256] = "0.0.0.0:80", filename[256];
|
|
int ch, client_mode = 0;
|
|
|
|
#if 1
|
|
acl_mem_slice_init(8, 10240, 100000, ACL_SLICE_FLAG_GC2 | ACL_SLICE_FLAG_RTGC_OFF | ACL_SLICE_FLAG_LP64_ALIGN);
|
|
http_hdr_cache(100);
|
|
#endif
|
|
|
|
while ((ch = getopt(argc, argv, "hs:c:")) > 0) {
|
|
switch (ch) {
|
|
case 'h':
|
|
usage(argv[0]);
|
|
exit (0);
|
|
case 's':
|
|
ACL_SAFE_STRNCPY(addr, optarg, sizeof(addr));
|
|
break;
|
|
case 'c':
|
|
client_mode = 1;
|
|
ACL_SAFE_STRNCPY(filename, optarg, sizeof(filename));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (0)
|
|
test();
|
|
|
|
init();
|
|
if (client_mode)
|
|
run_client(addr, filename);
|
|
else
|
|
run_server(addr);
|
|
end();
|
|
return (0);
|
|
}
|