BALDE_API balde_response_t* balde_abort(balde_app_t *app, const balde_http_exception_code_t code) { balde_abort_set_error(app, code); balde_response_t* response = NULL; if (app->error != NULL) { response = balde_make_response_from_exception(app->error); g_clear_error(&app->error); app->error = NULL; } return response; }
void test_make_response_from_exception(void) { balde_app_t *app = balde_app_init(); balde_abort_set_error(app, 404); balde_response_t *res = balde_make_response_from_exception(app->error); g_assert(res != NULL); g_assert(res->status_code == 404); g_assert(g_hash_table_size(res->headers) == 1); GSList *tmp = g_hash_table_lookup(res->headers, "content-type"); g_assert_cmpstr(tmp->data, ==, "text/plain; charset=utf-8"); g_assert_cmpstr(res->body->str, ==, "404 Not Found\n\nThe requested URL was not found on the server. " "If you entered the URL manually please check your spelling and try again.\n"); balde_response_free(res); balde_app_free(app); }
void test_response_render_exception_without_body(void) { balde_app_t *app = balde_app_init(); balde_abort_set_error(app, 404); balde_response_t *res = balde_make_response_from_exception(app->error); g_assert(res != NULL); GString *out = balde_response_render(res, FALSE); g_assert_cmpstr(out->str, ==, "Status: 404 Not Found\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "Content-Length: 136\r\n" "\r\n"); g_string_free(out, TRUE); balde_response_free(res); balde_app_free(app); }
void test_make_response_from_external_exception(void) { balde_app_t *app = balde_app_init(); balde_abort_set_error(app, 1024); balde_response_t *res = balde_make_response_from_exception(app->error); g_assert(res != NULL); g_assert(res->status_code == 500); g_assert(g_hash_table_size(res->headers) == 1); GSList *tmp = g_hash_table_lookup(res->headers, "content-type"); g_assert_cmpstr(tmp->data, ==, "text/plain; charset=utf-8"); g_assert_cmpstr(res->body->str, ==, "500 Internal Server Error\n\nThe server encountered an internal error " "and was unable to complete your request. Either the server is " "overloaded or there is an error in the application.\n\n(null)\n"); balde_response_free(res); balde_app_free(app); }
void test_response_render_exception(void) { balde_app_t *app = balde_app_init(); balde_abort_set_error(app, 404); balde_response_t *res = balde_make_response_from_exception(app->error); g_assert(res != NULL); GString *out = balde_response_render(res, TRUE); g_assert_cmpstr(out->str, ==, "Status: 404 Not Found\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "Content-Length: 136\r\n" "\r\n" "404 Not Found\n\nThe requested URL was not found on the server. " "If you entered the URL manually please check your spelling and try again.\n"); g_string_free(out, TRUE); balde_response_free(res); balde_app_free(app); }
void test_app_copy(void) { balde_app_t *app = balde_app_init(); balde_app_t *copy = balde_app_copy(app); g_assert(!app->copy); g_assert(copy->copy); balde_abort_set_error(app, 404); g_assert(app->error != NULL); g_assert(copy->error == NULL); g_assert(app->priv->views != NULL); g_assert(app->priv->views == copy->priv->views); g_assert(app->priv->config != NULL); g_assert(app->priv->config == copy->priv->config); g_assert(app->priv->user_data == NULL); g_assert(copy->priv->user_data == NULL); copy->priv->user_data = GINT_TO_POINTER(10); g_assert_cmpint(GPOINTER_TO_INT(copy->priv->user_data), ==, 10); g_assert_cmpint(GPOINTER_TO_INT(app->priv->user_data), ==, 10); balde_app_free(app); balde_app_free(copy); }
GString* balde_app_main_loop(balde_app_t *app, balde_request_env_t *env, balde_response_render_t render, balde_http_exception_code_t *status_code) { balde_request_t *request = NULL; balde_response_t *response = NULL; balde_response_t *error_response = NULL; gchar *endpoint = NULL; gboolean with_body = TRUE; GString *rv = NULL; // render startup error, if any if (app->error != NULL) { error_response = balde_make_response_from_exception(app->error); rv = render(error_response, with_body); if (status_code != NULL) *status_code = error_response->status_code; balde_response_free(error_response); // free env, because it should be free'd by main loop and will not be // used anymore. balde_request_env_free(env); return rv; } request = balde_make_request(app, env); with_body = ! (request->method & BALDE_HTTP_HEAD); for (GSList *tmp = app->priv->before_requests; tmp != NULL; tmp = g_slist_next(tmp)) { balde_before_request_t *hook = tmp->data; hook->before_request_func(app, request); if (app->error != NULL) { error_response = balde_make_response_from_exception(app->error); rv = render(error_response, with_body); if (status_code != NULL) *status_code = error_response->status_code; balde_response_free(error_response); g_clear_error(&app->error); return rv; } } balde_app_t *app_copy = balde_app_copy(app); // get the view endpoint = balde_dispatch_from_path(app_copy->priv->views, request->path, &(request->priv->view_args)); if (endpoint == NULL) { // no view found! :( balde_abort_set_error(app_copy, 404); } else { // validate http method balde_view_t *view = balde_app_get_view_from_endpoint(app_copy, endpoint); if (request->method & view->url_rule->method) { // answer OPTIONS automatically if (request->method == BALDE_HTTP_OPTIONS) { response = balde_make_response(""); gchar *allow = balde_list_allowed_methods(view->url_rule->method); balde_response_set_header(response, "Allow", allow); g_free(allow); } // run the view else { response = view->view_func(app_copy, request); } } // method not allowed else { balde_abort_set_error(app_copy, 405); } g_free(endpoint); } balde_request_free(request); if (app_copy->error != NULL) { error_response = balde_make_response_from_exception(app_copy->error); rv = render(error_response, with_body); if (status_code != NULL) *status_code = error_response->status_code; balde_response_free(response); balde_response_free(error_response); balde_app_free(app_copy); return rv; } rv = render(response, with_body); if (status_code != NULL) *status_code = response->status_code; balde_response_free(response); balde_app_free(app_copy); return rv; }