mod_maintenance(1.3系統用)
指定した期間内でアクセスがあった場合、指定したURLへ遷移させるApacheモジュールです。
主に定期的なメンテナンス等で利用します。
以下はhttpd.confで設定できる内容です。
各環境用にURLを定義しないと動作しません(要するにURLは全て定義しておいてね、って事です)。
こちらは「MaintenanceStartTime」と「MaintenanceEndTime」の両方を定義しないと動作しません(片方の定義だけでは動作しません)。
<IfModule mod_maintenance.c> # 毎週1時から3時までの間は指定したURLへ遷移 <Location /TEST1/> MaintenanceLocationURL_PC http://www.example.com/mainte.html MaintenanceLocationURL_DOCOMO http://www.example.com/i/mainte.html MaintenanceLocationURL_EZWEB http://www.example.com/ez/mainte.html MaintenanceLocationURL_SOFTBANK http://www.example.com/sb/mainte.html MaintenanceStartTime 010000 MaintenanceEndTime 030000 </Location> # 毎週木曜日の1時から3時までの間は指定したURLへ遷移 <Location /TEST2/> MaintenanceLocationURL_PC http://www.example.com/mainte.html MaintenanceLocationURL_DOCOMO http://www.example.com/i/mainte.html MaintenanceLocationURL_EZWEB http://www.example.com/ez/mainte.html MaintenanceLocationURL_SOFTBANK http://www.example.com/sb/mainte.html MaintenanceStartTime 010000 MaintenanceEndTime 030000 # define of Sun or Mon or Tue or Wed or Thu or Fri or Sat MaintenanceWeek Thu </Location> </IfModule>
ビルドの仕方は(説明するまでもありませんが)makeファイルとプログラムファイルを同一の場所に配置して、make && make installを実行します。
以下はmakeファイルの内容です。APXSとAPACHECTLのパスは適切な場所を定義してください。
「Makefile」として保存するか、別名にする時はmakeコマンドの-fオプションを使ってファイルを指定してください。
## ## Makefile -- Build procedure for maintenance Apache module ## MODULE_NAME = mod_maintenance VERSION = 0.0.1 # the used tools APXS = /usr/local/apache/bin/apxs APACHECTL = /usr/local/apache/bin/apachectl # the default target all: mod_maintenance.so # compile the DSO file mod_maintenance.so: mod_maintenance.c $(APXS) -c $(DEF) $(INC) $(LIB) mod_maintenance.c # install the DSO file into the Apache installation # and activate it in the Apache configuration install: all $(APXS) -i -a -n 'maintenance' mod_maintenance.so # cleanup clean: rm -f mod_maintenance.o mod_maintenance.so
以下はプログラムファイルの内容です。
「mod_maintenance.c」として保存してください。
mod_datetimelimitをコピー&ペーストして作ったのでコーディングの質については、ご容赦、という事で。
/************************************************************************** mod_maintenance.c -- Apache maintenance module **************************************************************************/ /************************************************************************** define of proto-type for utility functions **************************************************************************/ static int maintenance_is_digit( const char * ); /************************************************************************** define of header file **************************************************************************/ #include "httpd.h" #include "http_conf_globals.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_protocol.h" #include "ap_config.h" #include "scoreboard.h" /************************************************************************** define of struct type etc... **************************************************************************/ typedef struct st_maintenance_config { char *location_pc; char *location_docomo; char *location_ezweb; char *location_softbank; long start_time; long end_time; long week; } maintenance_config; module MODULE_VAR_EXPORT maintenance_module; /************************************************************************** define of main function **************************************************************************/ static void *maintenance_cdir_config( pool *pool, char *path ) { maintenance_config *cfg = (maintenance_config *)ap_pcalloc( pool, sizeof( maintenance_config ) ); cfg->location_pc = NULL; cfg->location_docomo = NULL; cfg->location_ezweb = NULL; cfg->location_softbank = NULL; cfg->start_time = -1; cfg->end_time = -1; cfg->week = -1; return (void *)cfg; } /*************************************************************************/ static const char *set_maintenance_location_pc( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !ap_is_url( Buffer ) && Buffer[0] != '/' ) { return "argument is not also a URL or a path in MaintenanceStartLocationURL_PC."; } if( cfg->location_pc ) { return "duplicate entry for MaintenanceStartLocationURL_PC."; } cfg->location_pc = ap_pstrdup( parms->pool, Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_location_docomo( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !ap_is_url( Buffer ) && Buffer[0] != '/' ) { return "argument is not also a URL or a path in MaintenanceStartLocationURL_DOCOMO."; } if( cfg->location_docomo ) { return "duplicate entry for MaintenanceStartLocationURL_DOCOMO."; } cfg->location_docomo = ap_pstrdup( parms->pool, Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_location_ezweb( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !ap_is_url( Buffer ) && Buffer[0] != '/' ) { return "argument is not also a URL or a path in MaintenanceStartLocationURL_EZWEB."; } if( cfg->location_ezweb ) { return "duplicate entry for MaintenanceStartLocationURL_EZWEB."; } cfg->location_ezweb = ap_pstrdup( parms->pool, Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_location_softbank( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !ap_is_url( Buffer ) && Buffer[0] != '/' ) { return "argument is not also a URL or a path in MaintenanceStartLocationURL_SOFTBANK."; } if( cfg->location_softbank ) { return "duplicate entry for MaintenanceStartLocationURL_SOFTBANK."; } cfg->location_softbank = ap_pstrdup( parms->pool, Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_start_time( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !maintenance_is_digit( Buffer ) ) { return "argument is not a number for MaintenanceStartTime."; } if( strlen( Buffer ) != 6 ) { return "argument fomat error for MaintenanceStartTime."; } cfg->start_time = atol( Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_end_time( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( !maintenance_is_digit( Buffer ) ) { return "argument is not a number for MaintenanceEndTime."; } if( strlen( Buffer ) != 6 ) { return "argument fomat error for MaintenanceEndTime."; } cfg->end_time = atol( Buffer ); return NULL; } /*************************************************************************/ static const char *set_maintenance_week( cmd_parms *parms, void *myconfig, char *Buffer ) { maintenance_config *cfg = (maintenance_config *)myconfig; if( cfg->week >= 0 ) { return "duplicate entry for MaintenanceWeek."; } if( strcasecmp( "Sun", Buffer ) == 0 ) { cfg->week = 0; } else if( strcasecmp( "Mon", Buffer ) == 0 ) { cfg->week = 1; } else if( strcasecmp( "Tue", Buffer ) == 0 ) { cfg->week = 2; } else if( strcasecmp( "Wed", Buffer ) == 0 ) { cfg->week = 3; } else if( strcasecmp( "Thu", Buffer ) == 0 ) { cfg->week = 4; } else if( strcasecmp( "Fri", Buffer ) == 0 ) { cfg->week = 5; } else if( strcasecmp( "Sat", Buffer ) == 0 ) { cfg->week = 6; } else { return "unknown parameter in MaintenanceWeek."; } return NULL; } /*************************************************************************/ static int maintenance_getenv( request_rec *rec, maintenance_config *cfg ) { const char *agent; int Result; Result = 0; agent = ap_table_get( rec->headers_in, "User-Agent" ); if( strncmp( agent, "DoCoMo", 6 ) == 0 ) { if( !cfg->location_docomo ) { return Result; } Result = 2; } else if( strncmp( agent, "UP.Browser", 10 ) == 0 || strncmp( agent, "KDDI-", 5 ) == 0 ) { if( !cfg->location_ezweb ) { return Result; } Result = 3; } else if( strncmp( agent, "J-PHONE", 7 ) == 0 || strncmp( agent, "Vodafone", 8 ) == 0 || strncmp( agent, "MOT-", 4 ) == 0 || strncmp( agent, "J-EMULATOR", 10 ) == 0 || strncmp( agent, "SoftBank", 8 ) == 0 || strncmp( agent, "Vemulator", 9 ) == 0 || strncmp( agent, "Semulator", 9 ) == 0 ) { if( !cfg->location_softbank ) { return Result; } Result = 4; } else { if( !cfg->location_pc ) { return Result; } Result = 1; } return Result; } /*************************************************************************/ static int maintenance_is_check( request_rec *rec ) { maintenance_config *cfg = (maintenance_config *)ap_get_module_config( rec->per_dir_config, &maintenance_module ); char *url; int Result; time_t timer; struct tm *localtimer; char Buffer[10]; long target_time; long target_week; timer = time( NULL ); localtimer = localtime( &timer ); Buffer[0] = '\0'; sprintf( Buffer, "%02d%02d%02d", localtimer->tm_hour, localtimer->tm_min, localtimer->tm_sec ); target_time = atol( Buffer ); target_week = localtimer->tm_wday; if( cfg->week >= 0 && cfg->week != target_week ) { return DECLINED; } if( cfg->start_time < 0 || cfg->end_time < 0 ) { return DECLINED; } Result = maintenance_getenv( rec, cfg ); if( !Result ) { return DECLINED; } if( !( cfg->start_time <= target_time && target_time <= cfg->end_time ) ) { Result = 0; } if( Result ) { switch( Result ) { case 4 : { if( cfg->location_softbank[0] == '/' ) { if( strcmp( cfg->location_softbank, rec->uri ) == 0 ) { return DECLINED; } else { url = ap_construct_url( rec->pool, cfg->location_softbank, rec ); } } else { url = cfg->location_softbank; } break; } case 3 : { if( cfg->location_ezweb[0] == '/' ) { if( strcmp( cfg->location_ezweb, rec->uri ) == 0 ) { return DECLINED; } else { url = ap_construct_url( rec->pool, cfg->location_ezweb, rec ); } } else { url = cfg->location_ezweb; } break; } case 2 : { if( cfg->location_docomo[0] == '/' ) { if( strcmp( cfg->location_docomo, rec->uri ) == 0 ) { return DECLINED; } else { url = ap_construct_url( rec->pool, cfg->location_docomo, rec ); } } else { url = cfg->location_docomo; } break; } default : { if( cfg->location_pc[0] == '/' ) { if( strcmp( cfg->location_pc, rec->uri ) == 0 ) { return DECLINED; } else { url = ap_construct_url( rec->pool, cfg->location_pc, rec ); } } else { url = cfg->location_pc; } break; } } ap_table_setn( rec->headers_out, "Location", url ); return HTTP_MOVED_TEMPORARILY; } return DECLINED; } /************************************************************************** define of utility functions **************************************************************************/ static int maintenance_is_digit( const char *Buffer ) { if( !ap_isdigit( *Buffer ) ) { return 0; } while( ap_isdigit( *( ++Buffer ) ) ) { } return *Buffer == '\0' ? 1 : 0; } /************************************************************************** Dispatch list for API hooks **************************************************************************/ static command_rec maintenance_cmds[] = { { "MaintenanceLocationURL_PC", set_maintenance_location_pc, NULL, OR_LIMIT, TAKE1, "specify location start URL for PC" }, { "MaintenanceLocationURL_DOCOMO", set_maintenance_location_docomo, NULL, OR_LIMIT, TAKE1, "specify location start URL for DOCOMO" }, { "MaintenanceLocationURL_EZWEB", set_maintenance_location_ezweb, NULL, OR_LIMIT, TAKE1, "specify location start URL for EZWEB" }, { "MaintenanceLocationURL_SOFTBANK", set_maintenance_location_softbank, NULL, OR_LIMIT, TAKE1, "specify location start URL for SOFTBANK" }, { "MaintenanceStartTime", set_maintenance_start_time, NULL, OR_LIMIT, TAKE1, "specify start TIME" }, { "MaintenanceEndTime", set_maintenance_end_time, NULL, OR_LIMIT, TAKE1, "specify start TIME" }, { "MaintenanceWeek", set_maintenance_week, NULL, OR_LIMIT, TAKE1, "specify Maintenance Week(Sun or Mon or Tue or Wed or Thu or Fri or Sat)" }, { NULL } }; module MODULE_VAR_EXPORT maintenance_module = { STANDARD_MODULE_STUFF, NULL, /* module initializer */ maintenance_cdir_config, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ maintenance_cmds, /* table of config file commands */ NULL, /* [#8] MIME-typed-dispatched handlers */ NULL, /* [#1] URI to filename translation */ NULL, /* [#4] validate user id from request */ NULL, /* [#5] check if the user is ok _here_ */ maintenance_is_check, /* [#3] check access by host address */ NULL, /* [#6] determine MIME type */ NULL, /* [#7] pre-run fixups */ NULL, /* [#9] log a transaction */ NULL, /* [#2] header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* [#0] post read-request */ };
Linux(Debian 4.0 2.6.18-5-686) とSolaris10(sparc)で確認しています。
コンテンツを置く場所を持っていないので、ここに貼り付けてるのはスミマセン。