kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

v1.c (3206B)



      1 #include <time.h>
      2 #include <xlocale.h>
      3 #include <yajl/yajl_gen.h>
      4 #include <yajl/yajl_tree.h>
      5 #include <kore/kore.h>
      6 #include <kore/http.h>
      7 #include <kore/jsonrpc.h>
      8 
      9 int	v1(struct http_request *);
     10 
     11 static int
     12 write_string(struct jsonrpc_request *req, void *ctx)
     13 {
     14 	const unsigned char *str = (unsigned char *)ctx;
     15 
     16 	return yajl_gen_string(req->gen, str, strlen((const char *)str));
     17 }
     18 
     19 static int
     20 write_string_array_params(struct jsonrpc_request *req, void *ctx)
     21 {
     22 	int status = 0;
     23 
     24 	if (!YAJL_GEN_KO(status = yajl_gen_array_open(req->gen))) {
     25 		for (size_t i = 0; i < req->params->u.array.len; i++) {
     26 			yajl_val yajl_str = req->params->u.array.values[i];
     27 			char	 *str = YAJL_GET_STRING(yajl_str);
     28 
     29 			if (YAJL_GEN_KO(status = yajl_gen_string(req->gen,
     30 			    (unsigned char *)str, strlen(str))))
     31 				break;
     32 		}
     33 		if (status == 0)
     34 			status = yajl_gen_array_close(req->gen);
     35 	}
     36 
     37 	return status;
     38 }
     39 
     40 int
     41 v1(struct http_request *http_req)
     42 {
     43 	struct jsonrpc_request	req;
     44 	int			ret;
     45 	
     46 	/* We only allow POST/PUT methods. */
     47 	if (http_req->method != HTTP_METHOD_POST &&
     48 	    http_req->method != HTTP_METHOD_PUT) {
     49 		http_response_header(http_req, "allow", "POST, PUT");
     50 		http_response(http_req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
     51 		return (KORE_RESULT_OK);
     52 	}
     53 	
     54 	/* Read JSON-RPC request. */
     55 	if ((ret = jsonrpc_read_request(http_req, &req)) != 0)
     56 		return jsonrpc_error(&req, ret, NULL);
     57 	
     58 	/* Echo command takes and gives back params. */
     59 	if (strcmp(req.method, "echo") == 0) {
     60 		if (!YAJL_IS_ARRAY(req.params)) {
     61 			jsonrpc_log(&req, LOG_ERR,
     62 			    "Echo only accepts positional params");
     63 			return jsonrpc_error(&req, JSONRPC_INVALID_PARAMS, NULL);
     64 		}
     65 		for (size_t i = 0; i < req.params->u.array.len; i++) {
     66 			yajl_val v = req.params->u.array.values[i];
     67 			if (!YAJL_IS_STRING(v)) {
     68 				jsonrpc_log(&req, -3,
     69 				    "Echo only accepts strings");
     70 				return jsonrpc_error(&req,
     71 				    JSONRPC_INVALID_PARAMS, NULL);
     72 			}
     73 		}
     74 		return jsonrpc_result(&req, write_string_array_params, NULL);
     75 	}
     76 	
     77 	/* Date command displays date and time according to parameters. */
     78 	if (strcmp(req.method, "date") == 0) {
     79 		time_t		time_value;
     80 		struct tm	time_info;
     81 		char		timestamp[33];
     82 		struct tm	*(*gettm)(const time_t *, struct tm *) =
     83 				    localtime_r;
     84 		
     85 		if (YAJL_IS_OBJECT(req.params)) {
     86 			const char	*path[] = {"local", NULL};
     87 			yajl_val	bf;
     88 
     89 			bf = yajl_tree_get(req.params, path, yajl_t_false);
     90 			if (bf != NULL)
     91 				gettm = gmtime_r;
     92 		} else if (req.params != NULL) {
     93 			jsonrpc_log(&req, LOG_ERR,
     94 			    "Date only accepts named params");
     95 			return jsonrpc_error(&req, JSONRPC_INVALID_PARAMS, NULL);
     96 		}
     97 
     98 		if ((time_value = time(NULL)) == -1)
     99 			return jsonrpc_error(&req, -2,
    100 			    "Failed to get date time");
    101 		
    102 		if (gettm(&time_value, &time_info) == NULL)
    103 			return jsonrpc_error(&req, -3,
    104 			    "Failed to get date time info");
    105 		
    106 		memset(timestamp, 0, sizeof(timestamp));
    107 		if (strftime_l(timestamp, sizeof(timestamp) - 1, "%c",
    108 		    &time_info, LC_GLOBAL_LOCALE) == 0)
    109 			return jsonrpc_error(&req, -4,
    110 			    "Failed to get printable date time");
    111 		
    112 		return jsonrpc_result(&req, write_string, timestamp);
    113 	}
    114 	
    115 	return jsonrpc_error(&req, JSONRPC_METHOD_NOT_FOUND, NULL);
    116 }