#include "uri.h" #include #include #include #include const char ebb_http_header[] = "HTTP/1.0 201 Created\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: %zd\r\n\r\n"; void uri_ebb_buf_free(ebb_buf* buf) { free(buf->data); buf->data = 0; buf->len = buf->written = 0; buf->on_release = 0; } static uri_dispatch_t uri_map[] = { { .uri = "/", .init = uri_root_init, .parse = 0, .get = uri_root_discovery, .post = 0, .delete = 0, .destroy = uri_root_destroy, }, { .uri = "/bbf/detect.objects", .init = uri_bbf_detect_objects_init, .parse = uri_bbf_detect_objects_parse, .get = uri_bbf_detect_objects_intro, .post = uri_bbf_detect_objects, .delete = 0, .destroy = uri_bbf_detect_objects_destroy, }, { .uri = "/convnet/classify", .init = uri_convnet_classify_init, .parse = uri_convnet_classify_parse, .get = uri_convnet_classify_intro, .post = uri_convnet_classify, .delete = 0, .destroy = uri_convnet_classify_destroy, }, { .uri = "/dpm/detect.objects", .init = uri_dpm_detect_objects_init, .parse = uri_dpm_detect_objects_parse, .get = uri_dpm_detect_objects_intro, .post = uri_dpm_detect_objects, .delete = 0, .destroy = uri_dpm_detect_objects_destroy, }, { .uri = "/icf/detect.objects", .init = uri_icf_detect_objects_init, .parse = uri_icf_detect_objects_parse, .get = uri_icf_detect_objects_intro, .post = uri_icf_detect_objects, .delete = 0, .destroy = uri_icf_detect_objects_destroy, }, { .uri = "/scd/detect.objects", .init = uri_scd_detect_objects_init, .parse = uri_scd_detect_objects_parse, .get = uri_scd_detect_objects_intro, .post = uri_scd_detect_objects, .delete = 0, .destroy = uri_scd_detect_objects_destroy, }, { .uri = "/sift", .init = uri_sift_init, .parse = uri_sift_parse, .get = uri_sift_intro, .post = uri_sift, .delete = 0, .destroy = uri_sift_destroy, }, { .uri = "/swt/detect.words", .init = uri_swt_detect_words_init, .parse = uri_swt_detect_words_parse, .get = uri_swt_detect_words_intro, .post = uri_swt_detect_words, .delete = 0, .destroy = uri_swt_detect_words_destroy, }, { .uri = "/tld/track.object", .init = uri_tld_track_object_init, .parse = uri_tld_track_object_parse, .get = uri_tld_track_object_intro, .post = uri_tld_track_object, .delete = uri_tld_track_object_free, .destroy = uri_tld_track_object_destroy, }, }; uri_dispatch_t* find_uri_dispatch(const char* path) { uri_dispatch_t* low = (uri_dispatch_t*)uri_map; uri_dispatch_t* high = (uri_dispatch_t*)uri_map + sizeof(uri_map) / sizeof(uri_dispatch_t) - 1; while (low <= high) { uri_dispatch_t* middle = low + (high - low) / 2; int flag = strcmp(middle->uri, path); if (flag == 0) return middle; else if (flag < 0) low = middle + 1; else high = middle - 1; } return 0; } void uri_init(void) { int i; size_t len = sizeof(uri_map) / sizeof(uri_dispatch_t); for (i = 0; i < len; i++) { if (uri_map[i].init) { printf("init context for %s\n", uri_map[i].uri); uri_map[i].context = uri_map[i].init(); } else uri_map[i].context = 0; } } void uri_destroy(void) { int i; size_t len = sizeof(uri_map) / sizeof(uri_dispatch_t); for (i = 0; i < len; i++) { if (uri_map[i].destroy) { printf("destroy context for %s\n", uri_map[i].uri); uri_map[i].destroy(uri_map[i].context); } } } void* uri_root_init(void) { int i; size_t len = sizeof(uri_map) / sizeof(uri_dispatch_t); assert(len > 1); size_t root_len = 1; for (i = 1; i < len; i++) root_len += strlen(uri_map[i].uri) + 3; char* data = (char*)malloc(sizeof(ebb_buf) + 192 /* the head start for http header */ + root_len); ebb_buf* root_discovery = (ebb_buf*)data; data += sizeof(ebb_buf); snprintf(data, 192, ebb_http_header, root_len); root_discovery->written = strlen(data) + 2; data[root_discovery->written - 2] = '['; for (i = 1; i < len; i++) { size_t uri_len = strlen(uri_map[i].uri); data[root_discovery->written - 1] = '"'; memcpy(data + root_discovery->written, uri_map[i].uri, uri_len); root_discovery->written += uri_len + 3; data[root_discovery->written - 3] = '"'; data[root_discovery->written - 2] = (i == len - 1) ? ']' : ','; } data[root_discovery->written - 1] = '\n'; root_discovery->len = root_discovery->written; root_discovery->data = data; return root_discovery; } int uri_root_discovery(const void* context, const void* parsed, ebb_buf* buf) { ebb_buf* root_discovery = (ebb_buf*)context; buf->data = root_discovery->data; buf->len = root_discovery->len; return 0; } void uri_root_destroy(void* context) { free(context); }