#include "webserver.h" #include "master.h" #include #include #include #include #include #include #include #include #include /* embedded web pages and JS code */ #include "index.h" #include "jquery-ui-css.h" #include "jquery-js.h" #include "jquery-ui-js.h" #include "ui-bg_flat_0_aaaaaa_40x100-png.h" #include "ui-bg_flat_75_ffffff_40x100-png.h" #include "ui-bg_glass_55_fbf9ee_1x400-png.h" #include "ui-bg_glass_65_ffffff_1x400-png.h" #include "ui-bg_glass_75_dadada_1x400-png.h" #include "ui-bg_glass_75_e6e6e6_1x400-png.h" #include "ui-bg_glass_95_fef1ec_1x400-png.h" #include "ui-bg_highlight-soft_75_cccccc_1x100-png.h" #include "ui-icons_222222_256x240-png.h" #include "ui-icons_2e83ff_256x240-png.h" #include "ui-icons_454545_256x240-png.h" #include "ui-icons_888888_256x240-png.h" #include "ui-icons_cd0a0a_256x240-png.h" #include "loading-gif.h" #include "jquery.ui.waitbutton.js.h" static struct MHD_Daemon *d; #if MHD_VERSION < 0x00090500 enum MHD_ResponseMemoryMode { MHD_RESPMEM_PERSISTENT, MHD_RESPMEM_MUST_FREE, MHD_RESPMEM_MUST_COPY }; #define MHD_create_response_from_buffer wrap_response static struct MHD_Response *wrap_response( size_t size, void *buffer, enum MHD_ResponseMemoryMode mode) { return MHD_create_response_from_data( size, buffer, ( mode | MHD_RESPMEM_MUST_FREE ) == MHD_RESPMEM_MUST_FREE, ( mode | MHD_RESPMEM_MUST_COPY ) == MHD_RESPMEM_MUST_COPY ); } #endif static const char *CONTENT_TYPE_TEXT_HTML = "text/html"; static const char *CONTENT_TYPE_TEXT_JS = "text/javascript"; static const char *CONTENT_TYPE_TEXT_CSS = "text/css"; static const char *CONTENT_TYPE_IMAGE_PNG = "image/png"; static int handle_request( void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **ptr ) { struct MHD_Response *response; int ret; fprintf( stderr, "%s http request: %s\n", method, url ); if( strcmp( method, "GET" ) == 0 ) { char *biruda_msg = malloc( 512 * 1024 ); size_t biruda_msg_len = 0; const char *content_type = CONTENT_TYPE_TEXT_HTML; biruda_msg[0] = '\0'; if( strcmp( url, "/status" ) == 0 ) { for( int pos = 0; pos < MAX_COORDINATORS; pos++ ) { coordinator_t *c = &coordinator[pos]; if( c->used ) { char part[256]; snprintf( part, sizeof( part ), "coordinator %s %s %s %d %s %lld (%d)\n", c->host, c->os, c->arch, c->cpus, ( c->alive ? "alive" : "dead" ), (long long)c->lastAlive, pos ); strncat( biruda_msg, part, strlen( part ) ); for( int i = 0; i < c->nof_workers; i++ ) { worker_t *w = &c->worker[i]; snprintf( part, sizeof( part ), "worker %s %s %s %s (%d)\n", w->name, worker_state_str( w->state ), worker_exection_mode_str( w->mode ), ( w->command == NULL ? "" : w->command ), i ); strncat( biruda_msg, part, strlen( part ) ); } } } biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/worker" ) == 0 ) { const char *op = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "op" ); printf( "Got GET operation '%s'\n", op ); if( op == NULL ) { return MHD_NO; } if( strcmp( op, "output" ) == 0 ) { const char *name = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "name" ); if( name != NULL ) { master_output_outstanding_messages( name, biruda_msg, sizeof( biruda_msg ) ); } else { return MHD_NO; } } else if( strcmp( op, "tail" ) == 0 ) { const char *name = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "name" ); if( name != NULL ) { master_output_tail( name, biruda_msg, sizeof( biruda_msg ) ); } else { return MHD_NO; } } biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/web" ) == 0 ) { strncpy( biruda_msg, (char *)index_html, index_html_len ); biruda_msg[index_html_len] = '\0'; biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/web/jquery-ui.css" ) == 0 ) { strncpy( biruda_msg, (char *)jquery_ui_css, jquery_ui_css_len ); biruda_msg[jquery_ui_css_len] = '\0'; content_type = CONTENT_TYPE_TEXT_CSS; biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/web/jquery.js" ) == 0 ) { strncpy( biruda_msg, (char *)jquery_js, jquery_js_len ); biruda_msg[jquery_js_len] = '\0'; content_type = CONTENT_TYPE_TEXT_JS; biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/web/jquery-ui.js" ) == 0 ) { strncpy( biruda_msg, (char *)jquery_ui_js, jquery_ui_js_len ); biruda_msg[jquery_ui_js_len] = '\0'; content_type = CONTENT_TYPE_TEXT_JS; biruda_msg_len = strlen( biruda_msg ); } else if( strcmp( url, "/web/images/ui-bg_flat_0_aaaaaa_40x100.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_flat_0_aaaaaa_40x100_png, images_ui_bg_flat_0_aaaaaa_40x100_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_flat_0_aaaaaa_40x100_png_len; } else if( strcmp( url, "/web/images/ui-bg_flat_75_ffffff_40x100.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_flat_75_ffffff_40x100_png, images_ui_bg_flat_75_ffffff_40x100_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_flat_75_ffffff_40x100_png_len; } else if( strcmp( url, "/web/images/ui-bg_glass_55_fbf9ee_1x400.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_glass_55_fbf9ee_1x400_png, images_ui_bg_glass_55_fbf9ee_1x400_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_glass_55_fbf9ee_1x400_png_len; } else if( strcmp( url, "/web/images/ui-bg_glass_65_ffffff_1x400.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_glass_65_ffffff_1x400_png, images_ui_bg_glass_65_ffffff_1x400_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_glass_65_ffffff_1x400_png_len; } else if( strcmp( url, "/web/images/ui-bg_glass_75_dadada_1x400.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_glass_75_dadada_1x400_png, images_ui_bg_glass_75_dadada_1x400_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_glass_75_dadada_1x400_png_len; } else if( strcmp( url, "/web/images/ui-bg_glass_75_e6e6e6_1x400.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_glass_75_e6e6e6_1x400_png, images_ui_bg_glass_75_e6e6e6_1x400_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_glass_75_e6e6e6_1x400_png_len; } else if( strcmp( url, "/web/images/ui-bg_glass_95_fef1ec_1x400.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_glass_95_fef1ec_1x400_png, images_ui_bg_glass_95_fef1ec_1x400_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_glass_95_fef1ec_1x400_png_len; } else if( strcmp( url, "/web/images/ui-bg_highlight-soft_75_cccccc_1x100.png" ) == 0 ) { memcpy( biruda_msg, images_ui_bg_highlight_soft_75_cccccc_1x100_png, images_ui_bg_highlight_soft_75_cccccc_1x100_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_bg_highlight_soft_75_cccccc_1x100_png_len; } else if( strcmp( url, "/web/images/ui-icons_222222_256x240.png" ) == 0 ) { memcpy( biruda_msg, images_ui_icons_222222_256x240_png, images_ui_icons_222222_256x240_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_icons_222222_256x240_png_len; } else if( strcmp( url, "/web/images/ui-icons_2e83ff_256x240.png" ) == 0 ) { memcpy( biruda_msg, images_ui_icons_2e83ff_256x240_png, images_ui_icons_2e83ff_256x240_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_icons_2e83ff_256x240_png_len; } else if( strcmp( url, "/web/images/ui-icons_454545_256x240.png" ) == 0 ) { memcpy( biruda_msg, images_ui_icons_454545_256x240_png, images_ui_icons_454545_256x240_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_icons_454545_256x240_png_len; } else if( strcmp( url, "/web/images/ui-icons_888888_256x240.png" ) == 0 ) { memcpy( biruda_msg, images_ui_icons_888888_256x240_png, images_ui_icons_888888_256x240_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_icons_888888_256x240_png_len; } else if( strcmp( url, "/web/images/ui-icons_cd0a0a_256x240.png" ) == 0 ) { memcpy( biruda_msg, images_ui_icons_cd0a0a_256x240_png, images_ui_icons_cd0a0a_256x240_png_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_ui_icons_cd0a0a_256x240_png_len; } else if( strcmp( url, "/web/images/loading.gif" ) == 0 ) { memcpy( biruda_msg, images_loading_gif, images_loading_gif_len ); content_type = CONTENT_TYPE_IMAGE_PNG; biruda_msg_len = images_loading_gif_len; } else if( strcmp( url, "/web/jquery.ui.waitbutton.js" ) == 0 ) { strncpy( biruda_msg, (char *)jquery_ui_waitbutton_js, jquery_ui_waitbutton_js_len ); biruda_msg[jquery_ui_waitbutton_js_len] = '\0'; content_type = CONTENT_TYPE_TEXT_JS; biruda_msg_len = strlen( biruda_msg ); } else { strcat( biruda_msg, "

This is biruda, the REST api. You can access the web interface here.

" ); biruda_msg_len = strlen( biruda_msg ); } response = MHD_create_response_from_buffer( biruda_msg_len, (void *)biruda_msg, MHD_RESPMEM_MUST_COPY ); ret = MHD_add_response_header( response, "Content-Type", content_type ); ret = MHD_queue_response( connection, MHD_HTTP_OK, response ); MHD_destroy_response( response ); free( biruda_msg ); } else if( strcmp( method, "POST" ) == 0 ) { if( strcmp( url, "/worker" ) == 0 ) { char biruda_msg[2048]; biruda_msg[0] = '\0'; const char *op = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "op" ); printf( "Got POST operation '%s'\n", op ); if( op == NULL ) { return MHD_NO; } if( strcmp( op, "start" ) == 0 ) { const char *name = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "name" ); if( name != NULL ) { printf( "Got POST parameter for starting a worker with name '%s'\n", name ); int res = master_start_worker( name ); if( res < 0 ) { snprintf( biruda_msg, sizeof( biruda_msg ), "Queueing start request message failed\n" ); } else { snprintf( biruda_msg, sizeof( biruda_msg ), "Queued start worker request\n" ); } response = MHD_create_response_from_buffer( strlen( biruda_msg ), (void *)biruda_msg, MHD_RESPMEM_MUST_COPY ); ret = MHD_queue_response( connection, ( res == 0 ) ? MHD_HTTP_OK : MHD_HTTP_INTERNAL_SERVER_ERROR, response ); MHD_destroy_response( response ); } } else if( strcmp( op, "stop" ) == 0 ) { const char *name = MHD_lookup_connection_value( connection, MHD_GET_ARGUMENT_KIND, "name" ); if( name != NULL ) { printf( "Got POST parameter for stopping a worker with name '%s'\n", name ); int res = master_stop_worker( name ); if( res < 0 ) { snprintf( biruda_msg, sizeof( biruda_msg ), "Queueing stop request message failed\n" ); } else { snprintf( biruda_msg, sizeof( biruda_msg ), "Queued stop worker request\n" ); } response = MHD_create_response_from_buffer( strlen( biruda_msg ), (void *)biruda_msg, MHD_RESPMEM_MUST_COPY ); ret = MHD_queue_response( connection, ( res == 0 ) ? MHD_HTTP_OK : MHD_HTTP_INTERNAL_SERVER_ERROR, response ); MHD_destroy_response( response ); } } else { return MHD_NO; } } else { return MHD_NO; } } else { return MHD_NO; } return ret; } int webserver_init( unsigned int port ) { d = MHD_start_daemon( MHD_USE_SELECT_INTERNALLY, port, NULL, NULL, &handle_request, NULL, MHD_OPTION_END ); if( d == 0 ) { return 1; } printf( "http daemon started on port %d\n", port ); return 0; } void webserver_terminate( ) { MHD_stop_daemon( d ); puts( "http daemon stopped" ); } int webserver_free( ) { return 0; }