Commit d9551c50 authored by valenok's avatar valenok

mg_start: struct mg_request_info * -> const struct mg_request_info *

parent 68dde1b7
...@@ -26,11 +26,8 @@ ...@@ -26,11 +26,8 @@
#define MAX_SESSIONS 2 #define MAX_SESSIONS 2
#define SESSION_TTL 120 #define SESSION_TTL 120
static const char *login_url = "/login.html";
static const char *authorize_url = "/authorize"; static const char *authorize_url = "/authorize";
static const char *web_root = "./html"; static const char *login_url = "/login.html";
static const char *http_ports = "8081,8082s";
static const char *ssl_certificate = "ssl_cert.pem";
static const char *ajax_reply_start = static const char *ajax_reply_start =
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Cache: no-cache\r\n" "Cache: no-cache\r\n"
...@@ -77,6 +74,12 @@ static struct session *get_session(const struct mg_connection *conn) { ...@@ -77,6 +74,12 @@ static struct session *get_session(const struct mg_connection *conn) {
return i == MAX_SESSIONS ? NULL : &sessions[i]; return i == MAX_SESSIONS ? NULL : &sessions[i];
} }
static void get_qsvar(const struct mg_request_info *request_info,
const char *name, char *dst, size_t dst_len) {
const char *qs = request_info->query_string;
mg_get_var(qs, strlen(qs == NULL ? "" : qs), name, dst, dst_len);
}
// Get a get of messages with IDs greater than last_id and transform them // Get a get of messages with IDs greater than last_id and transform them
// into a JSON string. Return that string to the caller. The string is // into a JSON string. Return that string to the caller. The string is
// dynamically allocated, caller must free it. If there are no messages, // dynamically allocated, caller must free it. If there are no messages,
...@@ -117,10 +120,10 @@ static char *messages_to_json(long last_id) { ...@@ -117,10 +120,10 @@ static char *messages_to_json(long last_id) {
// Return 1 in this case, or 0 if "callback" is not specified. // Return 1 in this case, or 0 if "callback" is not specified.
// Wrap an output in Javascript function call. // Wrap an output in Javascript function call.
static int handle_jsonp(struct mg_connection *conn, static int handle_jsonp(struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
char cb[64]; char cb[64];
mg_get_qsvar(request_info, "callback", cb, sizeof(cb)); get_qsvar(request_info, "callback", cb, sizeof(cb));
if (cb[0] != '\0') { if (cb[0] != '\0') {
mg_printf(conn, "%s(", cb); mg_printf(conn, "%s(", cb);
} }
...@@ -131,14 +134,14 @@ static int handle_jsonp(struct mg_connection *conn, ...@@ -131,14 +134,14 @@ static int handle_jsonp(struct mg_connection *conn,
// A handler for the /ajax/get_messages endpoint. // A handler for the /ajax/get_messages endpoint.
// Return a list of messages with ID greater than requested. // Return a list of messages with ID greater than requested.
static void ajax_get_messages(struct mg_connection *conn, static void ajax_get_messages(struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
char last_id[32], *json; char last_id[32], *json;
int is_jsonp; int is_jsonp;
mg_printf(conn, "%s", ajax_reply_start); mg_printf(conn, "%s", ajax_reply_start);
is_jsonp = handle_jsonp(conn, request_info); is_jsonp = handle_jsonp(conn, request_info);
mg_get_qsvar(request_info, "last_id", last_id, sizeof(last_id)); get_qsvar(request_info, "last_id", last_id, sizeof(last_id));
if ((json = messages_to_json(strtoul(last_id, NULL, 10))) != NULL) { if ((json = messages_to_json(strtoul(last_id, NULL, 10))) != NULL) {
mg_printf(conn, "[%s]", json); mg_printf(conn, "[%s]", json);
free(json); free(json);
...@@ -165,7 +168,7 @@ static void my_strlcpy(char *dst, const char *src, size_t len) { ...@@ -165,7 +168,7 @@ static void my_strlcpy(char *dst, const char *src, size_t len) {
// A handler for the /ajax/send_message endpoint. // A handler for the /ajax/send_message endpoint.
static void ajax_send_message(struct mg_connection *conn, static void ajax_send_message(struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
struct message *message; struct message *message;
struct session *session; struct session *session;
char text[sizeof(message->text) - 1]; char text[sizeof(message->text) - 1];
...@@ -174,7 +177,7 @@ static void ajax_send_message(struct mg_connection *conn, ...@@ -174,7 +177,7 @@ static void ajax_send_message(struct mg_connection *conn,
mg_printf(conn, "%s", ajax_reply_start); mg_printf(conn, "%s", ajax_reply_start);
is_jsonp = handle_jsonp(conn, request_info); is_jsonp = handle_jsonp(conn, request_info);
(void) mg_get_qsvar(request_info, "text", text, sizeof(text)); get_qsvar(request_info, "text", text, sizeof(text));
if (text[0] != '\0') { if (text[0] != '\0') {
// We have a message to store. Write-lock the ringbuffer, // We have a message to store. Write-lock the ringbuffer,
// grab the next message and copy data into it. // grab the next message and copy data into it.
...@@ -198,7 +201,7 @@ static void ajax_send_message(struct mg_connection *conn, ...@@ -198,7 +201,7 @@ static void ajax_send_message(struct mg_connection *conn,
// Redirect user to the login form. In the cookie, store the original URL // Redirect user to the login form. In the cookie, store the original URL
// we came from, so that after the authorization we could redirect back. // we came from, so that after the authorization we could redirect back.
static void redirect_to_login(struct mg_connection *conn, static void redirect_to_login(struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
const char *host; const char *host;
host = mg_get_header(conn, "Host"); host = mg_get_header(conn, "Host");
...@@ -260,13 +263,13 @@ static void send_server_message(const char *fmt, ...) { ...@@ -260,13 +263,13 @@ static void send_server_message(const char *fmt, ...) {
// A handler for the /authorize endpoint. // A handler for the /authorize endpoint.
// Login page form sends user name and password to this endpoint. // Login page form sends user name and password to this endpoint.
static void authorize(struct mg_connection *conn, static void authorize(struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
char user[MAX_USER_LEN], password[MAX_USER_LEN], original_url[200]; char user[MAX_USER_LEN], password[MAX_USER_LEN], original_url[200];
struct session *session; struct session *session;
// Fetch user name and password. // Fetch user name and password.
mg_get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "user", user, sizeof(user));
mg_get_qsvar(request_info, "password", password, sizeof(password)); get_qsvar(request_info, "password", password, sizeof(password));
mg_get_cookie(conn, "original_url", original_url, sizeof(original_url)); mg_get_cookie(conn, "original_url", original_url, sizeof(original_url));
if (check_password(user, password) && (session = new_session()) != NULL) { if (check_password(user, password) && (session = new_session()) != NULL) {
...@@ -284,7 +287,7 @@ static void authorize(struct mg_connection *conn, ...@@ -284,7 +287,7 @@ static void authorize(struct mg_connection *conn,
my_strlcpy(session->user, user, sizeof(session->user)); my_strlcpy(session->user, user, sizeof(session->user));
snprintf(session->random, sizeof(session->random), "%d", rand()); snprintf(session->random, sizeof(session->random), "%d", rand());
generate_session_id(session->session_id, session->random, generate_session_id(session->session_id, session->random,
session->user, request_info); session->user, request_info);
send_server_message("<%s> joined", session->user); send_server_message("<%s> joined", session->user);
mg_printf(conn, "HTTP/1.1 302 Found\r\n" mg_printf(conn, "HTTP/1.1 302 Found\r\n"
"Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID "Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID
...@@ -302,7 +305,7 @@ static void authorize(struct mg_connection *conn, ...@@ -302,7 +305,7 @@ static void authorize(struct mg_connection *conn,
// Return 1 if request is authorized, 0 otherwise. // Return 1 if request is authorized, 0 otherwise.
static int is_authorized(const struct mg_connection *conn, static int is_authorized(const struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
struct session *session; struct session *session;
char valid_id[33]; char valid_id[33];
int authorized = 0; int authorized = 0;
...@@ -315,6 +318,7 @@ static int is_authorized(const struct mg_connection *conn, ...@@ -315,6 +318,7 @@ static int is_authorized(const struct mg_connection *conn,
authorized = 1; authorized = 1;
} }
} }
printf("session: %p\n", session);
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
return authorized; return authorized;
...@@ -323,54 +327,57 @@ static int is_authorized(const struct mg_connection *conn, ...@@ -323,54 +327,57 @@ static int is_authorized(const struct mg_connection *conn,
// Return 1 if authorization is required for requested URL, 0 otherwise. // Return 1 if authorization is required for requested URL, 0 otherwise.
static int must_authorize(const struct mg_request_info *request_info) { static int must_authorize(const struct mg_request_info *request_info) {
return (strcmp(request_info->uri, login_url) != 0 && return (strcmp(request_info->uri, login_url) != 0 &&
strcmp(request_info->uri, authorize_url) != 0); strcmp(request_info->uri, authorize_url) != 0);
} }
static enum mg_error_t process_request(struct mg_connection *conn, static void *event_handler(enum mg_event event,
const struct mg_request_info *request_info) { struct mg_connection *conn,
enum mg_error_t processed = MG_SUCCESS; const struct mg_request_info *request_info) {
void *processed = "yes";
if (must_authorize(request_info) &&
!is_authorized(conn, request_info)) { if (event == MG_NEW_REQUEST) {
// If user is not authorized, redirect to the login form. if (must_authorize(request_info) && !is_authorized(conn, request_info)) {
redirect_to_login(conn, request_info); redirect_to_login(conn, request_info);
} else if (strcmp(request_info->uri, authorize_url) == 0) { } else if (strcmp(request_info->uri, authorize_url) == 0) {
authorize(conn, request_info); authorize(conn, request_info);
} else if (strcmp(request_info->uri, "/ajax/get_messages") == 0) { } else if (strcmp(request_info->uri, "/ajax/get_messages") == 0) {
ajax_get_messages(conn, request_info); ajax_get_messages(conn, request_info);
} else if (strcmp(request_info->uri, "/ajax/send_message") == 0) { } else if (strcmp(request_info->uri, "/ajax/send_message") == 0) {
ajax_send_message(conn, request_info); ajax_send_message(conn, request_info);
} else {
// No suitable handler found, mark as not processed. Mongoose will
// try to serve the request.
processed = NULL;
}
} else { } else {
// No suitable handler found, mark as not processed. Mongoose will processed = NULL;
// try to serve the request.
processed = MG_ERROR;
} }
return processed; return processed;
} }
static const char *options[] = {
"document_root", "html",
"listening_ports", "8081,8082s",
"ssl_certificate", "ssl_cert.pem",
"num_threads", "5",
NULL
};
int main(void) { int main(void) {
struct mg_context *ctx; struct mg_context *ctx;
struct mg_config config;
// Initialize random number generator. It will be used later on for // Initialize random number generator. It will be used later on for
// the session identifier creation. // the session identifier creation.
srand((unsigned) time(0)); srand((unsigned) time(0));
// Setup and start Mongoose // Setup and start Mongoose
memset(&config, 0, sizeof(config)); ctx = mg_start(&event_handler, options);
config.document_root = web_root;
config.listening_ports = http_ports;
config.ssl_certificate = ssl_certificate;
config.index_files = "index.html";
config.new_request_handler = &process_request;
config.auth_domain = "";
config.num_threads = "5";
ctx = mg_start(&config);
assert(ctx != NULL); assert(ctx != NULL);
// Wait until enter is pressed, then exit // Wait until enter is pressed, then exit
printf("Chat server started on ports %s, press enter to quit.\n", http_ports); printf("Chat server started on ports %s, press enter to quit.\n",
mg_get_option(ctx, "listening_ports"));
getchar(); getchar();
mg_stop(ctx); mg_stop(ctx);
printf("%s\n", "Chat server stopped."); printf("%s\n", "Chat server stopped.");
......
...@@ -75,7 +75,7 @@ enum mg_event { ...@@ -75,7 +75,7 @@ enum mg_event {
// Mongoose proceeds with request handling as if nothing happened. // Mongoose proceeds with request handling as if nothing happened.
typedef void * (*mg_callback_t)(enum mg_event event, typedef void * (*mg_callback_t)(enum mg_event event,
struct mg_connection *conn, struct mg_connection *conn,
struct mg_request_info *request_info); const struct mg_request_info *request_info);
// Start web server. // Start web server.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment