int http_hdr_req_cookies_parse(HTTP_HDR_REQ *hh) { /* data format: "name1=value1; name2=value2; name3=value3" */ const char *myname = "http_hdr_req_cookies_parse"; const HTTP_HDR_ENTRY *entry; ACL_ARGV *argv; const char *ptr; ACL_ITER iter; if (hh == NULL) acl_msg_fatal("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); if ((hh->flag & HTTP_HDR_REQ_FLAG_PARSE_COOKIE) == 0) return 0; entry = http_hdr_entry((HTTP_HDR *) hh, "Cookie"); if (entry == NULL) return 0; if (hh->cookies_table == NULL) hh->cookies_table = acl_htable_create(__http_hdr_max_cookies, ACL_HTABLE_FLAG_KEY_REUSE); if (hh->cookies_table == NULL) acl_msg_fatal("%s, %s(%d): htable create error(%s)", __FILE__, myname, __LINE__, acl_last_serror()); /* 分隔数据段 */ argv = acl_argv_split(entry->value, ";"); acl_foreach(iter, argv) { ptr = (const char*) iter.data; __add_cookie_item(hh->cookies_table, ptr); }
int smtp_rcpt(SMTP_CLIENT *client, const char *to) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "RCPT TO: <%s>\r\n", to); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send rcpt error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets rcpt's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): rcpt's reply error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
static void proctl_monitor_loop(ACL_VSTREAM *sstream) { const char *myname = "proctl_monitor_loop"; ACL_VSTREAM *client; int n; char buf[1024]; ACL_ARGV *cmd_argv; while (1) { client = acl_vstream_accept(sstream, NULL, 0); if (client == NULL) continue; n = acl_vstream_gets_nonl(client, buf, sizeof(buf)); if (n == ACL_VSTREAM_EOF) continue; acl_debug(ACL_DEBUG_PROCTL, 2) ("%s(%d): get buf(%s)", myname, __LINE__, buf); cmd_argv = acl_argv_split(buf, "|"); if (cmd_argv) proctl_monitor_main(client, cmd_argv->argc, cmd_argv->argv); else usage(client); acl_vstream_close(client); } }
bool queue_manager::parse_path(const char* path, string* home, string* queueName, string* queueSub) { if (path == NULL || *path == 0) { logger_error("path invalid!"); return false; } /* WINDOWS 支持 '/' 和 '\\' 两种分隔符 */ // 数据格式: /home/queueName/queueSub ACL_ARGV *argv = acl_argv_split(path, "/\\"); if (argv->argc < 3) { logger_error("path(%s) invalid", path); acl_argv_free(argv); return false; } // 取得home home->clear(); // 如果第一个字符为 PATH_SEP 则需要补齐 if (*path == PATH_SEP) home->push_back(PATH_SEP); *home += argv->argv[argv->argc - 3]; // 取得队列名 *queueName = argv->argv[argv->argc - 2]; // 取得队列子目录名 *queueSub = argv->argv[argv->argc - 1]; acl_argv_free(argv); return true; }
int smtp_quit(SMTP_CLIENT *client) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "QUIT\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send quit cmd error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets quit's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 221) { acl_msg_error("%s(%d): quit's reply: %d", __FUNCTION__, __LINE__, client->smtp_code); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
void connect_manager::set_service_list(const char* addr_list, int count, int conn_timeout, int rw_timeout) { if (addr_list == NULL || *addr_list == 0) { logger("addr_list null"); return; } // 创建连接池服务集群 char* buf = acl_mystrdup(addr_list); char* addrs = acl_mystr_trim(buf); ACL_ARGV* tokens = acl_argv_split(addrs, ";,"); ACL_ITER iter; acl::string addr; acl_foreach(iter, tokens) { const char* ptr = (const char*) iter.data; int max = check_addr(ptr, addr, count); if (max < 0) { logger_error("invalid server addr: %s", addr.c_str()); continue; } (void) set(addr.c_str(), max, conn_timeout, rw_timeout); logger("add one service: %s, max connect: %d", addr.c_str(), max); } acl_argv_free(tokens); acl_myfree(buf); }
int smtp_data_end(SMTP_CLIENT *client) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "\r\n.\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send mail eof error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets mail eof's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): send mail error(%d), line: %s", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
void session::deserialize(string& buf, std::map<string, session_string>& attrs) { attrs_clear(attrs); // 先重置 session 前一次查询状态 ACL_ARGV* tokens = acl_argv_split(buf.c_str(), "\t"); ACL_ITER iter; acl_foreach(iter, tokens) { char* ptr = (char*) iter.data; // 重复使用原来的内存区,因为 tokens 中已经存储了中间结果数据 buf.clear(); if (unescape(ptr, strlen(ptr), buf) == false) { logger_error("unescape error"); continue; } ptr = buf.c_str(); // 因为 acl::string 肯定能保证缓冲区数据的尾部有 \0,所以在用 // strchr 时不必须担心越界问题,但 std::string 并不保证这样 char* p1 = strchr(ptr, 1); if (p1 == NULL || *(p1 + 1) == 0) continue; *p1++ = 0; //std::map<string, session_string>::iterator it = attrs.find(ptr); size_t len = buf.length() - (p1 - buf.c_str()); session_string ss(len); ss.copy(p1, len); ss.todo_ = TODO_SET; attrs.insert(std::make_pair(string(ptr), ss)); }
void session::deserialize(string& buf, std::map<string, VBUF*>& attrs) { attrs_clear(attrs); // 先重置 session 前一次查询状态 ACL_ARGV* tokens = acl_argv_split(buf.c_str(), "\t"); ACL_ITER iter; acl_foreach(iter, tokens) { char* ptr = (char*) iter.data; // 重复使用原来的内存区,因为 tokens 中已经存储了中间结果数据 buf.clear(); if (unescape(ptr, strlen(ptr), buf) == false) { logger_error("unescape error"); continue; } ptr = buf.c_str(); // 因为 acl::string 肯定能保证缓冲区数据的尾部有 \0,所以在用 // strchr 时不必须担心越界问题,但 std::string 并不保证这样 char* p1 = strchr(ptr, 1); if (p1 == NULL || *(p1 + 1) == 0) continue; *p1++ = 0; std::map<string, VBUF*>::iterator it = attrs.find(ptr); // xxx: 以防有重复的属性 if (it != attrs.end()) vbuf_free(it->second); // 将从后端取得数据属性都设为 TODO_SET attrs[ptr] = vbuf_new(p1, buf.length() - (p1 - buf.c_str()), TODO_SET); }
// 分析一个服务器地址,格式:IP:PORT[:MAX_CONN] // 返回值 < 0 表示非法的地址 static int check_addr(const char* addr, string& buf, size_t default_count) { // 数据格式:IP:PORT[:CONNECT_COUNT] ACL_ARGV* tokens = acl_argv_split(addr, ":|"); if (tokens->argc < 2) { logger_error("invalid addr: %s", addr); acl_argv_free(tokens); return -1; } int port = atoi(tokens->argv[1]); if (port <= 0 || port >= 65535) { logger_error("invalid addr: %s, port: %d", addr, port); acl_argv_free(tokens); return -1; } buf.format("%s:%d", tokens->argv[0], port); int conn_max; if (tokens->argc >= 3) conn_max = atoi(tokens->argv[2]); else conn_max = (int) default_count; if (conn_max < 0) conn_max = (int) default_count; acl_argv_free(tokens); return conn_max; }
bool master_udp::run_alone(const char* addrs, const char* path /* = NULL */, unsigned int count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; __count_limit = count; acl_assert(addrs && *addrs); #ifdef ACL_WINDOWS acl_init(); #endif ACL_EVENT* eventp = acl_event_new_select(1, 0); set_event(eventp); // 设置基类的事件句柄 ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_bind(addr, 0); if (sstream == NULL) { logger_error("bind %s error %s", addr, last_serror()); close_sstreams(); acl_event_free(eventp); acl_argv_free(tokens); return false; } acl_event_enable_read(eventp, sstream, 0, read_callback, sstream); socket_stream* ss = NEW socket_stream(); if (ss->open(sstream) == false) logger_fatal("open stream error!"); sstream->context = ss; sstreams_.push_back(ss); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); while (!__stop) acl_event_loop(eventp); service_exit(NULL, NULL); // 必须在调用 acl_event_free 前调用 close_sstreams,因为在关闭 // 网络流对象时依然有对 ACL_EVENT 引擎的使用 close_sstreams(); acl_event_free(eventp); return true; }
int smtp_data(SMTP_CLIENT *client) { ACL_ARGV *tokens; int ret; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "DATA\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send data error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets data's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 354) { acl_msg_error("%s(%d): data denied, error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
bool master_aio::run_alone(const char* addrs, const char* path /* = NULL */, aio_handle_type ht /* = ENGINE_SELECT */) { acl_assert(__handle == NULL); daemon_mode_ = false; #ifdef WIN32 acl_init(); #endif std::vector<aio_listen_stream*> sstreams; ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; // 初始化配置参数 conf_.load(path); __handle = NEW aio_handle(ht); ACL_AIO* aio = __handle->get_handle(); acl_assert(aio); ACL_EVENT* eventp = acl_aio_event(aio); set_event(eventp); // 设置基类的事件句柄 acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; aio_listen_stream* sstream = NEW aio_listen_stream(__handle); // 监听指定的地址 if (sstream->open(addr) == false) { logger_error("listen %s error: %s", addr, last_serror()); close_all_listener(sstreams); // XXX: 为了保证能关闭监听流,应在此处再 check 一下 __handle->check(); acl_argv_free(tokens); return (false); } sstream->add_accept_callback(this); } acl_argv_free(tokens); service_pre_jail(NULL); service_init(NULL); while (true) { // 如果返回 false 则表示不再继续,需要退出 if (__handle->check() == false) { logger("aio_server stop now ..."); break; } } close_all_listener(sstreams); __handle->check(); service_exit(NULL); return true; }
static void parse_env(void) { char *ptr, *name; ACL_ARGV *env_argv; ACL_ITER iter; ptr = getenv("SERVICE_ENV"); if (ptr == NULL) return; env_argv = acl_argv_split(ptr, ",\t "); if (env_argv == NULL) return; acl_foreach(iter, env_argv) { name = (char*) iter.data; ptr = strchr(name, ':'); if (ptr == NULL) continue; *ptr++ = 0; if (*ptr == 0) continue; #define STREQ !strcasecmp if (STREQ(name, "use_slice")) { if (STREQ(ptr, "true")) __use_slice = 1; else __use_slice = 0; } else if (STREQ(name, "slice_base")) { __slice_base = atoi(ptr); if (__slice_base <= 0) __slice_base = 8; } else if (STREQ(name, "nslice")) { __nslice = atoi(ptr); if (__nslice <= 0) __nslice = 1024; } else if (STREQ(name, "nalloc_gc")) { __nalloc_gc = atoi(ptr); if (__nalloc_gc <= 0) __nalloc_gc = 100000; } else if (STREQ(name, "slice_gc")) { if (STREQ(ptr, "gc1")) __slice_gc = ACL_SLICE_FLAG_GC1; else if (STREQ(ptr, "gc3")) __slice_gc = ACL_SLICE_FLAG_GC3; else __slice_gc = ACL_SLICE_FLAG_GC2; } else if (STREQ(name, "rtgc_off")) { if (STREQ(ptr, "true")) __rtgc_off = 1; else __rtgc_off = 0; } }
void service_set_dns(SERVICE *service, ACL_AIO *aio, const char *dns_list, int dns_lookup_timeout, int dns_cache_limit, const char *hosts_list) { const char *myname = "service_set_dns"; ACL_ARGV *argv; ACL_ITER iter; /* 创建DNS域名查询对象:外挂式查询或非阻塞式查询 */ if (!dns_list || !strcmp(dns_list, "")) { int nthreads = 100, idle = 60; /* 创建外挂式DNS查询对象 */ service->dns_server = dns_server_create(aio, 300); service->dns_table = acl_htable_create(100, 0); /* 创建半驻留线程池对象 */ service->wq = acl_workq_create(nthreads, idle, NULL, NULL); return; } /* 采用直接发送DNS协议方式进行查询的对象 */ argv = acl_argv_split(dns_list, ",; \t"); service->dns_handle = acl_dns_create(aio, dns_lookup_timeout); if (dns_cache_limit > 0) acl_dns_open_cache(service->dns_handle, dns_cache_limit); /* 添加DNS服务器地址 */ acl_foreach(iter, argv) { char *addr = (char*) iter.data; char *ptr1 = strchr(addr, ':'), *ptr2; int port, netmask = 24; if (ptr1) { *ptr1++ = 0; ptr2 = strchr(ptr1, ':'); if (ptr2) { *ptr2++ = 0; netmask = atoi(ptr2); if (netmask <= 0 || netmask >= 32) netmask = 24; } port = atoi(ptr1); if (port <= 0 || port >= 65535) port = 53; } else port = 53; acl_msg_info("%s(%d): add dns addr (%s:%d)", myname, __LINE__, addr, port); acl_dns_add_dns(service->dns_handle, addr, port, netmask); }
bool master_proc::run_alone(const char* addrs, const char* path /* = NULL */, int count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; __count_limit = count; acl_assert(addrs && *addrs); #ifdef ACL_WINDOWS acl_cpp_init(); #endif ACL_EVENT* eventp = acl_event_new_select(1, 0); set_event(eventp); // 调用基类方法设置事件引擎句柄 std::vector<ACL_VSTREAM*> sstreams; ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_listen(addr, 128); if (sstream == NULL) { logger_error("listen %s error %s", addr, last_serror()); close_all_listener(sstreams); acl_argv_free(tokens); return false; } service_on_listen(sstream); acl_event_enable_listen(eventp, sstream, 0, listen_callback, sstream); sstreams.push_back(sstream); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); while (!__stop) acl_event_loop(eventp); close_all_listener(sstreams); acl_event_free(eventp); service_exit(NULL, NULL); return true; }
int smtp_ehlo(SMTP_CLIENT *client, const char *ehlo) { int ret; char *ptr; ACL_ARGV *tokens; client->buf[0] = 0; client->smtp_code = 0; ret = acl_vstream_fprintf(client->conn, "EHLO %s\r\n", ehlo); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): set EHLO error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } while (1) { ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): get EHLO's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } else if (ret < 3) { acl_msg_warn("%s(%d): EHLO's reply(%s) tool short", __FUNCTION__, __LINE__, client->buf); continue; } if (strncmp(client->buf, "250", 3) != 0) { ret = client->buf[3]; client->buf[3] = 0; client->smtp_code = atoi(client->buf); client->buf[3] = ret; acl_msg_error("%s(%d): EHLO's reply(%s) code(%d) error", __FUNCTION__, __LINE__, client->buf, ret); return -1; } else client->smtp_code = 250; if (ret == 3) break; ptr = client->buf + 4; tokens = acl_argv_split(ptr, " ="); smtp_ehlo_flag(client, tokens); acl_argv_free(tokens); if (client->buf[3] == ' ') break; } return 0; }
hstable::hstable(int id, const char* dbn, const char* tbl, const char* idx, const char* flds) { id_ = id; dbn_ = acl_mystrdup(dbn); tbl_ = acl_mystrdup(tbl); idx_ = acl_mystrdup(idx); flds_ = acl_mystrdup(flds); ACL_ARGV *tokens = acl_argv_split(flds, ",; \t"); nfld_ = tokens->argc; acl_argv_free(tokens); values_ = (char**) acl_mycalloc(nfld_, sizeof(char*)); }
int main(void) { char *src = acl_mystrdup("hello \tworld! you're welcome to China!"); char *ptr, *src_saved; ACL_VSTRING* buf; const char* s = "hello"; unsigned int n1 = (unsigned int) -1; unsigned long n2 = (unsigned long) -1; unsigned long long n3 = (unsigned long long) -1; const char *str2 = "hello world, you're welcome!"; ACL_ARGV *tokens = acl_argv_split(str2, " \t,'!"); ACL_ITER iter; printf("----------------------------------------------\r\n"); acl_foreach(iter, tokens) printf("tokens[%d]: %s\r\n", iter.i, (const char*) iter.data); printf("total: %d\r\n", iter.size); acl_argv_free(tokens); printf("----------------------------------------------\r\n"); src_saved = src; printf("src: %s\r\n", src); while ((ptr = acl_mystrtok(&src, " \t!'")) != NULL) { printf("--------------------------------------\r\n"); printf("ptr: |%s|\r\n", ptr); printf("src: |%s|\r\n", src); printf("src_saved: |%s|\r\n", src_saved); } acl_myfree(src_saved); printf("----------------------------------------------\r\n"); buf = acl_vstring_alloc(1); acl_vstring_sprintf(buf, "%*lu, s: %s, n1: %20u, n2: %20lu, n3: %20llu\n", (int) sizeof(unsigned long) * 4, (unsigned long) getpid(), s, n1, n2, n3); printf("buf: %s\r\n", acl_vstring_str(buf)); acl_vstring_free(buf); printf("Enter any key to continue ...\r\n"); getchar(); test_quote_split(); return 0; }
CNetOption& CNetOption::SetRecipients(const char* s) { if (s == NULL || *s == 0) return *this; ACL_ARGV* tokens = acl_argv_split(s, ",;,; \t\r\n"); ACL_ITER iter; acl::string buf; acl_foreach(iter, tokens) { if (iter.i > 0) buf << ";\r\n"; buf << (char*) iter.data; } acl_argv_free(tokens); m_recipients = buf.c_str(); return *this; }
void url_coder::decode(const char* str) { ACL_ARGV* tokens = acl_argv_split(str, "&"); ACL_ITER iter; acl_foreach(iter, tokens) { char* name = (char*) iter.data; char* value = strchr(name, '='); if (value == NULL || *(value + 1) == 0) continue; *value++ = 0; name = acl_url_decode(name); value = acl_url_decode(value); URL_NV* param = (URL_NV*) acl_mymalloc(sizeof(URL_NV)); param->name = name; param->value = value; params_.push_back(param); }
bool queue_manager::parse_filePath(const char* filePath, string* home, string* queueName, string* queueSub, string* partName, string* extName) { if (filePath == NULL || *filePath == 0) { logger_error("filePath invalid!"); return false; } // 格式为: /home/queue_name/queue_sub_node/file_name.file_ext ACL_ARGV *argv = acl_argv_split(filePath, "/\\"); if (argv->argc < 4) { logger_error("filePath(%s) invalid", filePath); acl_argv_free(argv); return false; } home->clear(); // 如果第一个字符为 PATH_SEP 则需要补齐 if (*filePath == PATH_SEP) home->push_back(PATH_SEP); // 仅存储根路径部分 for (int i = 0; i < argv->argc - 3; i++) { if (i > 0 && home->length() > 0) (*home) += PATH_SEP; (*home) += argv->argv[i]; } // 取得队列名 *queueName = argv->argv[argv->argc - 3]; *queueSub = argv->argv[argv->argc - 2]; // 继续分析文件名部分 bool ret = parse_fileName(argv->argv[argv->argc - 1], partName, extName); acl_argv_free(argv); return ret; }
int http_hdr_req_cookies_parse(HTTP_HDR_REQ *hh) { /* data format: "name1=value1; name2=value2; name3=value3" */ const char *myname = "http_hdr_req_cookies_parse"; const HTTP_HDR_ENTRY *entry; ACL_ARGV *argv; const char *ptr; ACL_ITER iter; if (hh == NULL) acl_msg_fatal("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); if ((hh->flag & HTTP_HDR_REQ_FLAG_PARSE_COOKIE) == 0) return 0; entry = http_hdr_entry((HTTP_HDR *) hh, "Cookie"); if (entry == NULL) return 0; /* bugfix: 在创建哈希表时此处不应设置 ACL_HTABLE_FLAG_KEY_REUSE 标志位, * 如果设置了此标志,则在 __add_cookie_item 中调用 acl_htable_enter 时, * 会将 name 值的内存交给 htable,但随后在宏 RETURN 时却调用了释放数组 * 的函数 acl_argv_free(argv),将 name 所属的数组内存一起给释放了 * ---zsx, 2014.5.13 */ if (hh->cookies_table == NULL) #if 0 hh->cookies_table = acl_htable_create(__http_hdr_max_cookies, ACL_HTABLE_FLAG_KEY_REUSE); #else hh->cookies_table = acl_htable_create(__http_hdr_max_cookies, 0); #endif if (hh->cookies_table == NULL) acl_msg_fatal("%s, %s(%d): htable create error(%s)", __FILE__, myname, __LINE__, acl_last_serror()); /* 分隔数据段 */ argv = acl_argv_split(entry->value, ";"); acl_foreach(iter, argv) { ptr = (const char*) iter.data; if (ptr && *ptr) __add_cookie_item(hh->cookies_table, ptr); }
int http_hdr_res_status_parse(HTTP_HDR_RES *hh, const char *dbuf) { char myname[] = "http_hdr_res_status_parse"; ACL_ARGV *status_argv; char *ptr; if (hh == NULL || dbuf == NULL) { acl_msg_error("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); return (-1); } /* data: HTTP/1.1 XXX info */ status_argv = acl_argv_split(dbuf, "\t "); if (status_argv->argc < 2) { acl_msg_error("%s, %s(%d): invalid reply status line=%s", __FILE__, myname, __LINE__, dbuf); acl_argv_free(status_argv); return (-1); } ptr = acl_argv_index(status_argv, 0); if (http_hdr_parse_version(&hh->hdr, ptr) < 0) { acl_argv_free(status_argv); return (-1); } ptr = acl_argv_index(status_argv, 1); if (ptr == NULL) acl_msg_fatal("%s, %s(%d): null value, idx=1, argc=%d", __FILE__, myname, __LINE__, status_argv->argc); hh->reply_status = atoi(ptr); if (hh->reply_status < 0) { acl_msg_error("%s, %s(%d): invalid status(%d)", __FILE__, myname, __LINE__, hh->reply_status); acl_argv_free(status_argv); return (-1); } acl_argv_free(status_argv); return (0); }
unsigned beanstalk::beanstalk_watch(const char* tube) { if (conn_.format("watch %s\r\n", tube) == -1) { logger_error("'watch %s' failed: %s", tube, last_serror()); errbuf_ = "watch"; return 0; } string line(128); if (conn_.gets(line) == false) { logger_error("'watch %s' error(%s): reply ailed", last_serror(), tube); errbuf_ = "watch"; return 0; } ACL_ARGV* tokens = acl_argv_split(line.c_str(), "\t "); if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "WATCHING")) { logger_error("'watch %s' error: %s", tube, line.c_str()); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return 0; } unsigned n = (unsigned) atoi(tokens->argv[1]); acl_argv_free(tokens); // 如果服务器返回所关注的队列数为 0,肯定是出错了,因为至少还有一个 // 缺省队列:default,所以此时需要关闭连接,以尽量消除与本连接相关 // 的错误,下一个命令会自动进行重连操作以恢复操作过程 if (n == 0) { logger_error("'watch %s' error(%s), tube watched is 0", line.c_str(), tube); errbuf_ = line.c_str(); close(); } return n; }
int acl_putenv(char *str) { #ifdef ACL_WINDOWS const char *myname = "acl_putenv"; ACL_ARGV *argv = acl_argv_split(str, "="); if (argv->argc != 2) { acl_msg_error("%s(%d): input(%s) invalid", myname, __LINE__, str); return (-1); } if (!SetEnvironmentVariable(argv->argv[0], argv->argv[1])) { acl_msg_error("%s(%d): putenv(%s, %s) error(%s)", myname, __LINE__, argv->argv[0], argv->argv[1], acl_last_serror()); return (-1); } return (0); #else return (putenv(str)); #endif }
ACL_TOKEN *acl_token_tree_create2(const char *s, const char *sep) { const char *myname = "acl_token_tree_create"; ACL_ARGV *argv; ACL_ITER iter; unsigned int flag; ACL_TOKEN *token_tree; const ACL_TOKEN *token; ACL_VSTRING *buf; token_tree = acl_token_new(); if (s == NULL || *s == 0) return (token_tree); buf = acl_vstring_alloc(256); argv = acl_argv_split(s, sep); acl_foreach(iter, argv) { char *word = (char*) iter.ptr; char *ptr = strchr(word, '|'); flag = ACL_TOKEN_F_STOP; if (ptr) { *ptr++ = 0; if (*ptr == 'D' || *ptr == 'd') flag |= ACL_TOKEN_F_DENY; if (*ptr == 'P' || *ptr == 'p') flag |= ACL_TOKEN_F_PASS; } token = acl_token_tree_add(token_tree, word, flag, NULL); if (token == NULL) { acl_msg_info("%s(%d): word(%s) discard", myname, __LINE__, word); } else { ACL_VSTRING_RESET(buf); acl_token_name(token, buf); /* acl_msg_info("%s(%d): add word(%s) ok, token's name(%s)", myname, __LINE__, word, STR(buf)); */ } }
// value 格式:xxx=xxx; domain=xxx; expires=xxx; path=xxx bool HttpCookie::setCookie(const char* value) { if (value == NULL || *value == 0) return false; ACL_ARGV* tokens = acl_argv_split(value, ";"); acl_assert(tokens->argc > 0); HTTP_PARAM param; // 从第一个 name=value 字段中取得 cookie 名及 cookie 值 if (splitNameValue(tokens->argv[0], ¶m) == false) { acl_argv_free(tokens); return false; } // name 肯定非 "\0",而 value 可以为 "\0" name_ = dbuf_->dbuf_strdup(param.name); value_ = dbuf_->dbuf_strdup(param.value); for (int i = 1; i < tokens->argc; i++) { if (splitNameValue(tokens->argv[i], ¶m) == false) continue; if (*(param.value) == 0) continue; if (strcasecmp(param.name, "domain") == 0) setDomain(param.value); else if (strcasecmp(param.name, "expires") == 0) setExpires(param.value); else if (strcasecmp(param.name, "path") == 0) setPath(param.value); else add(param.name, param.value); } acl_argv_free(tokens); return true; }
const std::vector<HttpCookie*>& HttpServletRequest::getCookies(void) const { if (cookies_inited_) return cookies_; // 设置标记表明已经分析过cookie了,以便于下次重复调用时节省时间 const_cast<HttpServletRequest*>(this)->cookies_inited_ = true; if (cgi_mode_) { const char* ptr = acl_getenv("HTTP_COOKIE"); if (ptr == NULL || *ptr == 0) return cookies_; ACL_ARGV* argv = acl_argv_split(ptr, ";"); ACL_ITER iter; acl_foreach(iter, argv) { add_cookie(const_cast<HttpServletRequest*> (this)->cookies_, (char*) iter.data); } acl_argv_free(argv); return cookies_; }
int smtp_mail(SMTP_CLIENT *client, const char *from) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; /* 发送 mail from 信息 */ ret = acl_vstream_fprintf(client->conn, "MAIL FROM: <%s>\r\n", from); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send mail from error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } /* 读取响应信息 */ ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets mail from's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return (-1); } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): mail from error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }