Statistics
| Branch: | Tag: | Revision:

mongoose / examples / api_server / api_server.c @ eaef5bd1

History | View | Annotate | Download (3.02 KB)

1
/*
2
 * Copyright (c) 2014 Cesanta Software Limited
3
 * All rights reserved
4
 */
5

    
6
#include "db_plugin.h"
7

    
8
static const char *s_http_port = "8000";
9
static struct mg_serve_http_opts s_http_server_opts;
10
static int s_sig_num = 0;
11
static void *s_db_handle = NULL;
12
static const char *s_db_path = "api_server.db";
13
static const struct mg_str s_get_method = MG_MK_STR("GET");
14
static const struct mg_str s_put_method = MG_MK_STR("PUT");
15
static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
16

    
17
static void signal_handler(int sig_num) {
18
  signal(sig_num, signal_handler);
19
  s_sig_num = sig_num;
20
}
21

    
22
static int has_prefix(const struct mg_str *uri, const struct mg_str *prefix) {
23
  return uri->len > prefix->len && memcmp(uri->p, prefix->p, prefix->len) == 0;
24
}
25

    
26
static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
27
  return s1->len == s2->len && memcmp(s1->p, s2->p, s2->len) == 0;
28
}
29

    
30
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
31
  static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
32
  struct http_message *hm = (struct http_message *) ev_data;
33
  struct mg_str key;
34

    
35
  switch (ev) {
36
    case MG_EV_HTTP_REQUEST:
37
      if (has_prefix(&hm->uri, &api_prefix)) {
38
        key.p = hm->uri.p + api_prefix.len;
39
        key.len = hm->uri.len - api_prefix.len;
40
        if (is_equal(&hm->method, &s_get_method)) {
41
          db_op(nc, hm, &key, s_db_handle, API_OP_GET);
42
        } else if (is_equal(&hm->method, &s_put_method)) {
43
          db_op(nc, hm, &key, s_db_handle, API_OP_SET);
44
        } else if (is_equal(&hm->method, &s_delele_method)) {
45
          db_op(nc, hm, &key, s_db_handle, API_OP_DEL);
46
        } else {
47
          mg_printf(nc, "%s",
48
                    "HTTP/1.0 501 Not Implemented\r\n"
49
                    "Content-Length: 0\r\n\r\n");
50
        }
51
      } else {
52
        mg_serve_http(nc, hm, s_http_server_opts); /* Serve static content */
53
      }
54
      break;
55
    default:
56
      break;
57
  }
58
}
59

    
60
int main(int argc, char *argv[]) {
61
  struct mg_mgr mgr;
62
  struct mg_connection *nc;
63
  int i;
64

    
65
  /* Open listening socket */
66
  mg_mgr_init(&mgr, NULL);
67
  nc = mg_bind(&mgr, s_http_port, ev_handler);
68
  mg_set_protocol_http_websocket(nc);
69
  s_http_server_opts.document_root = "web_root";
70

    
71
  /* Parse command line arguments */
72
  for (i = 1; i < argc; i++) {
73
    if (strcmp(argv[i], "-D") == 0) {
74
      mgr.hexdump_file = argv[++i];
75
    } else if (strcmp(argv[i], "-f") == 0) {
76
      s_db_path = argv[++i];
77
    } else if (strcmp(argv[i], "-r") == 0) {
78
      s_http_server_opts.document_root = argv[++i];
79
    }
80
  }
81

    
82
  signal(SIGINT, signal_handler);
83
  signal(SIGTERM, signal_handler);
84

    
85
  /* Open database */
86
  if ((s_db_handle = db_open(s_db_path)) == NULL) {
87
    fprintf(stderr, "Cannot open DB [%s]\n", s_db_path);
88
    exit(EXIT_FAILURE);
89
  }
90

    
91
  /* Run event loop until signal is received */
92
  printf("Starting RESTful server on port %s\n", s_http_port);
93
  while (s_sig_num == 0) {
94
    mg_mgr_poll(&mgr, 1000);
95
  }
96

    
97
  /* Cleanup */
98
  mg_mgr_free(&mgr);
99
  db_close(&s_db_handle);
100

    
101
  printf("Exiting on signal %d\n", s_sig_num);
102

    
103
  return 0;
104
}