赞
踩
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <libgen.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <signal.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <jansson.h>
- #include <curl/curl.h>
- #include "log.h"
-
- #ifndef likely
- #define likely(x) __builtin_expect(!!(x), 1)
- #endif
-
- #ifndef unlikely
- #define unlikely(x) __builtin_expect(!!(x), 0)
- #endif
-
- typedef struct data_t
- {
- unsigned char *value;
- unsigned int length;
- }data_t;
-
- static volatile sig_atomic_t isterm = 0; // 结束信号
- static volatile sig_atomic_t isalarm = 0; // 时钟信号
-
- // 中断后的信号处理函数
- static void signals_handler(int sig, siginfo_t *si, void *context)
- {
- static siginfo_t empty_siginfo;
- if(!si) si = &empty_siginfo;
- switch(sig)
- {
- case SIGINT: case SIGTERM:
- isterm = sig;
- break;
- case SIGPIPE:
- break;
- case SIGALRM:
- isalarm = sig;
- break;
- default:
- break;
- }
- }
-
- // 注册信号中断
- static void signals_register()
- {
- struct sigaction act;
- struct itimerval interval;
-
- sigfillset(&act.sa_mask);
- sigdelset(&act.sa_mask, SIGINT);
- sigdelset(&act.sa_mask, SIGTERM);
- sigdelset(&act.sa_mask, SIGPIPE);
- sigdelset(&act.sa_mask, SIGALRM);
- sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
-
- act.sa_flags = SA_SIGINFO;
- act.sa_sigaction = signals_handler;
-
- interval.it_interval.tv_sec = 1;
- interval.it_interval.tv_usec = 0;
- interval.it_value.tv_sec = 1;
- interval.it_value.tv_usec = 0;
-
- sigaction(SIGINT, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGPIPE, &act, NULL);
- sigaction(SIGALRM, &act, NULL);
- setitimer(ITIMER_REAL, &interval, NULL);
- }
-
- static size_t recv_head_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
- {
- data_t *recv_head = (data_t*)userdata;
- unsigned int append = size*nmemb;
-
- recv_head->value = (unsigned char*)realloc(recv_head->value, recv_head->length+append+1);
- if(!recv_head->value)
- return -1;
-
- memcpy(recv_head->value+recv_head->length, ptr, append);
- recv_head->length += append;
- recv_head->value[recv_head->length] = 0;
-
- log_debug("recv http response head: %s", recv_head->value);
- return size*nmemb;
- }
-
- static size_t recv_body_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
- {
- data_t *recv_body = (data_t*)userdata;
- unsigned int append = size*nmemb;
-
- recv_body->value = (unsigned char*)realloc(recv_body->value, recv_body->length+append+1);
- if(!recv_body->value)
- return -1;
-
- memcpy(recv_body->value+recv_body->length, ptr, append);
- recv_body->length += append;
- recv_body->value[recv_body->length] = 0;
-
- log_debug("recv http response body: %s", recv_body->value);
- return size*nmemb;
- }
-
- static int jsonrpc_request_url(char *url)
- {
- CURL *curl = NULL;
- CURLcode rcode;
- struct curl_slist *headers = NULL;
-
- json_t *json_req = NULL;
- json_t *json_res = NULL;
- data_t send_body, recv_head, recv_body;
- memset(&send_body, 0, sizeof(data_t));
- memset(&recv_head, 0, sizeof(data_t));
- memset(&recv_body, 0, sizeof(data_t));
-
- rcode = curl_global_init(CURL_GLOBAL_ALL);
- if(rcode != CURLE_OK)
- {
- log_error("curl global init failed: %s", curl_easy_strerror(rcode));
- return -1;
- }
-
- curl = curl_easy_init();
- if(!curl)
- {
- log_error("curl easy init failed: %s", curl_easy_strerror(rcode));
- goto ErrP;
- }
-
- json_req = json_pack("{ s:s, s:s, s:s }", "jsonrpc", "2.0", "method", "jsonrpc", "id", "1");
- if(json_req == NULL)
- {
- log_error("json pack http request body failed");
- goto ErrP;
- }
-
- send_body.value = (unsigned char *)json_dumps(json_req, 0);
- send_body.length = strlen((const char *)send_body.value);
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_POST, 1L);
-
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_body.value);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, send_body.length);
-
- curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);
- curl_easy_setopt(curl, CURLOPT_USERPWD, "admin:111111");
-
- curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;");
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
-
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L);
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
-
- headers = curl_slist_append(headers, "Accept: text/json");
- headers = curl_slist_append(headers, "Content-Type: text/json; charset=UTF-8");
- headers = curl_slist_append(headers, "Connection: keep-alive");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, recv_head_callback);
- curl_easy_setopt(curl, CURLOPT_HEADERDATA, &recv_head);
-
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, recv_body_callback);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &recv_body);
-
- rcode = curl_easy_perform(curl);
- if(rcode != CURLE_OK)
- {
- log_error("curl easy perform failed: %s", curl_easy_strerror(rcode));
- goto ErrP;
- }
-
- unsigned int code = 200;
- rcode = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
- if(rcode != CURLE_OK || code != 200)
- {
- log_error("Response-Code: %d", code);
- goto ErrP;
- }
-
- unsigned char *ct;
- rcode = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
- if(rcode == CURLE_OK)
- {
- log_debug("Content-Type: %s", ct);
- }
-
- json_res = json_loadb((const char *)(recv_body.value), recv_body.length, 0, NULL);
- if(json_res == NULL)
- {
- log_error("json unpack http response body failed");
- goto ErrP;
- }
-
- json_t *json_result = json_object_get(json_res, "result");
- char *buf_result = (char*)json_string_value(json_result);
- if(!json_result || !buf_result || strncasecmp(buf_result, "succeed", 7))
- {
- log_error("jsonrpc request url result failed");
- goto ErrP;
- }
- log_info("jsonrpc request url result succeed");
-
- if(send_body.value) free(send_body.value);
- if(json_req) json_decref(json_req);
-
- if(recv_head.value) free(recv_head.value);
- if(recv_body.value) free(recv_body.value);
- if(json_res) json_decref(json_res);
-
- if(headers) curl_slist_free_all(headers);
- if(curl) curl_easy_cleanup(curl);
- curl_global_cleanup();
- return 0;
- ErrP:
- if(send_body.value) free(send_body.value);
- if(json_req) json_decref(json_req);
-
- if(recv_head.value) free(recv_head.value);
- if(recv_body.value) free(recv_body.value);
- if(json_res) json_decref(json_res);
-
- if(headers) curl_slist_free_all(headers);
- if(curl) curl_easy_cleanup(curl);
- curl_global_cleanup();
- return -1;
- }
-
- int main(int argc, char *argv[])
- {
- int ret = 0;
-
- log_open(basename(argv[0]), 1);
-
- #if 0
- if(argc != 2)
- {
- log_error("Usage: %s URL", argv[0]);
- return -1;
- }
- #endif
-
- signals_register();
- while(!isterm)
- {
- if(unlikely(isterm))
- {
- log_info("term signal: %d", isterm);
- isterm = 0;
- }
-
- if(likely(isalarm))
- {
- log_info("alarm signal: %d", isalarm);
- isalarm = 0;
-
- ret = jsonrpc_request_url(argv[1] ? argv[1] : "http://127.0.0.1:1990/jsonrpc.php");
- if(ret != 0)
- {
- log_error("jsonrpc request url failed: %d", ret);
- break;
- }
-
- }
-
- sleep(-1);
- }
-
- log_close();
- return ret;
- }
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <libgen.h>
- #include <signal.h>
- #include <event.h>
- #include <evhttp.h>
- #include <event2/event.h>
- #include <event2/thread.h>
- #include <event2/buffer.h>
- #include <event2/bufferevent.h>
- #include <event2/util.h>
- #include <event2/dns.h>
- #include <event2/http.h>
- #include <event2/rpc.h>
- #include <jansson.h>
- #include "log.h"
-
- static void jsonrpc_request_cb(struct evhttp_request *req, void *arg)
- {
- struct evkeyvalq *headers = NULL;
- struct evkeyval *header = NULL;
-
- struct evbuffer *req_evb = NULL;
- struct evbuffer *res_evb = NULL;
-
- int ret = 0;
- int req_len = 0;
- char *req_buf = NULL;
- char *res_buf = NULL;
- json_t *req_json = NULL;
- json_t *res_json = NULL;
-
- if(evhttp_request_get_command(req) != EVHTTP_REQ_POST)
- {
- log_error("jsonrpc_request_cb EVHTTP_REQ_POST failed");
- goto EndP;
- }
-
- headers = evhttp_request_get_input_headers(req);
- for (header = headers->tqh_first; header; header = header->next.tqe_next)
- log_debug("%s: %s", header->key, header->value);
-
- req_evb = evhttp_request_get_input_buffer(req);
- req_len = evbuffer_get_length(req_evb);
-
- req_buf = (char*)malloc(req_len+1);
- if(!req_buf)
- {
- log_error("malloc failed");
- goto EndP;
- }
- memset(req_buf, 0, req_len+1);
-
- ret = evbuffer_remove(req_evb, req_buf, req_len);
- if(ret != req_len)
- {
- log_error("evbuffer_copyout failed");
- goto EndP;
- }
- req_buf[req_len] = 0;
- log_info("Request: %s", req_buf);
-
- req_json = json_loadb((const char *)req_buf, req_len, 0, NULL);
- if(!req_json)
- {
- log_error("jsonrpc_request_cb json_loadb failed: %s", strerror(errno));
- goto EndP;
- }
-
- json_t *method_json = json_object_get(req_json, "method");
- char *method_buf = (char*)json_string_value(method_json);
- if(!method_json || !method_buf || strncasecmp(method_buf, "jsonrpc", 7))
- {
- log_error("jsonrpc_request_cb method failed");
- goto EndP;
- }
-
- evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/json; charset=UTF-8");
- evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "keep-alive");
-
- res_json = json_pack("{ s:s, s:s, s:s }", "jsonrpc", "2.0", "result", "succeed", "id", "1");
- if(!res_json)
- {
- log_error("jsonrpc_request_cb json_pack failed: %s", strerror(errno));
- goto EndP;
- }
-
- res_buf = json_dumps(res_json, 0);
- if(!res_buf)
- {
- log_error("jsonrpc_request_cb json_dunmps failed: %s", strerror(errno));
- goto EndP;
- }
-
- res_evb = evbuffer_new();
- if(!res_evb)
- {
- log_error("jsonrpc_request_cb evbuffer_new failed: %s", strerror(errno));
- goto EndP;
- }
- evbuffer_add_printf(res_evb, "%s", res_buf);
- log_info("Response: %s", res_buf);
-
- evhttp_send_reply(req, HTTP_OK, "OK", res_evb);
- if(res_evb) evbuffer_free(res_evb);
- if(res_buf) free(res_buf);
- if(res_json) json_decref(res_json);
- if(req_json) json_decref(req_json);
- if(req_buf) free(req_buf);
- return;
- EndP:
- evhttp_send_error(req, HTTP_BADMETHOD, "BAD METHOD");
- if(res_evb) evbuffer_free(res_evb);
- if(res_buf) free(res_buf);
- if(res_json) json_decref(res_json);
- if(req_json) json_decref(req_json);
- if(req_buf) free(req_buf);
- return;
- }
-
- static void default_request_cb(struct evhttp_request *req, void *arg)
- {
- evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/plain; charset=UTF-8");
- evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "close");
- evhttp_send_error(req, HTTP_NOTFOUND, "NOT FOUND");
- }
-
- static void term_evsignal_cb(evutil_socket_t fd, short event, void *arg)
- {
- struct event_base *base = arg;
- struct timeval tv = { 1, 0 };
-
- log_info("term signal: %d", SIGINT);
- event_base_loopexit(base, &tv);
- }
-
- static void alrm_evsignal_cb(evutil_socket_t fd, short event, void *arg)
- {
- //struct event *signal_alrm = arg;
-
- log_info("alrm signal: %d", SIGALRM);
- //event_del(signal_alrm);
- }
-
- static void cycle_timout_cb(evutil_socket_t fd, short event, void *arg)
- {
- struct timeval tv = {1, 0};
- log_info("cycle timeout callback");
- event_add(*(struct event**)arg, &tv);
- }
-
- int main(int argc, char *argv[])
- {
- int ret = 0;
- char *server_ip = "0.0.0.0";
- unsigned short server_port = 1990;
-
- struct event_base *base = NULL;
- struct evhttp *http = NULL;
- struct evhttp_bound_socket *handle = NULL;
- evutil_socket_t server_fd = -1;
- struct event *timeout = NULL;
- struct event *signal_int = NULL;
- struct event signal_alrm;
-
- log_open(basename(argv[0]), 1);
-
- base = event_base_new();
- if(!base)
- {
- log_error("event_base_new failed: %s", strerror(errno));
- goto ErrP;
- }
-
- struct timeval tv = {1, 0};
- timeout = event_new(base, -1, 0, cycle_timout_cb, (void*)&timeout);
- if(!timeout)
- {
- log_error("evtimer_new failed: %s", strerror(errno));
- goto ErrP;
- }
- event_add(timeout, &tv);
-
- signal_int = event_new(base, SIGINT, EV_SIGNAL|EV_PERSIST, term_evsignal_cb, (void *)base);
- if(!signal_int)
- {
- log_error("evsignal_new failed: %s", strerror(errno));
- goto ErrP;
- }
- event_add(signal_int, NULL);
-
- ret = event_assign(&signal_alrm, base, SIGALRM, EV_SIGNAL|EV_PERSIST, alrm_evsignal_cb, (void *)&signal_alrm);
- if(ret != 0)
- {
- log_error("evsignal_assign failed: %s", strerror(errno));
- goto ErrP;
- }
- event_add(&signal_alrm, NULL);
-
- http = evhttp_new(base);
- if(!http)
- {
- log_error("evhttp_new failed: %s", strerror(errno));
- goto ErrP;
- }
-
- handle = evhttp_bind_socket_with_handle(http, server_ip, server_port);
- if(!handle)
- {
- log_error("evhttp_bind_socket_with_handle failed: %s", strerror(errno));
- goto ErrP;
- }
- server_fd = evhttp_bound_socket_get_fd(handle);
- log_info("evhttp_bind_socket_with_handle succeed: %d", server_fd);
-
- evhttp_set_timeout(http, 120);
- evhttp_set_cb(http, "/jsonrpc.php", jsonrpc_request_cb, &base);
- evhttp_set_gencb(http, default_request_cb, &base);
-
- event_base_dispatch(base);
-
- if(http) evhttp_free(http);
- if(signal_int) event_free(signal_int);
- if(timeout) event_free(timeout);
- if(base) event_base_free(base);
- log_close();
- return 0;
- ErrP:
- if(http) evhttp_free(http);
- if(signal_int) event_free(signal_int);
- if(timeout) event_free(timeout);
- if(base) event_base_free(base);
- log_close();
- return -1;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。