initial commit
This commit is contained in:
118
third_party/libhv/unittest/CMakeLists.txt
vendored
Executable file
118
third_party/libhv/unittest/CMakeLists.txt
vendored
Executable file
@@ -0,0 +1,118 @@
|
||||
add_definitions(-DHV_SOURCE=1)
|
||||
|
||||
# ------base------
|
||||
add_executable(hbase_test hbase_test.c ../base/hbase.c)
|
||||
target_include_directories(hbase_test PRIVATE .. ../base)
|
||||
|
||||
add_executable(mkdir_p mkdir_test.c ../base/hbase.c)
|
||||
target_include_directories(mkdir_p PRIVATE .. ../base)
|
||||
|
||||
add_executable(rmdir_p rmdir_test.c ../base/hbase.c)
|
||||
target_include_directories(rmdir_p PRIVATE .. ../base)
|
||||
|
||||
add_executable(date date_test.c ../base/htime.c)
|
||||
target_include_directories(date PRIVATE .. ../base)
|
||||
|
||||
add_executable(hatomic_test hatomic_test.c)
|
||||
target_include_directories(hatomic_test PRIVATE .. ../base)
|
||||
target_link_libraries(hatomic_test -lpthread)
|
||||
|
||||
add_executable(hthread_test hthread_test.cpp)
|
||||
target_include_directories(hthread_test PRIVATE .. ../base)
|
||||
target_link_libraries(hthread_test -lpthread)
|
||||
|
||||
add_executable(hmutex_test hmutex_test.c ../base/htime.c)
|
||||
target_include_directories(hmutex_test PRIVATE .. ../base)
|
||||
target_link_libraries(hmutex_test -lpthread)
|
||||
|
||||
add_executable(connect_test connect_test.c ../base/hsocket.c ../base/htime.c)
|
||||
target_include_directories(connect_test PRIVATE .. ../base)
|
||||
|
||||
add_executable(socketpair_test socketpair_test.c ../base/hsocket.c)
|
||||
target_include_directories(socketpair_test PRIVATE .. ../base)
|
||||
|
||||
# ------util------
|
||||
add_executable(base64 base64_test.c ../util/base64.c)
|
||||
target_include_directories(base64 PRIVATE .. ../util)
|
||||
|
||||
add_executable(md5 md5_test.c ../util/md5.c)
|
||||
target_include_directories(md5 PRIVATE .. ../util)
|
||||
|
||||
add_executable(sha1 sha1_test.c ../util/sha1.c)
|
||||
target_include_directories(sha1 PRIVATE .. ../util)
|
||||
|
||||
# ------cpputil------
|
||||
add_executable(hstring_test hstring_test.cpp ../cpputil/hstring.cpp)
|
||||
target_include_directories(hstring_test PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(hpath_test hpath_test.cpp ../cpputil/hpath.cpp)
|
||||
target_include_directories(hpath_test PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(hurl_test hurl_test.cpp ../cpputil/hurl.cpp ../base/hbase.c)
|
||||
target_include_directories(hurl_test PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(ls listdir_test.cpp ../cpputil/hdir.cpp)
|
||||
target_include_directories(ls PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(ifconfig ifconfig_test.cpp ../cpputil/ifconfig.cpp)
|
||||
target_include_directories(ifconfig PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(defer_test defer_test.cpp)
|
||||
target_include_directories(defer_test PRIVATE .. ../base ../cpputil)
|
||||
|
||||
add_executable(synchronized_test synchronized_test.cpp)
|
||||
target_include_directories(synchronized_test PRIVATE .. ../base ../cpputil)
|
||||
target_link_libraries(synchronized_test -lpthread)
|
||||
|
||||
add_executable(threadpool_test threadpool_test.cpp)
|
||||
target_include_directories(threadpool_test PRIVATE .. ../base ../cpputil)
|
||||
target_link_libraries(threadpool_test -lpthread)
|
||||
|
||||
add_executable(objectpool_test objectpool_test.cpp)
|
||||
target_include_directories(objectpool_test PRIVATE .. ../base ../cpputil)
|
||||
target_link_libraries(objectpool_test -lpthread)
|
||||
|
||||
# ------protocol------
|
||||
add_executable(nslookup nslookup_test.c ../protocol/dns.c)
|
||||
target_include_directories(nslookup PRIVATE .. ../base ../protocol)
|
||||
|
||||
add_executable(ping ping_test.c ../protocol/icmp.c ../base/hsocket.c ../base/htime.c)
|
||||
target_compile_definitions(ping PRIVATE -DPRINT_DEBUG)
|
||||
target_include_directories(ping PRIVATE .. ../base ../protocol)
|
||||
|
||||
add_executable(ftp ftp_test.c ../protocol/ftp.c ../base/hsocket.c)
|
||||
target_include_directories(ftp PRIVATE .. ../base ../protocol)
|
||||
|
||||
add_executable(sendmail sendmail_test.c ../protocol/smtp.c ../base/hsocket.c ../util/base64.c)
|
||||
target_include_directories(sendmail PRIVATE .. ../base ../protocol ../util)
|
||||
|
||||
if(UNIX)
|
||||
add_executable(webbench webbench.c)
|
||||
endif()
|
||||
|
||||
add_custom_target(unittest DEPENDS
|
||||
mkdir_p
|
||||
rmdir_p
|
||||
date
|
||||
hatomic_test
|
||||
hthread_test
|
||||
hmutex_test
|
||||
connect_test
|
||||
socketpair_test
|
||||
base64
|
||||
md5
|
||||
sha1
|
||||
hstring_test
|
||||
hpath_test
|
||||
hurl_test
|
||||
ls
|
||||
ifconfig
|
||||
defer_test
|
||||
synchronized_test
|
||||
threadpool_test
|
||||
objectpool_test
|
||||
nslookup
|
||||
ping
|
||||
ftp
|
||||
sendmail
|
||||
)
|
||||
118
third_party/libhv/unittest/base64_test.c
vendored
Executable file
118
third_party/libhv/unittest/base64_test.c
vendored
Executable file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* @build: gcc -o bin/base64 unittest/base64_test.c util/base64.c -I. -Iutil
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
static void test() {
|
||||
unsigned char in[] = "0123456789";
|
||||
// test encode
|
||||
int encoded_size = BASE64_ENCODE_OUT_SIZE(10);
|
||||
char* encoded = (char*)malloc(encoded_size + 1);
|
||||
encoded_size = hv_base64_encode(in, 10, encoded);
|
||||
encoded[encoded_size] = '\0';
|
||||
assert(strcmp(encoded, "MDEyMzQ1Njc4OQ==") == 0);
|
||||
// test decode
|
||||
int decoded_size = BASE64_DECODE_OUT_SIZE(encoded_size);
|
||||
unsigned char* decoded = (unsigned char*)malloc(decoded_size);
|
||||
decoded_size = hv_base64_decode(encoded, encoded_size, decoded);
|
||||
assert(decoded_size == 10 && memcmp(in, decoded, decoded_size) == 0);
|
||||
|
||||
free(encoded);
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
test();
|
||||
|
||||
if (argc < 3) {
|
||||
printf("Usage: base64 infile outfile\n");
|
||||
printf(" base64 -d infile outfile\n");
|
||||
return -10;
|
||||
}
|
||||
else if (argc == 3) {
|
||||
// encode file
|
||||
const char* infile = argv[1];
|
||||
const char* outfile = argv[2];
|
||||
|
||||
FILE* infp = fopen(infile, "rb");
|
||||
if (infp == NULL) {
|
||||
printf("Open file '%s' failed!\n", infile);
|
||||
return -20;
|
||||
}
|
||||
fseek(infp, 0, SEEK_END);
|
||||
long filesize = ftell(infp);
|
||||
// printf("filesize=%ld\n", filesize);
|
||||
fseek(infp, 0, SEEK_SET);
|
||||
unsigned char* filebuf = (unsigned char*)malloc(filesize);
|
||||
size_t nread = fread(filebuf, 1, filesize, infp);
|
||||
assert(nread == filesize);
|
||||
|
||||
int encoded_size = BASE64_ENCODE_OUT_SIZE(filesize);
|
||||
char* encoded = (char*)malloc(encoded_size + 1);
|
||||
encoded_size = hv_base64_encode(filebuf, filesize, encoded);
|
||||
encoded[encoded_size] = '\0';
|
||||
|
||||
FILE* outfp = fopen(outfile, "w");
|
||||
if (outfp == NULL) {
|
||||
printf("Save file '%s' failed!\n", infile);
|
||||
return -20;
|
||||
}
|
||||
size_t nwrite = fwrite(encoded, 1, encoded_size, outfp);
|
||||
assert(nwrite == encoded_size);
|
||||
|
||||
free(filebuf);
|
||||
free(encoded);
|
||||
fclose(infp);
|
||||
fclose(outfp);
|
||||
}
|
||||
else if (argc == 4) {
|
||||
const char* flags = argv[1];
|
||||
if (flags[0] == '-' && flags[1] == 'd') {
|
||||
// decode file
|
||||
const char* infile = argv[2];
|
||||
const char* outfile = argv[3];
|
||||
FILE* infp = fopen(infile, "r");
|
||||
if (infp == NULL) {
|
||||
printf("Open file '%s' failed!\n", infile);
|
||||
return -20;
|
||||
}
|
||||
fseek(infp, 0, SEEK_END);
|
||||
long filesize = ftell(infp);
|
||||
// printf("filesize=%ld\n", filesize);
|
||||
fseek(infp, 0, SEEK_SET);
|
||||
char* filebuf = (char*)malloc(filesize);
|
||||
size_t nread = fread(filebuf, 1, filesize, infp);
|
||||
assert(nread == filesize);
|
||||
|
||||
int decoded_size = BASE64_DECODE_OUT_SIZE(filesize);
|
||||
unsigned char* decoded = (unsigned char*)malloc(decoded_size);
|
||||
decoded_size = hv_base64_decode(filebuf, filesize, decoded);
|
||||
|
||||
FILE* outfp = fopen(outfile, "wb");
|
||||
if (outfp == NULL) {
|
||||
printf("Save file '%s' failed!\n", infile);
|
||||
return -20;
|
||||
}
|
||||
size_t nwrite = fwrite(decoded, 1, decoded_size, outfp);
|
||||
assert(nwrite == decoded_size);
|
||||
|
||||
free(filebuf);
|
||||
free(decoded);
|
||||
fclose(infp);
|
||||
fclose(outfp);
|
||||
}
|
||||
else {
|
||||
printf("Unrecognized flags '%s'\n", flags);
|
||||
return -40;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
third_party/libhv/unittest/connect_test.c
vendored
Executable file
29
third_party/libhv/unittest/connect_test.c
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
#include "hsocket.h"
|
||||
#include "htime.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 3) {
|
||||
printf("Usage: cmd ip port\n");
|
||||
return -10;
|
||||
}
|
||||
|
||||
const char* ip = argv[1];
|
||||
int port = atoi(argv[2]);
|
||||
|
||||
unsigned int start_time = gettick_ms();
|
||||
int ret = ConnectNonblock(ip, port);
|
||||
unsigned int end_time = gettick_ms();
|
||||
printf("ConnectNonblock[%s:%d] retval=%d cost=%ums\n", ip, port, ret, end_time-start_time);
|
||||
|
||||
start_time = gettick_ms();
|
||||
ret = ConnectTimeout(ip, port, 3000);
|
||||
end_time = gettick_ms();
|
||||
printf("ConnectTimeout[%s:%d] retval=%d cost=%ums\n", ip, port, ret, end_time-start_time);
|
||||
|
||||
start_time = gettick_ms();
|
||||
ret = Connect(ip, port, 0);
|
||||
end_time = gettick_ms();
|
||||
printf("ConnectBlock[%s:%d] retval=%d cost=%ums\n", ip, port, ret, end_time-start_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
third_party/libhv/unittest/date_test.c
vendored
Executable file
17
third_party/libhv/unittest/date_test.c
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
#include "htime.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
datetime_t dt = datetime_now();
|
||||
char buf1[DATETIME_FMT_BUFLEN];
|
||||
datetime_fmt(&dt, buf1);
|
||||
puts(buf1);
|
||||
datetime_fmt_iso(&dt, buf1);
|
||||
puts(buf1);
|
||||
|
||||
time_t ts = datetime_mktime(&dt);
|
||||
char buf2[GMTIME_FMT_BUFLEN];
|
||||
gmtime_fmt(ts, buf2);
|
||||
puts(buf2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
third_party/libhv/unittest/defer_test.cpp
vendored
Executable file
19
third_party/libhv/unittest/defer_test.cpp
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hscope.h"
|
||||
|
||||
int main() {
|
||||
defer (
|
||||
printf("1\n");
|
||||
printf("2\n");
|
||||
)
|
||||
|
||||
defer (
|
||||
printf("3\n");
|
||||
printf("4\n");
|
||||
)
|
||||
|
||||
defer(printf("hello\n");)
|
||||
|
||||
return 0;
|
||||
}
|
||||
88
third_party/libhv/unittest/ftp_test.c
vendored
Executable file
88
third_party/libhv/unittest/ftp_test.c
vendored
Executable file
@@ -0,0 +1,88 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ftp.h"
|
||||
|
||||
void print_help() {
|
||||
printf("Usage:\n\
|
||||
help\n\
|
||||
login <username> <password>\n\
|
||||
download <remote_filepath> <local_filepath>\n\
|
||||
upload <local_filepath> <remote_filepath>\n\
|
||||
quit\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: ftp host [port]\n");
|
||||
return 0;
|
||||
}
|
||||
const char* host = argv[1];
|
||||
int port = FTP_COMMAND_PORT;
|
||||
if (argc >= 3) {
|
||||
port = atoi(argv[2]);
|
||||
}
|
||||
int ret = 0;
|
||||
ftp_handle_t hftp;
|
||||
ret = ftp_connect(&hftp, host, port);
|
||||
if (ret != 0) {
|
||||
printf("ftp connect failed!\n");
|
||||
return ret;
|
||||
}
|
||||
print_help();
|
||||
|
||||
char cmd[256] = {0};
|
||||
char param1[256] = {0};
|
||||
char param2[256] = {0};
|
||||
while (1) {
|
||||
printf("> ");
|
||||
scanf("%s", cmd);
|
||||
if (strncmp(cmd, "help", 4) == 0) {
|
||||
print_help();
|
||||
}
|
||||
else if (strncmp(cmd, "login", 5) == 0) {
|
||||
scanf("%s", param1);
|
||||
scanf("%s", param2);
|
||||
//printf("cmd=%s param1=%s param2=%s\n", cmd, param1, param2);
|
||||
const char* username = param1;
|
||||
const char* password = param2;
|
||||
ret = ftp_login(&hftp, username, password);
|
||||
printf("%s", hftp.recvbuf);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
else if (strncmp(cmd, "upload", 6) == 0) {
|
||||
scanf("%s", param1);
|
||||
scanf("%s", param2);
|
||||
//printf("cmd=%s param1=%s param2=%s\n", cmd, param1, param2);
|
||||
const char* localfile = param1;
|
||||
const char* remotefile = param2;
|
||||
ret = ftp_upload(&hftp, localfile, remotefile);
|
||||
printf("%s", hftp.recvbuf);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
else if (strncmp(cmd, "download", 8) == 0) {
|
||||
scanf("%s", param1);
|
||||
scanf("%s", param2);
|
||||
//printf("cmd=%s param1=%s param2=%s\n", cmd, param1, param2);
|
||||
const char* remotefile = param1;
|
||||
const char* localfile = param2;
|
||||
ret = ftp_download(&hftp, remotefile, localfile);
|
||||
printf("%s", hftp.recvbuf);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
else if (strncmp(cmd, "quit", 4) == 0) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
scanf("%s", param1);
|
||||
//printf("cmd=%s param=%s\n", cmd, param1);
|
||||
ret = ftp_exec(&hftp, cmd, param1);
|
||||
printf("%s", hftp.recvbuf);
|
||||
}
|
||||
}
|
||||
printf("QUIT\n");
|
||||
ftp_quit(&hftp);
|
||||
printf("%s", hftp.recvbuf);
|
||||
return 0;
|
||||
}
|
||||
39
third_party/libhv/unittest/hatomic_test.c
vendored
Executable file
39
third_party/libhv/unittest/hatomic_test.c
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hatomic.h"
|
||||
#include "hthread.h"
|
||||
|
||||
hatomic_flag_t flag = HATOMIC_FLAG_INIT;
|
||||
hatomic_t cnt = HATOMIC_VAR_INIT(0);
|
||||
|
||||
HTHREAD_ROUTINE(test_hatomic_flag) {
|
||||
if (!hatomic_flag_test_and_set(&flag)) {
|
||||
printf("tid=%ld flag 0=>1\n", hv_gettid());
|
||||
}
|
||||
else {
|
||||
printf("tid=%ld flag=1\n", hv_gettid());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_hatomic) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
long n = hatomic_inc(&cnt);
|
||||
printf("tid=%ld cnt=%ld\n", hv_gettid(), n);
|
||||
hv_delay(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
hthread_create(test_hatomic_flag, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
hthread_create(test_hatomic, NULL);
|
||||
}
|
||||
|
||||
hv_delay(1000);
|
||||
return 0;
|
||||
}
|
||||
39
third_party/libhv/unittest/hatomic_test.cpp
vendored
Executable file
39
third_party/libhv/unittest/hatomic_test.cpp
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hatomic.h"
|
||||
#include "hthread.h"
|
||||
|
||||
hatomic_flag_t flag = HATOMIC_FLAG_INIT;
|
||||
hatomic_t cnt = HATOMIC_VAR_INIT(0);
|
||||
|
||||
HTHREAD_ROUTINE(test_hatomic_flag) {
|
||||
if (!hatomic_flag_test_and_set(&flag)) {
|
||||
printf("tid=%ld flag 0=>1\n", hv_gettid());
|
||||
}
|
||||
else {
|
||||
printf("tid=%ld flag=1\n", hv_gettid());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_hatomic) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
long n = hatomic_inc(&cnt);
|
||||
printf("tid=%ld cnt=%ld\n", hv_gettid(), n);
|
||||
hv_delay(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
hthread_create(test_hatomic_flag, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
hthread_create(test_hatomic, NULL);
|
||||
}
|
||||
|
||||
hv_delay(1000);
|
||||
return 0;
|
||||
}
|
||||
114
third_party/libhv/unittest/hbase_test.c
vendored
Executable file
114
third_party/libhv/unittest/hbase_test.c
vendored
Executable file
@@ -0,0 +1,114 @@
|
||||
#include "hbase.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char buf[16] = {0};
|
||||
printf("hv_rand(10, 99) -> %d\n", hv_rand(10, 99));
|
||||
printf("hv_random_string(buf, 10) -> %s\n", hv_random_string(buf, 10));
|
||||
|
||||
assert(hv_getboolean("1"));
|
||||
assert(hv_getboolean("yes"));
|
||||
|
||||
assert(hv_wildcard_match("www.example.com", "www.example.com"));
|
||||
assert(hv_wildcard_match("www.example.com", "*.example.com"));
|
||||
assert(hv_wildcard_match("www.example.com", "www.*.com"));
|
||||
assert(hv_wildcard_match("www.example.com", "www.example.*"));
|
||||
|
||||
assert(hv_parse_size("256") == 256);
|
||||
assert(hv_parse_size("1K") == 1024);
|
||||
assert(hv_parse_size("1G2M3K4B") ==
|
||||
1 * 1024 * 1024 * 1024 +
|
||||
2 * 1024 * 1024 +
|
||||
3 * 1024 +
|
||||
4);
|
||||
|
||||
assert(hv_parse_time("30") == 30);
|
||||
assert(hv_parse_time("1m") == 60);
|
||||
assert(hv_parse_time("1d2h3m4s") ==
|
||||
1 * 24 * 60 * 60 +
|
||||
2 * 60 * 60 +
|
||||
3 * 60 +
|
||||
4);
|
||||
|
||||
const char* test_urls[] = {
|
||||
"http://user:pswd@www.example.com:80/path?query#fragment",
|
||||
"http://user:pswd@www.example.com/path?query#fragment",
|
||||
"http://www.example.com/path?query#fragment",
|
||||
"http://www.example.com/path?query",
|
||||
"http://www.example.com/path",
|
||||
"www.example.com/path",
|
||||
"/path",
|
||||
};
|
||||
hurl_t stURL;
|
||||
for (int i = 0; i < ARRAY_SIZE(test_urls); ++i) {
|
||||
const char* strURL = test_urls[i];
|
||||
printf("%s =>\n", strURL);
|
||||
hv_parse_url(&stURL, strURL);
|
||||
assert(stURL.port == 80);
|
||||
// scheme://
|
||||
if (stURL.fields[HV_URL_SCHEME].len > 0) {
|
||||
const char* scheme = strURL + stURL.fields[HV_URL_SCHEME].off;
|
||||
int len = stURL.fields[HV_URL_SCHEME].len;
|
||||
assert(len == 4);
|
||||
assert(strncmp(scheme, "http", len) == 0);
|
||||
printf("%.*s://", len, scheme);
|
||||
}
|
||||
// user:pswd@
|
||||
if (stURL.fields[HV_URL_USERNAME].len > 0) {
|
||||
const char* user = strURL + stURL.fields[HV_URL_USERNAME].off;
|
||||
int len = stURL.fields[HV_URL_USERNAME].len;
|
||||
assert(len == 4);
|
||||
assert(strncmp(user, "user", len) == 0);
|
||||
printf("%.*s", len, user);
|
||||
if (stURL.fields[HV_URL_PASSWORD].len > 0) {
|
||||
const char* pswd = strURL + stURL.fields[HV_URL_PASSWORD].off;
|
||||
int len = stURL.fields[HV_URL_PASSWORD].len;
|
||||
assert(len == 4);
|
||||
assert(strncmp(pswd, "pswd", len) == 0);
|
||||
printf(":%.*s", len, pswd);
|
||||
}
|
||||
printf("@");
|
||||
}
|
||||
// host:port
|
||||
if (stURL.fields[HV_URL_HOST].len > 0) {
|
||||
const char* host = strURL + stURL.fields[HV_URL_HOST].off;
|
||||
int len = stURL.fields[HV_URL_HOST].len;
|
||||
assert(len == strlen("www.example.com"));
|
||||
assert(strncmp(host, "www.example.com", len) == 0);
|
||||
printf("%.*s", len, host);
|
||||
if (stURL.fields[HV_URL_PORT].len > 0) {
|
||||
const char* port = strURL + stURL.fields[HV_URL_PORT].off;
|
||||
int len = stURL.fields[HV_URL_PORT].len;
|
||||
assert(len == 2);
|
||||
assert(strncmp(port, "80", len) == 0);
|
||||
printf(":%.*s", len, port);
|
||||
}
|
||||
}
|
||||
// /path
|
||||
if (stURL.fields[HV_URL_PATH].len > 0) {
|
||||
const char* path = strURL + stURL.fields[HV_URL_PATH].off;
|
||||
int len = stURL.fields[HV_URL_PATH].len;
|
||||
assert(len == 5);
|
||||
assert(strncmp(path, "/path", len) == 0);
|
||||
printf("%.*s", len, path);
|
||||
}
|
||||
// ?query
|
||||
if (stURL.fields[HV_URL_QUERY].len > 0) {
|
||||
const char* query = strURL + stURL.fields[HV_URL_QUERY].off;
|
||||
int len = stURL.fields[HV_URL_QUERY].len;
|
||||
assert(len == 5);
|
||||
assert(strncmp(query, "query", len) == 0);
|
||||
printf("?%.*s", len, query);
|
||||
}
|
||||
// #fragment
|
||||
if (stURL.fields[HV_URL_FRAGMENT].len > 0) {
|
||||
const char* fragment = strURL + stURL.fields[HV_URL_FRAGMENT].off;
|
||||
int len = stURL.fields[HV_URL_FRAGMENT].len;
|
||||
assert(len == 8);
|
||||
assert(strncmp(fragment, "fragment", len) == 0);
|
||||
printf("#%.*s", len, fragment);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
134
third_party/libhv/unittest/hmutex_test.c
vendored
Executable file
134
third_party/libhv/unittest/hmutex_test.c
vendored
Executable file
@@ -0,0 +1,134 @@
|
||||
#include "hthread.h"
|
||||
#include "hmutex.h"
|
||||
#include "htime.h"
|
||||
|
||||
void once_print() {
|
||||
printf("exec once\n");
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_once) {
|
||||
honce_t once = HONCE_INIT;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
honce(&once, once_print);
|
||||
}
|
||||
printf("honce test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_mutex) {
|
||||
hmutex_t mutex;
|
||||
hmutex_init(&mutex);
|
||||
hmutex_lock(&mutex);
|
||||
hmutex_unlock(&mutex);
|
||||
hmutex_destroy(&mutex);
|
||||
printf("hmutex test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_recursive_mutex) {
|
||||
hrecursive_mutex_t mutex;
|
||||
hrecursive_mutex_init(&mutex);
|
||||
hrecursive_mutex_lock(&mutex);
|
||||
hrecursive_mutex_lock(&mutex);
|
||||
hrecursive_mutex_unlock(&mutex);
|
||||
hrecursive_mutex_unlock(&mutex);
|
||||
hrecursive_mutex_destroy(&mutex);
|
||||
printf("hrecursive_mutex test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_spinlock) {
|
||||
hspinlock_t spin;
|
||||
hspinlock_init(&spin);
|
||||
hspinlock_lock(&spin);
|
||||
hspinlock_unlock(&spin);
|
||||
hspinlock_destroy(&spin);
|
||||
printf("hspinlock test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_rwlock) {
|
||||
hrwlock_t rwlock;
|
||||
hrwlock_init(&rwlock);
|
||||
hrwlock_rdlock(&rwlock);
|
||||
hrwlock_rdunlock(&rwlock);
|
||||
hrwlock_wrlock(&rwlock);
|
||||
hrwlock_wrunlock(&rwlock);
|
||||
hrwlock_destroy(&rwlock);
|
||||
printf("hrwlock test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_timed_mutex) {
|
||||
htimed_mutex_t mutex;
|
||||
htimed_mutex_init(&mutex);
|
||||
htimed_mutex_lock(&mutex);
|
||||
time_t start_time = gettick_ms();
|
||||
htimed_mutex_lock_for(&mutex, 3000);
|
||||
time_t end_time = gettick_ms();
|
||||
printf("htimed_mutex_lock_for %zdms\n", end_time - start_time);
|
||||
htimed_mutex_unlock(&mutex);
|
||||
htimed_mutex_destroy(&mutex);
|
||||
printf("htimed_mutex test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_condvar) {
|
||||
hmutex_t mutex;
|
||||
hmutex_init(&mutex);
|
||||
hcondvar_t cv;
|
||||
hcondvar_init(&cv);
|
||||
|
||||
hmutex_lock(&mutex);
|
||||
hcondvar_signal(&cv);
|
||||
hcondvar_broadcast(&cv);
|
||||
time_t start_time = gettick_ms();
|
||||
hcondvar_wait_for(&cv, &mutex, 3000);
|
||||
time_t end_time = gettick_ms();
|
||||
printf("hcondvar_wait_for %zdms\n", end_time - start_time);
|
||||
hmutex_unlock(&mutex);
|
||||
|
||||
hmutex_destroy(&mutex);
|
||||
hcondvar_destroy(&cv);
|
||||
printf("hcondvar test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(test_sem) {
|
||||
hsem_t sem;
|
||||
hsem_init(&sem, 10);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
hsem_wait(&sem);
|
||||
}
|
||||
hsem_post(&sem);
|
||||
hsem_wait(&sem);
|
||||
time_t start_time = gettick_ms();
|
||||
hsem_wait_for(&sem, 3000);
|
||||
time_t end_time = gettick_ms();
|
||||
printf("hsem_wait_for %zdms\n", end_time - start_time);
|
||||
hsem_destroy(&sem);
|
||||
printf("hsem test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
hthread_t thread_once = hthread_create(test_once, NULL);
|
||||
hthread_t thread_mutex = hthread_create(test_mutex, NULL);
|
||||
hthread_t thread_recursive_mutex = hthread_create(test_recursive_mutex, NULL);
|
||||
hthread_t thread_spinlock = hthread_create(test_spinlock, NULL);
|
||||
hthread_t thread_rwlock = hthread_create(test_rwlock, NULL);
|
||||
hthread_t thread_timed_mutex = hthread_create(test_timed_mutex, NULL);
|
||||
hthread_t thread_condvar = hthread_create(test_condvar, NULL);
|
||||
hthread_t thread_sem = hthread_create(test_sem, NULL);
|
||||
|
||||
hthread_join(thread_once);
|
||||
hthread_join(thread_mutex);
|
||||
hthread_join(thread_recursive_mutex);
|
||||
hthread_join(thread_spinlock);
|
||||
hthread_join(thread_rwlock);
|
||||
hthread_join(thread_timed_mutex);
|
||||
hthread_join(thread_condvar);
|
||||
hthread_join(thread_sem);
|
||||
printf("hthread test OK!\n");
|
||||
return 0;
|
||||
}
|
||||
15
third_party/libhv/unittest/hpath_test.cpp
vendored
Executable file
15
third_party/libhv/unittest/hpath_test.cpp
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
#include "hpath.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::string filepath = HPath::join("/mnt/share/image", "test.jpg");
|
||||
std::string basename = HPath::basename(filepath);
|
||||
std::string dirname = HPath::dirname(filepath);
|
||||
std::string filename = HPath::filename(filepath);
|
||||
std::string suffixname = HPath::suffixname(filepath);
|
||||
printf("filepath = %s\n", filepath.c_str());
|
||||
printf("basename = %s\n", basename.c_str());
|
||||
printf("dirname = %s\n", dirname.c_str());
|
||||
printf("filename = %s\n", filename.c_str());
|
||||
printf("suffixname = %s\n", suffixname.c_str());
|
||||
return 0;
|
||||
}
|
||||
52
third_party/libhv/unittest/hstring_test.cpp
vendored
Executable file
52
third_party/libhv/unittest/hstring_test.cpp
vendored
Executable file
@@ -0,0 +1,52 @@
|
||||
#include "hstring.h"
|
||||
using namespace hv;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::string str1 = "a1B2*C3d4==";
|
||||
std::string str2 = "a1B2*C3d4==";
|
||||
println("toupper=" + toupper(str1));
|
||||
println("tolower=" + tolower(str2));
|
||||
std::string str3 = "abcdefg";
|
||||
println("reverse=" + reverse(str3));
|
||||
|
||||
std::string str4 = "123456789";
|
||||
printf("startswith=%d\nendswith=%d\ncontains=%d\n",
|
||||
(int)startswith(str4, "123"),
|
||||
(int)endswith(str4, "789"),
|
||||
(int)contains(str4, "456"));
|
||||
|
||||
std::string str5 = asprintf("%s%d", "hello", 5);
|
||||
println("asprintf=" + str5);
|
||||
|
||||
std::string str6("123,456,789");
|
||||
StringList strlist = split(str6, ',');
|
||||
println("split " + str6);
|
||||
for (auto& str : strlist) {
|
||||
println(str);
|
||||
}
|
||||
|
||||
std::string str7("user=admin&pswd=123456");
|
||||
hv::KeyValue kv = splitKV(str7, '&', '=');
|
||||
for (auto& pair : kv) {
|
||||
printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
|
||||
}
|
||||
|
||||
std::string str8("<stdio.h>");
|
||||
std::string str9 = trim_pairs(str8);
|
||||
println("trim_pairs=" + str9);
|
||||
|
||||
std::string str10("<title>{{title}}</title>");
|
||||
std::string str11 = replace(str10, "{{title}}", "Home");
|
||||
println("replace=" + str11);
|
||||
|
||||
NetAddr addr1("0.0.0.0:8080");
|
||||
println(addr1.to_string());
|
||||
|
||||
NetAddr addr2("[::0]:8080");
|
||||
println(addr2.to_string());
|
||||
|
||||
NetAddr addr3(":8080");
|
||||
println(addr3.to_string());
|
||||
|
||||
return 0;
|
||||
}
|
||||
59
third_party/libhv/unittest/hthread_test.cpp
vendored
Executable file
59
third_party/libhv/unittest/hthread_test.cpp
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
#include "hthread.h"
|
||||
#include "htime.h"
|
||||
|
||||
HTHREAD_ROUTINE(test_thread1) {
|
||||
int cnt = 10;
|
||||
while (cnt-- > 0) {
|
||||
printf("tid=%ld time=%llums\n", hv_gettid(), gettimeofday_ms());
|
||||
hv_msleep(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class TestThread2 : public HThread {
|
||||
protected:
|
||||
virtual void run() {
|
||||
int cnt = 10;
|
||||
while (cnt-- > 0) {
|
||||
printf("tid=%ld time=%llums\n", hv_gettid(), gettimeofday_ms());
|
||||
hv_msleep(100);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class TestThread3 : public HThread {
|
||||
protected:
|
||||
virtual bool doPrepare() {
|
||||
printf("doPrepare\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void doTask() {
|
||||
printf("tid=%ld time=%llums\n", hv_gettid(), gettimeofday_ms());
|
||||
}
|
||||
|
||||
virtual bool doFinish() {
|
||||
printf("doFinish\n");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
printf("c-style hthread_create\n");
|
||||
hthread_t thread1 = hthread_create(test_thread1, NULL);
|
||||
hthread_join(thread1);
|
||||
|
||||
printf("cpp-style override HThread::run\n");
|
||||
TestThread2 thread2;
|
||||
thread2.start();
|
||||
thread2.stop();
|
||||
|
||||
printf("cpp-style override HThread::doTask\n");
|
||||
TestThread3 thread3;
|
||||
thread3.setSleepPolicy(HThread::SLEEP_UNTIL, 100);
|
||||
thread3.start();
|
||||
hv_sleep(1);
|
||||
thread3.stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
23
third_party/libhv/unittest/hurl_test.cpp
vendored
Executable file
23
third_party/libhv/unittest/hurl_test.cpp
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "hurl.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::string strURL = "http://www.example.com/path?query#fragment";
|
||||
HUrl url;
|
||||
if (!url.parse(strURL)) {
|
||||
printf("parse url %s error!\n", strURL.c_str());
|
||||
return -1;
|
||||
}
|
||||
std::string dumpURL = url.dump();
|
||||
printf("%s =>\n%s\n", strURL.c_str(), dumpURL.c_str());
|
||||
assert(strURL == dumpURL);
|
||||
|
||||
const char* str = "中 文";
|
||||
std::string escaped = HUrl::escape(str);
|
||||
std::string unescaped = HUrl::unescape(escaped.c_str());
|
||||
printf("%s => %s\n", str, escaped.c_str());
|
||||
assert(str == unescaped);
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
third_party/libhv/unittest/ifconfig_test.cpp
vendored
Executable file
17
third_party/libhv/unittest/ifconfig_test.cpp
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ifconfig.h"
|
||||
|
||||
int main() {
|
||||
std::vector<ifconfig_t> ifcs;
|
||||
ifconfig(ifcs);
|
||||
for (auto& item : ifcs) {
|
||||
printf("%s\nip: %s\nmask: %s\nbroadcast: %s\nmac: %s\n\n",
|
||||
item.name,
|
||||
item.ip,
|
||||
item.mask,
|
||||
item.broadcast,
|
||||
item.mac);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
44
third_party/libhv/unittest/listdir_test.cpp
vendored
Executable file
44
third_party/libhv/unittest/listdir_test.cpp
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hdir.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* dir = ".";
|
||||
if (argc > 1) {
|
||||
dir = argv[1];
|
||||
}
|
||||
std::list<hdir_t> dirs;
|
||||
listdir(dir, dirs);
|
||||
for (auto& item : dirs) {
|
||||
printf("%c%c%c%c%c%c%c%c%c%c\t",
|
||||
item.type,
|
||||
(item.mode & 0400) ? 'r' : '-',
|
||||
(item.mode & 0200) ? 'w' : '-',
|
||||
(item.mode & 0100) ? 'x' : '-',
|
||||
(item.mode & 0040) ? 'r' : '-',
|
||||
(item.mode & 0020) ? 'w' : '-',
|
||||
(item.mode & 0010) ? 'x' : '-',
|
||||
(item.mode & 0004) ? 'r' : '-',
|
||||
(item.mode & 0002) ? 'w' : '-',
|
||||
(item.mode & 0001) ? 'x' : '-');
|
||||
float hsize;
|
||||
if (item.size < 1024) {
|
||||
printf("%lu\t", item.size);
|
||||
}
|
||||
else if ((hsize = item.size/1024.0f) < 1024.0f) {
|
||||
printf("%.1fK\t", hsize);
|
||||
}
|
||||
else if ((hsize /= 1024.0f) < 1024.0f) {
|
||||
printf("%.1fM\t", hsize);
|
||||
}
|
||||
else {
|
||||
hsize /= 1024.0f;
|
||||
printf("%.1fG\t", hsize);
|
||||
}
|
||||
struct tm* tm = localtime(&item.mtime);
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\t",
|
||||
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
printf("%s%s\n", item.name, item.type == 'd' ? "/" : "");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
64
third_party/libhv/unittest/md5_test.c
vendored
Executable file
64
third_party/libhv/unittest/md5_test.c
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* @build: gcc -o bin/md5 unittest/md5_test.c util/md5.c -I. -Iutil
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
static void test() {
|
||||
unsigned char ch = '1';
|
||||
char md5[33] = {0};
|
||||
hv_md5_hex(&ch, 1, md5, sizeof(md5));
|
||||
assert(strcmp(md5, "c4ca4238a0b923820dcc509a6f75849b") == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
test();
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: md5 file\n");
|
||||
printf(" md5 -s string\n");
|
||||
return -10;
|
||||
}
|
||||
|
||||
char md5[33] = {0};
|
||||
|
||||
if (argc == 2) {
|
||||
const char* filepath = argv[1];
|
||||
FILE* fp = fopen(filepath, "rb");
|
||||
if (fp == NULL) {
|
||||
printf("Open file '%s' failed!\n", filepath);
|
||||
return -20;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long filesize = ftell(fp);
|
||||
// printf("filesize=%ld\n", filesize);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
unsigned char* filebuf = (unsigned char*)malloc(filesize);
|
||||
size_t nread = fread(filebuf, 1, filesize, fp);
|
||||
assert(nread == filesize);
|
||||
hv_md5_hex(filebuf, filesize, md5, sizeof(md5));
|
||||
|
||||
free(filebuf);
|
||||
fclose(fp);
|
||||
}
|
||||
else if (argc == 3) {
|
||||
const char* flags = argv[1];
|
||||
if (flags[0] == '-' && flags[1] == 's') {
|
||||
hv_md5_hex((unsigned char*)argv[2], strlen(argv[2]), md5, sizeof(md5));
|
||||
}
|
||||
else {
|
||||
printf("Unrecognized flags '%s'\n", flags);
|
||||
return -40;
|
||||
}
|
||||
}
|
||||
|
||||
puts(md5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
third_party/libhv/unittest/mkdir_test.c
vendored
Executable file
10
third_party/libhv/unittest/mkdir_test.c
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
#include "hbase.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: mkdir_p dir\n");
|
||||
return -1;
|
||||
}
|
||||
const char* dir = argv[1];
|
||||
return hv_mkdir_p(dir);
|
||||
}
|
||||
34
third_party/libhv/unittest/nslookup_test.c
vendored
Executable file
34
third_party/libhv/unittest/nslookup_test.c
vendored
Executable file
@@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hplatform.h" // inet_ntop
|
||||
#include "dns.h" // nslookup
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: nslookup domain [nameserver]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* domain = argv[1];
|
||||
const char* nameserver = "127.0.1.1";
|
||||
#ifndef OS_LINUX
|
||||
nameserver = "114.114.114.114";
|
||||
// nameserver = "8.8.8.8";
|
||||
#endif
|
||||
|
||||
if (argc > 2) {
|
||||
nameserver = argv[2];
|
||||
}
|
||||
|
||||
uint32_t addrs[16];
|
||||
int naddr = nslookup(domain, addrs, 16, nameserver);
|
||||
if (naddr < 0) {
|
||||
return naddr;
|
||||
}
|
||||
char ip[16];
|
||||
for (int i = 0; i < naddr; ++i) {
|
||||
inet_ntop(AF_INET, (void*)&addrs[i], ip, 16);
|
||||
printf("%s\n", ip);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
56
third_party/libhv/unittest/objectpool_test.cpp
vendored
Executable file
56
third_party/libhv/unittest/objectpool_test.cpp
vendored
Executable file
@@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
#include <thread>
|
||||
|
||||
#include "hobjectpool.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void msleep(unsigned int ms) {
|
||||
#ifdef _WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
usleep(ms*1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
class Task {
|
||||
public:
|
||||
Task() {printf("Task()\n");}
|
||||
~Task() {printf("~Task()\n");}
|
||||
|
||||
void Do() {
|
||||
printf("%p start do...\n", this);
|
||||
msleep(4000);
|
||||
printf("%p end do\n", this);
|
||||
}
|
||||
};
|
||||
|
||||
HObjectPool<Task> task_pool(1, 5);
|
||||
|
||||
void task_thread(int id) {
|
||||
printf("thread %d run...\n", id);
|
||||
HPoolObject<Task> pTask(task_pool);
|
||||
if (pTask) {
|
||||
pTask->Do();
|
||||
}
|
||||
else {
|
||||
printf("No available task in pool\n");
|
||||
}
|
||||
printf("thread %d exit\n", id);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
new std::thread(task_thread, i);
|
||||
}
|
||||
msleep(5000);
|
||||
for (int i = 10; i < 20; ++i) {
|
||||
new std::thread(task_thread, i);
|
||||
}
|
||||
msleep(10000);
|
||||
return 0;
|
||||
}
|
||||
16
third_party/libhv/unittest/ping_test.c
vendored
Executable file
16
third_party/libhv/unittest/ping_test.c
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include "icmp.h"
|
||||
#include "hplatform.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: ping host|ip\n");
|
||||
return -10;
|
||||
}
|
||||
|
||||
char* host = argv[1];
|
||||
int ping_cnt = 4;
|
||||
int ok_cnt = ping(host, ping_cnt);
|
||||
printf("ping %d count, %d ok.\n", ping_cnt, ok_cnt);
|
||||
return 0;
|
||||
}
|
||||
111
third_party/libhv/unittest/rbtree_test.c
vendored
Executable file
111
third_party/libhv/unittest/rbtree_test.c
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rbtree.h"
|
||||
|
||||
typedef int rbtree_key_type;
|
||||
typedef int rbtree_val_type;
|
||||
|
||||
struct rbtree_entry {
|
||||
struct rb_node rb_node;
|
||||
rbtree_key_type key;
|
||||
rbtree_val_type val;
|
||||
};
|
||||
|
||||
int rbtree_insert(struct rb_root* root, struct rbtree_entry* entry) {
|
||||
printf("insert %d\n", entry->key);
|
||||
struct rb_node** n = &root->rb_node;
|
||||
struct rb_node* parent = NULL;
|
||||
struct rbtree_entry* e = NULL;
|
||||
while (*n) {
|
||||
parent = *n;
|
||||
e = rb_entry(*n, struct rbtree_entry, rb_node);
|
||||
if (entry->key < e->key) {
|
||||
n = &(*n)->rb_left;
|
||||
} else if (entry->key > e->key) {
|
||||
n = &(*n)->rb_right;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&entry->rb_node, parent, n);
|
||||
rb_insert_color(&entry->rb_node, root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rbtree_remove(struct rb_root* root, struct rbtree_entry* entry) {
|
||||
printf("remove %d\n", entry->key);
|
||||
rb_erase(&entry->rb_node, root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rbtree_entry* rbtree_search(struct rb_root* root, const rbtree_key_type* key) {
|
||||
struct rb_node* n = root->rb_node;
|
||||
struct rbtree_entry* e = NULL;
|
||||
while (n) {
|
||||
e = rb_entry(n, struct rbtree_entry, rb_node);
|
||||
if (*key < e->key) {
|
||||
n = n->rb_left;
|
||||
} else if (*key > e->key) {
|
||||
n = n->rb_right;
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rbtree_entry_print(struct rbtree_entry* entry) {
|
||||
if (entry == NULL) {
|
||||
printf("null\n");
|
||||
return;
|
||||
}
|
||||
printf("%d:%d\n", entry->key, entry->val);
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct rb_root root = { NULL };
|
||||
struct rbtree_entry* entry = NULL;
|
||||
|
||||
struct rbtree_entry entries[10];
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
memset(&entries[i], 0, sizeof(struct rbtree_entry));
|
||||
entries[i].key = i;
|
||||
entries[i].val = i;
|
||||
}
|
||||
|
||||
rbtree_insert(&root, &entries[1]);
|
||||
rbtree_insert(&root, &entries[2]);
|
||||
rbtree_insert(&root, &entries[3]);
|
||||
rbtree_insert(&root, &entries[7]);
|
||||
rbtree_insert(&root, &entries[8]);
|
||||
rbtree_insert(&root, &entries[9]);
|
||||
rbtree_insert(&root, &entries[4]);
|
||||
rbtree_insert(&root, &entries[5]);
|
||||
rbtree_insert(&root, &entries[6]);
|
||||
|
||||
rbtree_remove(&root, &entries[1]);
|
||||
rbtree_remove(&root, &entries[9]);
|
||||
rbtree_remove(&root, &entries[4]);
|
||||
rbtree_remove(&root, &entries[6]);
|
||||
|
||||
int key = 5;
|
||||
entry = rbtree_search(&root, &key);
|
||||
rbtree_entry_print(entry);
|
||||
|
||||
key = 4;
|
||||
entry = rbtree_search(&root, &key);
|
||||
rbtree_entry_print(entry);
|
||||
|
||||
struct rb_node* node = NULL;
|
||||
// while((node = rb_first(&root))) {
|
||||
while((node = root.rb_node)) {
|
||||
entry = rb_entry(node, struct rbtree_entry, rb_node);
|
||||
rb_erase(node, &root);
|
||||
rbtree_entry_print(entry);
|
||||
memset(entry, 0, sizeof(struct rbtree_entry));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
third_party/libhv/unittest/rmdir_test.c
vendored
Executable file
10
third_party/libhv/unittest/rmdir_test.c
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
#include "hbase.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: rmdir_p dir\n");
|
||||
return -1;
|
||||
}
|
||||
const char* dir = argv[1];
|
||||
return hv_rmdir_p(dir);
|
||||
}
|
||||
24
third_party/libhv/unittest/sendmail_test.c
vendored
Executable file
24
third_party/libhv/unittest/sendmail_test.c
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "smtp.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 8) {
|
||||
printf("Usage: sendmail smtp_server username password from to subject body\n");
|
||||
return -10;
|
||||
}
|
||||
|
||||
const char* smtp_server = argv[1];
|
||||
const char* username = argv[2];
|
||||
const char* password = argv[3];
|
||||
mail_t mail;
|
||||
mail.from = argv[4];
|
||||
mail.to = argv[5];
|
||||
mail.subject = argv[6];
|
||||
mail.body = argv[7];
|
||||
|
||||
int status_code = sendmail(smtp_server, username, password, &mail);
|
||||
printf("sendmail: %d %s\n", status_code, smtp_status_str((enum smtp_status)status_code));
|
||||
|
||||
return status_code == SMTP_STATUS_OK ? 0 : status_code;
|
||||
}
|
||||
64
third_party/libhv/unittest/sha1_test.c
vendored
Executable file
64
third_party/libhv/unittest/sha1_test.c
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* @build: gcc -o bin/sha1 unittest/sha1_test.c util/sha1.c -I. -Iutil
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
static void test() {
|
||||
unsigned char ch = '1';
|
||||
char sha1[41] = {0};
|
||||
hv_sha1_hex(&ch, 1, sha1, sizeof(sha1));
|
||||
assert(strcmp(sha1, "356a192b7913b04c54574d18c28d46e6395428ab") == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
test();
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: sha1 file\n");
|
||||
printf(" sha1 -s string\n");
|
||||
return -10;
|
||||
}
|
||||
|
||||
char sha1[41] = {0};
|
||||
|
||||
if (argc == 2) {
|
||||
const char* filepath = argv[1];
|
||||
FILE* fp = fopen(filepath, "rb");
|
||||
if (fp == NULL) {
|
||||
printf("Open file '%s' failed!\n", filepath);
|
||||
return -20;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long filesize = ftell(fp);
|
||||
// printf("filesize=%ld\n", filesize);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
unsigned char* filebuf = (unsigned char*)malloc(filesize);
|
||||
size_t nread = fread(filebuf, 1, filesize, fp);
|
||||
assert(nread == filesize);
|
||||
hv_sha1_hex(filebuf, filesize, sha1, sizeof(sha1));
|
||||
|
||||
free(filebuf);
|
||||
fclose(fp);
|
||||
}
|
||||
else if (argc == 3) {
|
||||
const char* flags = argv[1];
|
||||
if (flags[0] == '-' && flags[1] == 's') {
|
||||
hv_sha1_hex((unsigned char*)argv[2], strlen(argv[2]), sha1, sizeof(sha1));
|
||||
}
|
||||
else {
|
||||
printf("Unrecognized flags '%s'\n", flags);
|
||||
return -40;
|
||||
}
|
||||
}
|
||||
|
||||
puts(sha1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
62
third_party/libhv/unittest/sizeof_test.cpp
vendored
Executable file
62
third_party/libhv/unittest/sizeof_test.cpp
vendored
Executable file
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hloop.h"
|
||||
#include "hevent.h"
|
||||
|
||||
#include "EventLoop.h"
|
||||
#include "EventLoopThread.h"
|
||||
#include "EventLoopThreadPool.h"
|
||||
#include "Channel.h"
|
||||
#include "TcpClient.h"
|
||||
#include "TcpServer.h"
|
||||
#include "UdpClient.h"
|
||||
#include "UdpServer.h"
|
||||
|
||||
#include "HttpMessage.h"
|
||||
#include "Http1Parser.h"
|
||||
#include "HttpContext.h"
|
||||
#include "HttpServer.h"
|
||||
#include "HttpHandler.h"
|
||||
#include "HttpResponseWriter.h"
|
||||
|
||||
#include "WebSocketChannel.h"
|
||||
#include "WebSocketParser.h"
|
||||
#include "WebSocketServer.h"
|
||||
#include "WebSocketClient.h"
|
||||
|
||||
using namespace hv;
|
||||
|
||||
int main() {
|
||||
// event
|
||||
printf("sizeof(struct hloop_s)=%lu\n", sizeof(struct hloop_s));
|
||||
printf("sizeof(struct hevent_s)=%lu\n", sizeof(struct hevent_s));
|
||||
printf("sizeof(struct hidle_s)=%lu\n", sizeof(struct hidle_s));
|
||||
printf("sizeof(struct htimer_s)=%lu\n", sizeof(struct htimer_s));
|
||||
printf("sizeof(struct htimeout_s)=%lu\n", sizeof(struct htimeout_s));
|
||||
printf("sizeof(struct hperiod_s)=%lu\n", sizeof(struct hperiod_s));
|
||||
printf("sizeof(struct hio_s)=%lu\n", sizeof(struct hio_s));
|
||||
// evpp
|
||||
printf("sizeof(class EventLoop)=%lu\n", sizeof(EventLoop));
|
||||
printf("sizeof(class EventLoopThread)=%lu\n", sizeof(EventLoopThread));
|
||||
printf("sizeof(class EventLoopThreadPool)=%lu\n", sizeof(EventLoopThreadPool));
|
||||
printf("sizeof(class Channel)=%lu\n", sizeof(Channel));
|
||||
printf("sizeof(class SocketChannel)=%lu\n", sizeof(SocketChannel));
|
||||
printf("sizeof(class TcpClient)=%lu\n", sizeof(TcpClient));
|
||||
printf("sizeof(class TcpServer)=%lu\n", sizeof(TcpServer));
|
||||
printf("sizeof(class UdpClient)=%lu\n", sizeof(UdpClient));
|
||||
printf("sizeof(class UdpServer)=%lu\n", sizeof(UdpServer));
|
||||
// http
|
||||
printf("sizeof(class HttpRequest)=%lu\n", sizeof(HttpRequest));
|
||||
printf("sizeof(class HttpResponse)=%lu\n", sizeof(HttpResponse));
|
||||
printf("sizeof(class Http1Parser)=%lu\n", sizeof(Http1Parser));
|
||||
printf("sizeof(class HttpContext)=%lu\n", sizeof(HttpContext));
|
||||
printf("sizeof(class HttpServer)=%lu\n", sizeof(HttpServer));
|
||||
printf("sizeof(class HttpHandler)=%lu\n", sizeof(HttpHandler));
|
||||
printf("sizeof(class HttpResponseWrite)=%lu\n", sizeof(HttpResponseWriter));
|
||||
// websocket
|
||||
printf("sizeof(class WebSocketChannel)=%lu\n", sizeof(WebSocketChannel));
|
||||
printf("sizeof(class WebSocketParser)=%lu\n", sizeof(WebSocketParser));
|
||||
printf("sizeof(class WebSocketClient)=%lu\n", sizeof(WebSocketClient));
|
||||
printf("sizeof(class WebSocketServer)=%lu\n", sizeof(WebSocketServer));
|
||||
return 0;
|
||||
}
|
||||
24
third_party/libhv/unittest/socketpair_test.c
vendored
Executable file
24
third_party/libhv/unittest/socketpair_test.c
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hsocket.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int sockfds[2];
|
||||
if (Socketpair(AF_INET, SOCK_STREAM, 0, sockfds) != 0) {
|
||||
printf("socketpair failed!\n");
|
||||
return -1;
|
||||
}
|
||||
printf("Socketpair %d<=>%d\n", sockfds[0], sockfds[1]);
|
||||
|
||||
char sendbuf[] = "hello,world!";
|
||||
char recvbuf[1460];
|
||||
int nsend = send(sockfds[0], sendbuf, strlen(sendbuf), 0);
|
||||
printf("sockfd:%d send %d bytes: %s\n", sockfds[0], nsend, sendbuf);
|
||||
memset(recvbuf, 0, sizeof(recvbuf));
|
||||
int nrecv = recv(sockfds[1], recvbuf, sizeof(recvbuf), 0);
|
||||
printf("sockfd:%d recv %d bytes: %s\n", sockfds[1], nrecv, recvbuf);
|
||||
|
||||
closesocket(sockfds[0]);
|
||||
closesocket(sockfds[1]);
|
||||
return 0;
|
||||
}
|
||||
24
third_party/libhv/unittest/synchronized_test.cpp
vendored
Executable file
24
third_party/libhv/unittest/synchronized_test.cpp
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
#include "hthread.h"
|
||||
#include "hmutex.h"
|
||||
|
||||
#define THREAD_NUM 10
|
||||
std::mutex g_mutex;
|
||||
|
||||
HTHREAD_ROUTINE(test_synchronized) {
|
||||
synchronized(g_mutex) {
|
||||
hv_delay(1000);
|
||||
printf("tid=%ld time=%llus\n", hv_gettid(), (unsigned long long)time(NULL));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
hthread_t threads[THREAD_NUM];
|
||||
for (int i = 0; i < THREAD_NUM; ++i) {
|
||||
threads[i] = hthread_create(test_synchronized, NULL);
|
||||
}
|
||||
for (int i = 0; i < THREAD_NUM; ++i) {
|
||||
hthread_join(threads[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
30
third_party/libhv/unittest/threadpool_test.cpp
vendored
Executable file
30
third_party/libhv/unittest/threadpool_test.cpp
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hthreadpool.h"
|
||||
#include "hthread.h"
|
||||
#include "htime.h"
|
||||
|
||||
void print_task(int i) {
|
||||
printf("thread[%ld]: task[%d]\n", hv_gettid(), i);
|
||||
hv_sleep(1);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
HThreadPool tp(1, 4);
|
||||
tp.start();
|
||||
|
||||
int i = 0;
|
||||
for (; i < 10; ++i) {
|
||||
tp.commit(print_task, i);
|
||||
}
|
||||
|
||||
tp.wait();
|
||||
|
||||
for (; i < 20; ++i) {
|
||||
tp.commit(print_task, i);
|
||||
}
|
||||
|
||||
tp.wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
373
third_party/libhv/unittest/webbench.c
vendored
Executable file
373
third_party/libhv/unittest/webbench.c
vendored
Executable file
@@ -0,0 +1,373 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h> // for gethostbyname
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int Connect(const char* host, int port) {
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
in_addr_t inaddr = inet_addr(host);
|
||||
if (inaddr != INADDR_NONE) {
|
||||
addr.sin_addr.s_addr = inaddr;
|
||||
}
|
||||
else {
|
||||
struct hostent* phe = gethostbyname(host);
|
||||
if (phe == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(&addr.sin_addr, phe->h_addr_list[0], phe->h_length);
|
||||
}
|
||||
addr.sin_port = htons(port);
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
return -2;
|
||||
}
|
||||
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
perror("connect");
|
||||
return -3;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
#define METHOD_GET 0
|
||||
#define METHOD_HEAD 1
|
||||
#define METHOD_OPTIONS 2
|
||||
#define METHOD_TRACE 3
|
||||
|
||||
#define VERSION "webbench/1.19.3.15"
|
||||
|
||||
int verbose = 0;
|
||||
int quiet = 0;
|
||||
volatile int timerexpired = 0; // for timer
|
||||
int time = 30;
|
||||
int clients = 1;
|
||||
char host[64] = {0};
|
||||
int port = 80;
|
||||
char* proxy_host = NULL;
|
||||
int proxy_port = 80;
|
||||
int method = METHOD_GET;
|
||||
int http = 1; // 1=HTTP/1.1 0=HTTP/1.0
|
||||
int keepalive = 0;
|
||||
const char* url = NULL;
|
||||
|
||||
#define REQUEST_SIZE 2048
|
||||
char request[REQUEST_SIZE] = {0};
|
||||
char buf[1460] = {0};
|
||||
|
||||
int mypipe[2]; // IPC
|
||||
|
||||
static const char options[] = "?hVvq01kt:p:c:";
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"time", required_argument, NULL, 't'},
|
||||
{"proxy", required_argument, NULL, 'p'},
|
||||
{"clients", required_argument, NULL, 'c'},
|
||||
{"http10", no_argument, NULL, '0'},
|
||||
{"http11", no_argument, NULL, '1'},
|
||||
{"keepalive", no_argument, NULL, 'k'},
|
||||
{"get", no_argument, &method, METHOD_GET},
|
||||
{"head", no_argument, &method, METHOD_HEAD},
|
||||
{"options", no_argument, &method, METHOD_OPTIONS},
|
||||
{"trace", no_argument, &method, METHOD_TRACE},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
void print_usage() {
|
||||
printf("Usage: webbench [%s] URL\n", options);
|
||||
puts("\n\
|
||||
Options:\n\
|
||||
-?|-h|--help Print this information.\n\
|
||||
-V|--version Print version.\n\
|
||||
-v|--verbose Print verbose.\n\
|
||||
-q|--quiet Print quiet.\n\
|
||||
-0|--http10 Use HTTP/1.0 protocol.\n\
|
||||
-1|--http11 Use HTTP/1.1 protocol.\n\
|
||||
-k|--keepalive Connection: keep-alive.\n\
|
||||
-t|--time <sec> Run benchmark for <sec> seconds. Default 30.\n\
|
||||
-p|--proxy <server:port> Use proxy server for request.\n\
|
||||
-c|--clients <n> Run <n> HTTP clients. Default one.\n\
|
||||
--get Use GET request method.\n\
|
||||
--head Use HEAD request method.\n\
|
||||
--options Use OPTIONS request method.\n\
|
||||
--trace Use TRACE request method.\n\
|
||||
");
|
||||
}
|
||||
|
||||
int parse_cmdline(int argc, char** argv) {
|
||||
int opt = 0;
|
||||
int opt_idx = 0;
|
||||
while ((opt=getopt_long(argc, argv, options, long_options, &opt_idx)) != EOF) {
|
||||
switch (opt) {
|
||||
case '?':
|
||||
case 'h': print_usage(); exit(1);
|
||||
case 'V': puts(VERSION); exit(1);
|
||||
case 'v': verbose = 1; break;
|
||||
case 'q': quiet = 1; break;
|
||||
case '0': http = 0; break;
|
||||
case '1': http = 1; break;
|
||||
case 'k': keepalive = 1; break;
|
||||
case 't': time = atoi(optarg); break;
|
||||
case 'c': clients = atoi(optarg); break;
|
||||
case 'p':
|
||||
{
|
||||
// host:port
|
||||
char* pos = strrchr(optarg, ':');
|
||||
proxy_host = optarg;
|
||||
if (pos == NULL) break;
|
||||
if (pos == optarg ||
|
||||
pos == optarg + strlen(optarg) - 1) {
|
||||
printf("Error option --proxy\n");
|
||||
return -2;
|
||||
}
|
||||
*pos = '\0';
|
||||
proxy_port = atoi(pos+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
printf("Missing URL\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
url = argv[optind];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void alarm_handler(int singal) {
|
||||
timerexpired = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 1) {
|
||||
print_usage();
|
||||
return 2;
|
||||
}
|
||||
|
||||
int ret = parse_cmdline(argc, argv);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("%d clients, running %d sec\n", clients, time);
|
||||
|
||||
// domain port url
|
||||
const char* req_url = "/";
|
||||
if (proxy_host) {
|
||||
strncpy(host, proxy_host, sizeof(host));
|
||||
port = proxy_port;
|
||||
} else {
|
||||
// http://host:port/path
|
||||
const char* pos1 = strstr(url, "http://");
|
||||
if (pos1 == NULL) {
|
||||
pos1 = url;
|
||||
} else {
|
||||
pos1 += strlen("http://");
|
||||
}
|
||||
const char* pos2 = strchr(pos1, '/');
|
||||
if (pos2 == NULL) {
|
||||
pos2 = url + strlen(url);
|
||||
} else {
|
||||
req_url = pos2;
|
||||
}
|
||||
int len = pos2 - pos1;
|
||||
char* server = (char*)malloc(len+1);
|
||||
memcpy(server, pos1, len);
|
||||
server[len] = '\0';
|
||||
char* pos3 = strrchr(server, ':');
|
||||
if (pos3 == NULL) {
|
||||
port = 80;
|
||||
} else {
|
||||
*pos3 = '\0';
|
||||
port = atoi(pos3+1);
|
||||
}
|
||||
strncpy(host, server, sizeof(host));
|
||||
free(server);
|
||||
}
|
||||
char Host[256];
|
||||
snprintf(Host, sizeof(Host), "Host: %s:%d\r\n", host, port);
|
||||
printf("%s", Host);
|
||||
|
||||
// test connect
|
||||
int sock = Connect(host, port);
|
||||
if (sock < 0) {
|
||||
printf("Connect failed!\n");
|
||||
return -20;
|
||||
} else {
|
||||
printf("Connect test OK!\n");
|
||||
close(sock);
|
||||
}
|
||||
|
||||
// build request
|
||||
switch (method) {
|
||||
case METHOD_GET:
|
||||
default:
|
||||
strcpy(request, "GET");
|
||||
break;
|
||||
case METHOD_HEAD:
|
||||
strcpy(request, "HEAD");
|
||||
break;
|
||||
case METHOD_OPTIONS:
|
||||
strcpy(request, "OPTIONS");
|
||||
break;
|
||||
case METHOD_TRACE:
|
||||
strcpy(request, "TRACE");
|
||||
break;
|
||||
}
|
||||
|
||||
strcat(request, " ");
|
||||
strcat(request, req_url);
|
||||
strcat(request, " ");
|
||||
if (http == 0) {
|
||||
strcat(request, "HTTP/1.0");
|
||||
} else if (http == 1) {
|
||||
strcat(request, "HTTP/1.1");
|
||||
}
|
||||
strcat(request, "\r\n");
|
||||
strcat(request, "User-Agent: webbench/1.18.3.15\r\n");
|
||||
strcat(request, Host);
|
||||
strcat(request, "Cache-Control: no-cache\r\n");
|
||||
if (keepalive) {
|
||||
strcat(request, "Connection: keep-alive\r\n");
|
||||
}
|
||||
else {
|
||||
strcat(request, "Connection: close\r\n");
|
||||
}
|
||||
strcat(request, "\r\n");
|
||||
if (!quiet) {
|
||||
printf("%s", request);
|
||||
}
|
||||
|
||||
// IPC
|
||||
if (pipe(mypipe) < 0) {
|
||||
perror("pipe");
|
||||
exit(20);
|
||||
}
|
||||
|
||||
// fork childs
|
||||
pid_t pid = 0;
|
||||
FILE* fp = NULL;
|
||||
long long succeed = 0, failed = 0, bytes = 0;
|
||||
int childs = clients;
|
||||
int i;
|
||||
for (i = 0; i < childs; ++i) {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
exit(-10);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
// child
|
||||
//printf("child[%d] start\n", getpid());
|
||||
signal(SIGALRM, alarm_handler);
|
||||
alarm(time);
|
||||
int sock = -1;
|
||||
int len = strlen(request);
|
||||
int wrbytes, rdbytes;
|
||||
while (1) {
|
||||
connect:
|
||||
if (timerexpired) break;
|
||||
if (sock == -1) {
|
||||
sock = Connect(host, port);
|
||||
}
|
||||
if (sock < 0) {
|
||||
++failed;
|
||||
continue;
|
||||
}
|
||||
int total_rdbytes = 0;
|
||||
write:
|
||||
if (timerexpired) break;
|
||||
wrbytes = write(sock, request, len);
|
||||
if (verbose) {
|
||||
printf("write %d bytes\n", wrbytes);
|
||||
}
|
||||
if (wrbytes != len) {
|
||||
++failed;
|
||||
goto close;
|
||||
}
|
||||
if (verbose) {
|
||||
printf("%s\n", request);
|
||||
}
|
||||
read:
|
||||
if (timerexpired) break;
|
||||
rdbytes = read(sock, buf, sizeof(buf));
|
||||
if (verbose) {
|
||||
printf("read %d bytes\n", rdbytes);
|
||||
}
|
||||
if (rdbytes <= 0) {
|
||||
++failed;
|
||||
goto close;
|
||||
}
|
||||
if (verbose) {
|
||||
printf("%.*s\n", rdbytes, buf);
|
||||
}
|
||||
static int s_rdbytes = 0;
|
||||
if (s_rdbytes == 0) {
|
||||
s_rdbytes = rdbytes;
|
||||
}
|
||||
bytes += rdbytes;
|
||||
total_rdbytes += rdbytes;
|
||||
if (total_rdbytes < s_rdbytes) {
|
||||
// NOTE: some http server head and body send not one packet.
|
||||
goto read;
|
||||
}
|
||||
++succeed;
|
||||
close:
|
||||
if (!keepalive) {
|
||||
close(sock);
|
||||
sock = -1;
|
||||
}
|
||||
}
|
||||
|
||||
fp = fdopen(mypipe[1], "w");
|
||||
if (fp == NULL) {
|
||||
perror("fdopen");
|
||||
return 30;
|
||||
}
|
||||
fprintf(fp, "%lld %lld %lld\n", succeed, failed, bytes);
|
||||
fclose(fp);
|
||||
//printf("child[%d] end\n", getpid());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fp = fdopen(mypipe[0], "r");
|
||||
if (fp == NULL) {
|
||||
perror("fdopen");
|
||||
return 30;
|
||||
}
|
||||
while (1) {
|
||||
long long i,j,k;
|
||||
fscanf(fp, "%lld %lld %lld", &i, &j, &k);
|
||||
succeed += i;
|
||||
failed += j;
|
||||
bytes += k;
|
||||
if (--childs==0) break;
|
||||
}
|
||||
fclose(fp);
|
||||
printf("recv %lld bytes/sec, %lld succeed, %lld failed\n",
|
||||
bytes/time,
|
||||
succeed,
|
||||
failed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user