This commit is contained in:
@@ -104,6 +104,7 @@ extern off_t restd_http_get_content_length(restd_conn_t *conn);
|
||||
extern size_t restd_http_get_content_length_stored(restd_conn_t *conn);
|
||||
extern void *restd_http_get_content(restd_conn_t *conn, size_t maxsize, size_t *storedsize);
|
||||
extern int restd_http_is_keepalive_request(restd_conn_t *conn);
|
||||
extern int http_parser(restd_http_t *http, struct evbuffer *in);
|
||||
|
||||
extern int restd_http_set_response_header(restd_conn_t *conn, const char *name, const char *value);
|
||||
extern const char *restd_http_get_response_header(restd_conn_t *conn, const char *name);
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
|
||||
/*------------------------------- INCLUDES ----------------------------------*/
|
||||
|
||||
extern int restd_rest_handler(short event, restd_conn_t *conn, void *userdata);
|
||||
extern int restd_rest_handler(short event, restd_conn_t *conn);
|
||||
|
||||
#endif /* _RESTD_REST_HANDLER_H */
|
||||
@@ -70,6 +70,7 @@ enum restd_log_e
|
||||
/**
|
||||
* User callback(hook) prototype.
|
||||
*/
|
||||
typedef int (*restd_call_hook_cb)(short event, restd_conn_t *conn);
|
||||
typedef int (*restd_callback)(short event, restd_conn_t *conn, void *userdata);
|
||||
typedef void (*restd_userdata_free_cb)(restd_conn_t *conn, void *userdata);
|
||||
|
||||
@@ -107,6 +108,8 @@ struct restd_server_s
|
||||
struct event_base *evbase; /*!< event base */
|
||||
|
||||
struct bufferevent *notify_buffer; /*!< internal notification channel */
|
||||
|
||||
restd_call_hook_cb call_hooks;
|
||||
restd_callback request_handler;
|
||||
restd_callback error_handler;
|
||||
};
|
||||
@@ -157,6 +160,7 @@ extern int restd_server_get_option_int(restd_server_t *server, const char *key);
|
||||
|
||||
extern void restd_server_register_request_handler(restd_server_t *server, restd_callback cb);
|
||||
extern void restd_server_register_error_handler(restd_server_t *server, restd_callback cb);
|
||||
extern void restd_server_register_call_hooks_handler(restd_server_t *server, restd_call_hook_cb cb);
|
||||
|
||||
extern void restd_server_register_hook(restd_server_t *server, restd_callback cb, void *userdata);
|
||||
extern void restd_server_register_hook_on_method(restd_server_t *server, const char *method,
|
||||
|
||||
@@ -45,7 +45,6 @@ static void http_free(restd_http_t *http);
|
||||
static size_t http_add_inbuf(struct evbuffer *buffer, restd_http_t *http,
|
||||
size_t maxsize);
|
||||
|
||||
static int http_parser(restd_http_t *http, struct evbuffer *in);
|
||||
static int parse_requestline(restd_http_t *http, char *line);
|
||||
static int parse_headers(restd_http_t *http, struct evbuffer *in);
|
||||
static int parse_body(restd_http_t *http, struct evbuffer *in);
|
||||
@@ -617,7 +616,7 @@ static size_t http_add_inbuf(struct evbuffer *buffer, restd_http_t *http,
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static int http_parser(restd_http_t *http, struct evbuffer *in)
|
||||
int http_parser(restd_http_t *http, struct evbuffer *in)
|
||||
{
|
||||
ASSERT(http != NULL && in != NULL);
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ static bool contain(const char *src, const char *dest, int len)
|
||||
*
|
||||
* @brief Main function to manage rest request.
|
||||
*/
|
||||
int restd_rest_handler(short event, restd_conn_t *conn, void *userdata)
|
||||
int restd_rest_handler(short event, restd_conn_t *conn)
|
||||
{
|
||||
if (event & RESTD_EVENT_INIT)
|
||||
{
|
||||
@@ -186,99 +186,93 @@ int restd_rest_handler(short event, restd_conn_t *conn, void *userdata)
|
||||
restd_conn_set_extra(conn, http, http_free_cb);
|
||||
return RESTD_OK;
|
||||
}
|
||||
else if (event & RESTD_EVENT_READ)
|
||||
{
|
||||
DEBUG("==> HTTP READ");
|
||||
return RESTD_OK;
|
||||
}
|
||||
else if (event & RESTD_EVENT_WRITE)
|
||||
{
|
||||
DEBUG("==> HTTP WRITE");
|
||||
return RESTD_OK;
|
||||
}
|
||||
else if (event & RESTD_EVENT_CLOSE)
|
||||
{
|
||||
DEBUG("==> HTTP CLOSE=%x (TIMEOUT=%d, SHUTDOWN=%d)",
|
||||
event, event & RESTD_EVENT_TIMEOUT, event & RESTD_EVENT_SHUTDOWN);
|
||||
return RESTD_OK;
|
||||
}
|
||||
else if ((event & RESTD_EVENT_READ) || (event & RESTD_EVENT_WRITE))
|
||||
{
|
||||
restd_http_t *http = (restd_http_t *)restd_conn_get_extra(conn);
|
||||
int status = http_parser(http, conn->in);
|
||||
if (conn->method == NULL && http->request.method != NULL)
|
||||
{
|
||||
restd_conn_set_method(conn, http->request.method);
|
||||
}
|
||||
DEBUG("==> HTTP READ || HTTP WRITE");
|
||||
int reason = RESTD_ERROR_PATH_NOT_FOUND;
|
||||
DEBUG("ZOB********restd_rest_handler: event 0x%x", event);
|
||||
char *root_path;
|
||||
qlist_t *hooks = conn->server->hooks;
|
||||
|
||||
qlist_obj_t obj;
|
||||
bzero((void *)&obj, sizeof(qlist_obj_t));
|
||||
while (hooks->getnext(hooks, &obj, false) == true)
|
||||
{
|
||||
restd_hook_t *hook = (restd_hook_t *)obj.data;
|
||||
if (hook->cb)
|
||||
{
|
||||
DEBUG("ZOB call_hooks: method: %s - %s \n", hook->method, conn->method);
|
||||
DEBUG("call_hooks: path: %s - %s\n", hook->path, http->request.path);
|
||||
DEBUG("HOOK FOUND !!!!\n");
|
||||
if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0))
|
||||
{
|
||||
DEBUG("Hook found but method failed.\n");
|
||||
reason = RESTD_ERROR_METHOD_NOT_ALLOWED;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((hook->path != NULL) && (http->request.path != NULL))
|
||||
{
|
||||
int i = 0;
|
||||
int pos = -1;
|
||||
while (hook->path[i])
|
||||
{
|
||||
if (hook->path[i] == ':')
|
||||
pos = i;
|
||||
i++;
|
||||
}
|
||||
if (pos != -1 && contain(hook->path, http->request.path, pos))
|
||||
{
|
||||
const char *buffer = &http->request.path[pos];
|
||||
// printf("buffer: <%s>\n", buffer);
|
||||
conn->id = atoi(buffer);
|
||||
return hook->cb(event, conn, hook->userdata);
|
||||
}
|
||||
else if (strcmp(hook->path, http->request.path) == 0)
|
||||
return hook->cb(event, conn, hook->userdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
// No Hook Found check if it's a real file into document root.
|
||||
root_path = restd_server_get_option(conn->server, "server.root_path");
|
||||
if ((root_path != NULL) && (strlen(root_path) != 0))
|
||||
{
|
||||
FILE *file;
|
||||
char buf[1024] = "";
|
||||
qstrcatf(buf, "%s%s", root_path, http->request.path);
|
||||
if ((file = fopen(buf, "r")))
|
||||
{
|
||||
long fsize;
|
||||
char *file_buf;
|
||||
fseek(file, 0, SEEK_END);
|
||||
fsize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
file_buf = malloc(fsize + 1);
|
||||
fread(file_buf, 1, fsize, file);
|
||||
fclose(file);
|
||||
file_buf[fsize] = 0;
|
||||
|
||||
printf("mime type:%s\n", file_mime_lookup(buf));
|
||||
restd_http_response(conn, 200, file_mime_lookup(buf), file_buf, fsize);
|
||||
return RESTD_CLOSE;
|
||||
}
|
||||
}
|
||||
|
||||
return conn->server->error_handler(reason, conn, NULL);
|
||||
}
|
||||
|
||||
BUG_EXIT();
|
||||
return RESTD_CLOSE;
|
||||
}
|
||||
|
||||
|
||||
int restd_rest_handler2(short event, restd_conn_t *conn, void *userdata)
|
||||
{
|
||||
int reason = RESTD_ERROR_PATH_NOT_FOUND;
|
||||
DEBUG("ZOB********restd_rest_handler: event 0x%x", event);
|
||||
restd_http_t *http = (restd_http_t *)restd_conn_get_extra(conn);
|
||||
char *root_path;
|
||||
qlist_t *hooks = conn->server->hooks;
|
||||
|
||||
qlist_obj_t obj;
|
||||
bzero((void *)&obj, sizeof(qlist_obj_t));
|
||||
while (hooks->getnext(hooks, &obj, false) == true)
|
||||
{
|
||||
restd_hook_t *hook = (restd_hook_t *)obj.data;
|
||||
if (hook->cb)
|
||||
{
|
||||
DEBUG("ZOB call_hooks: method: %s - %s \n", hook->method, conn->method);
|
||||
DEBUG("call_hooks: path: %s - %s\n", hook->path, http->request.path);
|
||||
DEBUG("HOOK FOUND !!!!\n");
|
||||
if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0))
|
||||
{
|
||||
// DEBUG("Hook found but method failed.\n");
|
||||
reason = RESTD_ERROR_METHOD_NOT_ALLOWED;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((hook->path != NULL) && (http->request.path != NULL))
|
||||
{
|
||||
int i = 0;
|
||||
int pos = -1;
|
||||
while (hook->path[i])
|
||||
{
|
||||
if (hook->path[i] == ':')
|
||||
pos = i;
|
||||
i++;
|
||||
}
|
||||
if (pos != -1 && contain(hook->path, http->request.path, pos))
|
||||
{
|
||||
const char *buffer = &http->request.path[pos];
|
||||
// printf("buffer: <%s>\n", buffer);
|
||||
conn->id = atoi(buffer);
|
||||
return hook->cb(event, conn, hook->userdata);
|
||||
}
|
||||
else if (strcmp(hook->path, http->request.path) == 0)
|
||||
return hook->cb(event, conn, hook->userdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
// No Hook Found check if it's a real file into document root.
|
||||
root_path = restd_server_get_option(conn->server, "server.root_path");
|
||||
if ((root_path != NULL) && (strlen(root_path) != 0))
|
||||
{
|
||||
FILE *file;
|
||||
char buf[1024] = "";
|
||||
qstrcatf(buf, "%s%s", root_path, http->request.path);
|
||||
if ((file = fopen(buf, "r")))
|
||||
{
|
||||
long fsize;
|
||||
char *file_buf;
|
||||
fseek(file, 0, SEEK_END);
|
||||
fsize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
file_buf = malloc(fsize + 1);
|
||||
fread(file_buf, 1, fsize, file);
|
||||
fclose(file);
|
||||
file_buf[fsize] = 0;
|
||||
|
||||
printf("mime type:%s\n", file_mime_lookup(buf));
|
||||
restd_http_response(conn, 200, file_mime_lookup(buf), file_buf, fsize);
|
||||
return RESTD_CLOSE;
|
||||
}
|
||||
}
|
||||
|
||||
return conn->server->error_handler(reason, conn, NULL);
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ restd_server_t *restd_server_new(void)
|
||||
server->options = qhashtbl(0, 0);
|
||||
server->stats = qhashtbl(100, QHASHTBL_THREADSAFE);
|
||||
server->hooks = qlist(0);
|
||||
server->call_hooks = call_hooks;
|
||||
if (server->options == NULL || server->stats == NULL || server->hooks == NULL)
|
||||
{
|
||||
restd_server_free(server);
|
||||
@@ -535,7 +536,7 @@ static restd_conn_t *conn_new(restd_server_t *server, struct bufferevent *buffer
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("conn_new\n");
|
||||
// Create a new connection container.
|
||||
restd_conn_t *conn = NEW_OBJECT(restd_conn_t);
|
||||
if (conn == NULL)
|
||||
@@ -555,7 +556,7 @@ static restd_conn_t *conn_new(restd_server_t *server, struct bufferevent *buffer
|
||||
bufferevent_enable(buffer, EV_READ);
|
||||
|
||||
// Run callbacks with AD_EVENT_INIT event.
|
||||
conn->status = call_hooks(RESTD_EVENT_INIT | RESTD_EVENT_WRITE, conn);
|
||||
conn->status = conn->server->call_hooks(RESTD_EVENT_INIT | RESTD_EVENT_WRITE, conn);
|
||||
|
||||
//
|
||||
conn->id = -1;
|
||||
@@ -600,7 +601,7 @@ static void conn_free(restd_conn_t *conn)
|
||||
{
|
||||
if (conn->status != RESTD_CLOSE)
|
||||
{
|
||||
call_hooks(RESTD_EVENT_CLOSE | RESTD_EVENT_SHUTDOWN, conn);
|
||||
conn->server->call_hooks(RESTD_EVENT_CLOSE | RESTD_EVENT_SHUTDOWN, conn);
|
||||
}
|
||||
conn_reset(conn);
|
||||
if (conn->buffer)
|
||||
@@ -652,7 +653,7 @@ static void conn_cb(restd_conn_t *conn, int event)
|
||||
DEBUG("conn_cb: status:0x%x, event:0x%x", conn->status, event)
|
||||
if (conn->status == RESTD_OK || conn->status == RESTD_TAKEOVER)
|
||||
{
|
||||
int status = call_hooks(event, conn);
|
||||
int status = conn->server->call_hooks(event, conn);
|
||||
// Update status only when it's higher then before.
|
||||
if (!(conn->status == RESTD_CLOSE || (conn->status == RESTD_DONE && conn->status >= status)))
|
||||
{
|
||||
@@ -664,9 +665,9 @@ static void conn_cb(restd_conn_t *conn, int event)
|
||||
{
|
||||
if (restd_server_get_option_int(conn->server, "server.request_pipelining"))
|
||||
{
|
||||
call_hooks(RESTD_EVENT_CLOSE, conn);
|
||||
conn->server->call_hooks(RESTD_EVENT_CLOSE, conn);
|
||||
conn_reset(conn);
|
||||
call_hooks(RESTD_EVENT_INIT, conn);
|
||||
conn->server->call_hooks(RESTD_EVENT_INIT, conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -684,7 +685,7 @@ static void conn_cb(restd_conn_t *conn, int event)
|
||||
if (evbuffer_get_length(conn->out) <= 0)
|
||||
{
|
||||
int newevent = (event & RESTD_EVENT_CLOSE) ? event : RESTD_EVENT_CLOSE;
|
||||
call_hooks(newevent, conn);
|
||||
//conn->server->call_hooks(newevent, conn);
|
||||
conn_free(conn);
|
||||
DEBUG("Connection closed.");
|
||||
return;
|
||||
@@ -708,6 +709,13 @@ void restd_server_register_error_handler(restd_server_t *server, restd_callback
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void restd_server_register_call_hooks_handler(restd_server_t *server, restd_call_hook_cb cb)
|
||||
{
|
||||
server->call_hooks = cb;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Register user hook.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user