diff options
260 files changed, 7230 insertions, 4267 deletions
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot Binary files differindex c152bd51cb..6f7fb5d7ca 100644 --- a/bootstrap/bin/start.boot +++ b/bootstrap/bin/start.boot diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot Binary files differindex c152bd51cb..6f7fb5d7ca 100644 --- a/bootstrap/bin/start_clean.boot +++ b/bootstrap/bin/start_clean.boot diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam Binary files differindex bc93332a44..8684b356ff 100644 --- a/bootstrap/lib/compiler/ebin/beam_asm.beam +++ b/bootstrap/lib/compiler/ebin/beam_asm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam Binary files differindex a8465b366c..6513a0f33b 100644 --- a/bootstrap/lib/compiler/ebin/beam_block.beam +++ b/bootstrap/lib/compiler/ebin/beam_block.beam diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam Binary files differindex ef7f24b0db..fb414eb9b1 100644 --- a/bootstrap/lib/compiler/ebin/beam_bool.beam +++ b/bootstrap/lib/compiler/ebin/beam_bool.beam diff --git a/bootstrap/lib/compiler/ebin/beam_clean.beam b/bootstrap/lib/compiler/ebin/beam_clean.beam Binary files differindex 3d9d9f3625..abe390267e 100644 --- a/bootstrap/lib/compiler/ebin/beam_clean.beam +++ b/bootstrap/lib/compiler/ebin/beam_clean.beam diff --git a/bootstrap/lib/compiler/ebin/beam_dict.beam b/bootstrap/lib/compiler/ebin/beam_dict.beam Binary files differindex 165d848a9a..89867ee4a3 100644 --- a/bootstrap/lib/compiler/ebin/beam_dict.beam +++ b/bootstrap/lib/compiler/ebin/beam_dict.beam diff --git a/bootstrap/lib/compiler/ebin/beam_except.beam b/bootstrap/lib/compiler/ebin/beam_except.beam Binary files differindex 16d2a29491..5a23c95f54 100644 --- a/bootstrap/lib/compiler/ebin/beam_except.beam +++ b/bootstrap/lib/compiler/ebin/beam_except.beam diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam Binary files differindex 314c300b1f..ff455ce50f 100644 --- a/bootstrap/lib/compiler/ebin/beam_utils.beam +++ b/bootstrap/lib/compiler/ebin/beam_utils.beam diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam Binary files differindex e769659772..fed0bb3c48 100644 --- a/bootstrap/lib/compiler/ebin/beam_validator.beam +++ b/bootstrap/lib/compiler/ebin/beam_validator.beam diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam Binary files differindex bcb9802ba3..fcd22e932e 100644 --- a/bootstrap/lib/compiler/ebin/cerl_inline.beam +++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam Binary files differindex c2114e516a..34b3cc86a9 100644 --- a/bootstrap/lib/compiler/ebin/compile.beam +++ b/bootstrap/lib/compiler/ebin/compile.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam b/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam Binary files differindex a3a8de17c0..120c4f4a76 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex b170623982..5c87bdd3dd 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_inline.beam b/bootstrap/lib/compiler/ebin/sys_core_inline.beam Binary files differindex 29e35496b6..1e358ee0ea 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_inline.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_inline.beam diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam Binary files differindex e38d58d349..c683fc6c46 100644 --- a/bootstrap/lib/compiler/ebin/v3_codegen.beam +++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 2f0d81251a..8004afb882 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam Binary files differindex a3d29bed82..0566a7ff51 100644 --- a/bootstrap/lib/compiler/ebin/v3_kernel.beam +++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam Binary files differindex 73ce589a8c..590b9a54b0 100644 --- a/bootstrap/lib/kernel/ebin/application_controller.beam +++ b/bootstrap/lib/kernel/ebin/application_controller.beam diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam Binary files differindex 265d714238..430c2e0733 100644 --- a/bootstrap/lib/kernel/ebin/code_server.beam +++ b/bootstrap/lib/kernel/ebin/code_server.beam diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam Binary files differindex 1b160a7c12..8a7d6a8388 100644 --- a/bootstrap/lib/kernel/ebin/disk_log.beam +++ b/bootstrap/lib/kernel/ebin/disk_log.beam diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam Binary files differindex 12d2523889..5193dfa53d 100644 --- a/bootstrap/lib/kernel/ebin/disk_log_1.beam +++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam diff --git a/bootstrap/lib/kernel/ebin/file_io_server.beam b/bootstrap/lib/kernel/ebin/file_io_server.beam Binary files differindex a611bdc2b4..dfaa1b07f0 100644 --- a/bootstrap/lib/kernel/ebin/file_io_server.beam +++ b/bootstrap/lib/kernel/ebin/file_io_server.beam diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam Binary files differindex c44ac55d16..1629089858 100644 --- a/bootstrap/lib/kernel/ebin/global.beam +++ b/bootstrap/lib/kernel/ebin/global.beam diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam Binary files differindex 261e7fa6d0..fe203f816f 100644 --- a/bootstrap/lib/kernel/ebin/inet.beam +++ b/bootstrap/lib/kernel/ebin/inet.beam diff --git a/bootstrap/lib/kernel/ebin/inet_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam Binary files differindex 92dabef630..9fd86024e0 100644 --- a/bootstrap/lib/kernel/ebin/inet_dns.beam +++ b/bootstrap/lib/kernel/ebin/inet_dns.beam diff --git a/bootstrap/lib/kernel/ebin/inet_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam Binary files differindex c590292850..2636552e92 100644 --- a/bootstrap/lib/kernel/ebin/inet_res.beam +++ b/bootstrap/lib/kernel/ebin/inet_res.beam diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam Binary files differindex 722fcdefed..33193008c7 100644 --- a/bootstrap/lib/kernel/ebin/net_kernel.beam +++ b/bootstrap/lib/kernel/ebin/net_kernel.beam diff --git a/bootstrap/lib/kernel/ebin/ram_file.beam b/bootstrap/lib/kernel/ebin/ram_file.beam Binary files differindex 74fcc898c3..4d6df15730 100644 --- a/bootstrap/lib/kernel/ebin/ram_file.beam +++ b/bootstrap/lib/kernel/ebin/ram_file.beam diff --git a/bootstrap/lib/stdlib/ebin/base64.beam b/bootstrap/lib/stdlib/ebin/base64.beam Binary files differindex 54ea68b9c0..e8d4b44102 100644 --- a/bootstrap/lib/stdlib/ebin/base64.beam +++ b/bootstrap/lib/stdlib/ebin/base64.beam diff --git a/bootstrap/lib/stdlib/ebin/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam Binary files differindex d496dbebbb..b22233171b 100644 --- a/bootstrap/lib/stdlib/ebin/beam_lib.beam +++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam Binary files differindex 6984331480..cb4da358d6 100644 --- a/bootstrap/lib/stdlib/ebin/dets_utils.beam +++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam Binary files differindex 2a670d30df..87e3caec1e 100644 --- a/bootstrap/lib/stdlib/ebin/dets_v8.beam +++ b/bootstrap/lib/stdlib/ebin/dets_v8.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam Binary files differindex 7d7a926a6c..c85adabcae 100644 --- a/bootstrap/lib/stdlib/ebin/dets_v9.beam +++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam Binary files differindex 7e797acf16..d58dd86070 100644 --- a/bootstrap/lib/stdlib/ebin/erl_eval.beam +++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex 2bab926e97..10d32c9865 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam Binary files differindex 4b5d3467c1..851270bd37 100644 --- a/bootstrap/lib/stdlib/ebin/erl_scan.beam +++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam Binary files differindex e660705631..401b41a2f5 100644 --- a/bootstrap/lib/stdlib/ebin/escript.beam +++ b/bootstrap/lib/stdlib/ebin/escript.beam diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam Binary files differindex 2de24e86b3..8d024aaa99 100644 --- a/bootstrap/lib/stdlib/ebin/ets.beam +++ b/bootstrap/lib/stdlib/ebin/ets.beam diff --git a/bootstrap/lib/stdlib/ebin/eval_bits.beam b/bootstrap/lib/stdlib/ebin/eval_bits.beam Binary files differindex e92fadd53c..6627e1132c 100644 --- a/bootstrap/lib/stdlib/ebin/eval_bits.beam +++ b/bootstrap/lib/stdlib/ebin/eval_bits.beam diff --git a/bootstrap/lib/stdlib/ebin/file_sorter.beam b/bootstrap/lib/stdlib/ebin/file_sorter.beam Binary files differindex a2825af89a..1c0353488e 100644 --- a/bootstrap/lib/stdlib/ebin/file_sorter.beam +++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam Binary files differindex a558c5cbef..d3700da35e 100644 --- a/bootstrap/lib/stdlib/ebin/filename.beam +++ b/bootstrap/lib/stdlib/ebin/filename.beam diff --git a/bootstrap/lib/stdlib/ebin/orddict.beam b/bootstrap/lib/stdlib/ebin/orddict.beam Binary files differindex 722117e542..5fea6d0622 100644 --- a/bootstrap/lib/stdlib/ebin/orddict.beam +++ b/bootstrap/lib/stdlib/ebin/orddict.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam Binary files differindex d3ef6e3b36..ec3f0d174e 100644 --- a/bootstrap/lib/stdlib/ebin/qlc.beam +++ b/bootstrap/lib/stdlib/ebin/qlc.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam Binary files differindex 7ac58096e7..5c89047e67 100644 --- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam +++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam Binary files differindex 6f21292509..90d82c23c0 100644 --- a/bootstrap/lib/stdlib/ebin/sofs.beam +++ b/bootstrap/lib/stdlib/ebin/sofs.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam Binary files differindex cfc34ae41e..d1d1131c06 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor.beam diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam Binary files differindex 5484f5ac35..76342ef108 100644 --- a/bootstrap/lib/stdlib/ebin/unicode.beam +++ b/bootstrap/lib/stdlib/ebin/unicode.beam diff --git a/erts/configure.in b/erts/configure.in index 3b4c46d4a5..cf21d0cbfc 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1336,7 +1336,7 @@ TERMCAP_LIB= if test "x$with_termcap" != "xno" && test "X$host" != "Xwin32"; then # try these libs - termcap_libs="ncurses curses termcap termlib" + termcap_libs="tinfo ncurses curses termcap termlib" for termcap_lib in $termcap_libs; do AC_CHECK_LIB($termcap_lib, tgetent, TERMCAP_LIB="-l$termcap_lib") diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 711473afd2..124302a2cb 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -6008,6 +6008,13 @@ ok <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p> </item> + <tag><marker id="system_info_otp_correction_package"><c>otp_correction_package</c></marker></tag> + <item> + <p>Returns a string containing the OTP correction package version + number that currenly executing VM is part of. Note that other + OTP applications in the system may be part of other OTP correction + packages.</p> + </item> <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag> <item> <p>Returns a string containing the OTP release number.</p> diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml index 180447cac4..d2b09d4515 100644 --- a/erts/doc/src/escript.xml +++ b/erts/doc/src/escript.xml @@ -44,6 +44,7 @@ <p><c>escript</c> runs a script written in Erlang.</p> <p>Here follows an example.</p> <pre> +$ <input>chmod u+x factorial</input> $ <input>cat factorial</input> #!/usr/bin/env escript %% -*- erlang -*- @@ -66,12 +67,13 @@ usage() -> fac(0) -> 1; fac(N) -> N * fac(N-1). -$ <input>factorial 5</input> +$ <input>./factorial 5</input> factorial 5 = 120 -$ <input>factorial</input> +$ <input>./factorial</input> usage: factorial integer -$ <input>factorial five</input> -usage: factorial integer </pre> +$ <input>./factorial five</input> +usage: factorial integer + </pre> <p>The header of the Erlang script in the example differs from a normal Erlang module. The first line is intended to be the interpreter line, which invokes <c>escript</c>. However if you diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 5638683f88..b270099566 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -575,7 +575,7 @@ GENERATE += $(TTF_DIR)/erl_alloc_types.h # version include file $(TARGET)/erl_version.h: ../vsn.mk - $(gen_verbose)LANG=C $(PERL) utils/make_version -o $@ $(SYSTEM_VSN) $(VSN)$(SERIALNO) $(TARGET) + $(gen_verbose)LANG=C $(PERL) utils/make_version -o $@ $(SYSTEM_VSN) $(SYSTEM_CP_VSN) $(VSN)$(SERIALNO) $(TARGET) GENERATE += $(TARGET)/erl_version.h # driver table diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 78ab6fa30f..b413f0e859 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -48,7 +48,7 @@ # define OpCase(OpCode) case op_##OpCode # define CountCase(OpCode) case op_count_##OpCode # define OpCode(OpCode) ((Uint*)op_##OpCode) -# define Goto(Rel) {Go = (int)(Rel); goto emulator_loop;} +# define Goto(Rel) {Go = (int)(UWord)(Rel); goto emulator_loop;} # define LabelAddr(Addr) &&##Addr #else # define OpCase(OpCode) lb_##OpCode @@ -133,7 +133,7 @@ do { \ /* We don't check the range if an ordinary switch is used */ #ifdef NO_JUMP_TABLE -#define VALID_INSTR(IP) (0 <= (int)(IP) && ((int)(IP) < (NUMBER_OF_OPCODES*2+10))) +#define VALID_INSTR(IP) ((UWord)(IP) < (NUMBER_OF_OPCODES*2+10)) #else #define VALID_INSTR(IP) \ ((SWord)LabelAddr(emulator_loop) <= (SWord)(IP) && \ @@ -4326,7 +4326,19 @@ void process_main(void) flags = Arg(2); BsGetFieldSize(tmp_arg2, (flags >> 3), ClauseFail(), size); if (size >= SMALL_BITS) { - Uint wordsneeded = 1+WSIZE(NBYTES((Uint) size)); + Uint wordsneeded; + /* check bits size before potential gc. + * We do not want a gc and then realize we don't need + * the allocated space (i.e. if the op fails) + * + * remember to reacquire the matchbuffer after gc. + */ + + mb = ms_matchbuffer(tmp_arg1); + if (mb->size - mb->offset < size) { + ClauseFail(); + } + wordsneeded = 1+WSIZE(NBYTES((Uint) size)); TestHeapPreserve(wordsneeded, Arg(1), tmp_arg1); } mb = ms_matchbuffer(tmp_arg1); diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 32308fae9b..b4e52770e3 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2013. All Rights Reserved. +# Copyright Ericsson AB 2003-2014. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -150,7 +150,7 @@ type LINK_LH STANDARD PROCESSES link_lh type SUSPEND_MON STANDARD PROCESSES suspend_monitor type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend type PROC_LIST SHORT_LIVED PROCESSES proc_list -type EXTRA_ROOT SHORT_LIVED PROCESSES extra_root +type SAVED_ESTACK SHORT_LIVED PROCESSES saved_estack type FUN_ENTRY LONG_LIVED CODE fun_entry type ATOM_TXT LONG_LIVED ATOM atom_text type BEAM_REGISTER EHEAP PROCESSES beam_register diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 414ae2f046..e0b654cb22 100755 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -64,8 +64,10 @@ static Export *gather_gc_info_res_trap; #define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1) +static char otp_correction_package[] = ERLANG_OTP_CORRECTION_PACKAGE; /* Keep erts_system_version as a global variable for easy access from a core */ static char erts_system_version[] = ("Erlang/OTP " ERLANG_OTP_RELEASE + "%s" " [erts-" ERLANG_VERSION "]" #if !HEAP_ON_C_STACK && !HALFWORD_HEAP " [no-c-stack-objects]" @@ -304,11 +306,28 @@ make_link_list(Process *p, ErtsLink *root, Eterm tail) int erts_print_system_version(int to, void *arg, Process *c_p) { + int i, rc = -1; + char *rc_str = ""; + char rc_buf[100]; + char *ocp = otp_correction_package; #ifdef ERTS_SMP Uint total, online, active; (void) erts_schedulers_state(&total, &online, &active, 0); #endif - return erts_print(to, arg, erts_system_version + for (i = 0; i < sizeof(otp_correction_package)-4; i++) { + if (ocp[i] == '-' && ocp[i+1] == 'r' && ocp[i+2] == 'c') + rc = atoi(&ocp[i+3]); + } + if (rc >= 0) { + if (rc == 0) + rc_str = " [DEVELOPMENT]"; + else { + erts_snprintf(rc_buf, sizeof(rc_buf), " [RELEASE CANDIDATE %d]", rc); + rc_str = rc_buf; + } + } + return erts_print(to, arg, erts_system_version, + rc_str #ifdef ERTS_SMP , total, online #endif @@ -2417,6 +2436,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) DECL_AM(unknown); BIF_RET(AM_unknown); } + } else if (ERTS_IS_ATOM_STR("otp_correction_package", BIF_ARG_1)) { + int n = sizeof(ERLANG_OTP_CORRECTION_PACKAGE)-1; + hp = HAlloc(BIF_P, 2*n); + BIF_RET(buf_to_intlist(&hp, ERLANG_OTP_CORRECTION_PACKAGE, n, NIL)); } else if (ERTS_IS_ATOM_STR("otp_release", BIF_ARG_1)) { int n = sizeof(ERLANG_OTP_RELEASE)-1; hp = HAlloc(BIF_P, 2*n); diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index c5585d39e8..8ff6f9a3b9 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2013. All Rights Reserved. + * Copyright Ericsson AB 2002-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -1975,17 +1975,6 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset) ++n; } - /* - * A trapping BIF can add to rootset by setting the extra_root - * in the process_structure. - */ - if (p->extra_root != NULL) { - roots[n].v = p->extra_root->objv; - roots[n].sz = p->extra_root->sz; - ++n; - } - - ASSERT((is_nil(p->seq_trace_token) || is_tuple(follow_moved(p->seq_trace_token)) || is_atom(p->seq_trace_token))); @@ -2563,11 +2552,6 @@ offset_one_rootset(Process *p, Sint offs, char* area, Uint area_size, p->dictionary->used, offs, area, area_size); } - if (p->extra_root != NULL) { - offset_heap_ptr(p->extra_root->objv, - p->extra_root->sz, - offs, area, area_size); - } offset_heap_ptr(&p->fvalue, 1, offs, area, area_size); offset_heap_ptr(&p->ftrace, 1, offs, area, area_size); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 21fd8dd50a..9983a26688 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -8755,7 +8755,6 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). p->htop = p->heap; p->heap_sz = sz; p->catches = 0; - p->extra_root = NULL; p->bin_vheap_sz = p->min_vheap_size; p->bin_old_vheap_sz = p->min_vheap_size; @@ -10219,12 +10218,6 @@ erts_continue_exit_process(Process *p) if (pbt) erts_free(ERTS_ALC_T_BPD, (void *) pbt); - if (p->extra_root != NULL) { - (p->extra_root->cleanup)(p->extra_root); /* Should deallocate - whole structure */ - p->extra_root = NULL; - } - delete_process(p); #ifdef ERTS_SMP diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 043621125c..e35d1c785c 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -711,13 +711,6 @@ struct ErtsPendingSuspend_ { #endif -typedef struct ErlExtraRootSet_ ErlExtraRootSet; -struct ErlExtraRootSet_ { - Eterm *objv; - Uint sz; - void (*cleanup)(ErlExtraRootSet *); -}; - /* Defines to ease the change of memory architecture */ # define HEAP_START(p) (p)->heap # define HEAP_TOP(p) (p)->htop @@ -811,8 +804,6 @@ struct process { ErlMessageQueue msg; /* Message queue */ - ErlExtraRootSet *extra_root; /* Used by trapping BIF's */ - union { ErtsBifTimer *bif_timers; /* Bif timers aiming at this process */ void *terminate; diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 2cb44a5b64..5e7a5cab6e 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -87,7 +87,8 @@ static Export term_to_binary_trap_export; static byte* enc_term(ErtsAtomCacheMap *, Eterm, byte*, Uint32, struct erl_off_heap_header** off_heap); -static int enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, +struct TTBEncodeContext_; +static int enc_term_int(struct TTBEncodeContext_*,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, struct erl_off_heap_header** off_heap, Sint *reds, byte **res); static Uint is_external_string(Eterm obj, int* p_is_string); static byte* enc_atom(ErtsAtomCacheMap *, Eterm, byte*, Uint32); @@ -103,7 +104,8 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla Binary *context_b); static Uint encode_size_struct2(ErtsAtomCacheMap *, Eterm, unsigned); -static int encode_size_struct_int(Process *p, ErtsAtomCacheMap *acmp, Eterm obj, +struct TTBSizeContext_; +static int encode_size_struct_int(struct TTBSizeContext_*, ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags, Sint *reds, Uint *res); static Export binary_to_term_trap_export; @@ -1086,7 +1088,6 @@ BIF_RETTYPE term_to_binary_2(BIF_ALIST_2) int level = 0; Uint flags = TERM_TO_BINARY_DFLAGS; Eterm res; - Binary *bin = NULL; while (is_list(Flags)) { Eterm arg = CAR(list_val(Flags)); @@ -1123,7 +1124,7 @@ BIF_RETTYPE term_to_binary_2(BIF_ALIST_2) goto error; } - res = erts_term_to_binary_int(p, Term, level, flags, bin); + res = erts_term_to_binary_int(p, Term, level, flags, NULL); if (is_tuple(res)) { erts_set_gc_state(p, 0); BIF_TRAP1(&term_to_binary_trap_export,BIF_P,res); @@ -1726,14 +1727,20 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) { typedef enum { TTBSize, TTBEncode, TTBCompress } TTBState; -typedef struct { +typedef struct TTBSizeContext_ { Uint flags; int level; + Uint result; + Eterm obj; + ErtsEStack estack; } TTBSizeContext; -typedef struct { +typedef struct TTBEncodeContext_ { Uint flags; int level; + byte* ep; + Eterm obj; + ErtsWStack wstack; Binary *result_bin; } TTBEncodeContext; @@ -1763,8 +1770,10 @@ static void ttb_context_destructor(Binary *context_bin) context->alive = 0; switch (context->state) { case TTBSize: + DESTROY_SAVED_ESTACK(&context->s.sc.estack); break; case TTBEncode: + DESTROY_SAVED_WSTACK(&context->s.ec.wstack); if (context->s.ec.result_bin != NULL) { /* Set to NULL if ever made alive! */ ASSERT(erts_refc_read(&(context->s.ec.result_bin->refc),0) == 0); erts_bin_free(context->s.ec.result_bin); @@ -1829,6 +1838,7 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla /* Setup enough to get started */ context->state = TTBSize; context->alive = 1; + context->s.sc.estack.start = NULL; context->s.sc.flags = flags; context->s.sc.level = level; } else { @@ -1844,7 +1854,8 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla int level; Uint flags; /* Try for fast path */ - if (encode_size_struct_int(p, NULL, Term, context->s.sc.flags, &reds, &size) < 0) { + if (encode_size_struct_int(&context->s.sc, NULL, Term, + context->s.sc.flags, &reds, &size) < 0) { EXPORT_CONTEXT(); /* Same state */ RETURN_STATE(); @@ -1870,6 +1881,7 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla context->state = TTBEncode; context->s.ec.flags = flags; context->s.ec.level = level; + context->s.ec.wstack.wstart = NULL; context->s.ec.result_bin = result_bin; break; } @@ -1881,7 +1893,7 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla Binary *result_bin; flags = context->s.ec.flags; - if (enc_term_int(p,NULL,Term, bytes+1, flags, NULL, &reds, &endp) < 0) { + if (enc_term_int(&context->s.ec, NULL,Term, bytes+1, flags, NULL, &reds, &endp) < 0) { EXPORT_CONTEXT(); RETURN_STATE(); } @@ -2289,27 +2301,6 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete #define ENC_PATCH_FUN_SIZE ((Eterm) 2) #define ENC_LAST_ARRAY_ELEMENT ((Eterm) 3) -/* Free extra rootset (used when trapping) */ -static void cleanup_ttb_extra_root(ErlExtraRootSet *rs) -{ - if (rs->objv != NULL) { - erts_free(ERTS_ALC_T_EXTRA_ROOT, rs->objv); - } - erts_free(ERTS_ALC_T_EXTRA_ROOT, rs); -} - -/* Same as above, but we have an extra "stack" beyond GC reach, i.e. an array of two extra roots */ -static void cleanup_ttb_extra_root_2(ErlExtraRootSet *rs) -{ - if (rs->objv != NULL) { - erts_free(ERTS_ALC_T_EXTRA_ROOT, rs->objv); - } - if (rs[1].objv != NULL) { - erts_free(ERTS_ALC_T_EXTRA_ROOT, rs[1].objv); - } - - erts_free(ERTS_ALC_T_EXTRA_ROOT, rs); -} static byte* enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, @@ -2321,39 +2312,43 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, } static int -enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, +enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, struct erl_off_heap_header** off_heap, Sint *reds, byte **res) { - DECLARE_ESTACK(s); - DECLARE_WSTACK(com); + DECLARE_WSTACK(s); Uint n; Uint i; Uint j; Uint* ptr; Eterm val; FloatDef f; - int count_reds = (p != NULL && reds != NULL); Sint r = 0; +#if HALFWORD_HEAP + UWord wobj; +#endif + - if (count_reds) { - ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_EXTRA_ROOT); - WSTACK_CHANGE_ALLOCATOR(com, ERTS_ALC_T_EXTRA_ROOT); + if (ctx) { + WSTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK); r = *reds; - } - if (p && p->extra_root) { /* restore saved stacks and byte pointer */ - ESTACK_RESTORE(s,p->extra_root[0].objv, p->extra_root[0].sz); - obj = ESTACK_POP(s); - WSTACK_RESTORE(com, p->extra_root[1].objv, p->extra_root[1].sz); - ep = (byte *) WSTACK_POP(com); + if (ctx->wstack.wstart) { /* restore saved stacks and byte pointer */ + WSTACK_RESTORE(s, &ctx->wstack); + ep = ctx->ep; + obj = ctx->obj; + } } goto L_jump_start; outer_loop: - while (!ESTACK_ISEMPTY(s)) { - obj = ESTACK_POP(s); - switch (val = WSTACK_POP(com)) { + while (!WSTACK_ISEMPTY(s)) { +#if HALFWORD_HEAP + obj = (Eterm) (wobj = WSTACK_POP(s)); +#else + obj = WSTACK_POP(s); +#endif + switch (val = WSTACK_POP(s)) { case ENC_TERM: break; case ENC_ONE_CONS: @@ -2364,55 +2359,52 @@ enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dfla obj = CAR(cons); tl = CDR(cons); - WSTACK_PUSH(com, is_list(tl) ? ENC_ONE_CONS : ENC_TERM); - ESTACK_PUSH(s, tl); + WSTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM); + WSTACK_PUSH(s, tl); } break; case ENC_PATCH_FUN_SIZE: - /* obj will be discarded, it was NIL */ { - byte* size_p = (byte *) WSTACK_POP(com); +#if HALFWORD_HEAP + byte* size_p = (byte *) wobj; +#else + byte* size_p = (byte *) obj; +#endif put_int32(ep - size_p, size_p); } goto outer_loop; case ENC_LAST_ARRAY_ELEMENT: /* obj is the tuple */ { - Eterm* ptr = tuple_val(obj); - i = arityval(*ptr); - obj = ptr[i]; +#if HALFWORD_HEAP + Eterm* ptr = (Eterm *) wobj; +#else + Eterm* ptr = (Eterm *) obj; +#endif + obj = *ptr; } break; default: /* ENC_LAST_ARRAY_ELEMENT+1 and upwards */ { - Eterm* ptr = tuple_val(obj); - i = arityval(*ptr); - ESTACK_PUSH(s, obj); /* put back tuple and next element index */ - WSTACK_PUSH(com, val-1); - obj = ptr[i - (val - ENC_LAST_ARRAY_ELEMENT)]; /* the index is counting down */ +#if HALFWORD_HEAP + Eterm* ptr = (Eterm *) wobj; +#else + Eterm* ptr = (Eterm *) obj; +#endif + WSTACK_PUSH(s, val-1); + obj = *ptr++; + WSTACK_PUSH(s, (UWord)ptr); } break; } L_jump_start: - if (count_reds && --r == 0) { + if (ctx && --r == 0) { *reds = r; - ESTACK_PUSH(s,obj); /* push back current object, to be popped on restore */ - WSTACK_PUSH(com,((UWord) ep)); - if (p->extra_root == NULL) { - /* NB. Allocate an array of two "extra-roots", of which only the first element - is seen and handled by the GC. Index 1 holds the Wstack. */ - p->extra_root = erts_alloc(ERTS_ALC_T_EXTRA_ROOT, sizeof(ErlExtraRootSet)*2); - p->extra_root->objv = NULL; - p->extra_root->sz = 0; - p->extra_root->cleanup = cleanup_ttb_extra_root_2; - p->extra_root[1].objv = NULL; - p->extra_root[1].sz = 0; - p->extra_root[1].cleanup = NULL; /* Never used */ - } - ESTACK_SAVE(s, p->extra_root[0].objv, p->extra_root[0].sz); - WSTACK_SAVE(com, p->extra_root[1].objv, (p->extra_root[1].sz)); + ctx->obj = obj; + ctx->ep = ep; + WSTACK_SAVE(s, &ctx->wstack); return -1; } switch(tag_val_def(obj)) { @@ -2558,8 +2550,8 @@ enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dfla ep += 4; } if (i > 0) { - WSTACK_PUSH(com, ENC_LAST_ARRAY_ELEMENT+i-1); - ESTACK_PUSH(s, obj); + WSTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1); + WSTACK_PUSH(s, (UWord)ptr); } break; @@ -2703,9 +2695,8 @@ enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dfla int ei; *ep++ = NEW_FUN_EXT; - WSTACK_PUSH(com, (UWord) ep); /* Position for patching in size */ - WSTACK_PUSH(com, ENC_PATCH_FUN_SIZE); - ESTACK_PUSH(s,NIL); /* Will be thrown away */ + WSTACK_PUSH(s, ENC_PATCH_FUN_SIZE); + WSTACK_PUSH(s, (UWord) ep); /* Position for patching in size */ ep += 4; *ep = funp->arity; ep += 1; @@ -2722,8 +2713,8 @@ enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dfla fun_env: for (ei = funp->num_free-1; ei > 0; ei--) { - WSTACK_PUSH(com, ENC_TERM); - ESTACK_PUSH(s, (UWord) funp->env[ei]); + WSTACK_PUSH(s, ENC_TERM); + WSTACK_PUSH(s, (UWord) funp->env[ei]); } if (funp->num_free != 0) { obj = funp->env[0]; @@ -2766,13 +2757,9 @@ enc_term_int(Process *p,ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dfla break; } } - DESTROY_ESTACK(s); - DESTROY_WSTACK(com); - if (p && p->extra_root) { - cleanup_ttb_extra_root_2(p->extra_root); - p->extra_root = NULL; - } - if (count_reds) { + DESTROY_WSTACK(s); + if (ctx) { + ASSERT(ctx->wstack.wstart == NULL); *reds = r; } *res = ep; @@ -3742,26 +3729,24 @@ static Uint encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dfla } static int -encode_size_struct_int(Process *p, ErtsAtomCacheMap *acmp, Eterm obj, +encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags, Sint *reds, Uint *res) { DECLARE_ESTACK(s); Uint m, i, arity; Uint result = 0; - int count_reds = (p != NULL && reds != 0); Sint r = 0; - if (count_reds) { - ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_EXTRA_ROOT); + if (ctx) { + ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK); r = *reds; - } - - if (p && p->extra_root) { /* restore saved stack */ - ESTACK_RESTORE(s,p->extra_root->objv, p->extra_root->sz + 1); - result = ESTACK_POP(s); /*Untagged, beyond p->extra_root->sz */ - obj = ESTACK_POP(s); - } + if (ctx->estack.start) { /* restore saved stack */ + ESTACK_RESTORE(s, &ctx->estack); + result = ctx->result; + obj = ctx->obj; + } + } goto L_jump_start; @@ -3787,18 +3772,11 @@ encode_size_struct_int(Process *p, ErtsAtomCacheMap *acmp, Eterm obj, } L_jump_start: - if (count_reds && --r == 0) { + if (ctx && --r == 0) { *reds = r; - ESTACK_PUSH(s,obj); /* push back current object */ - ESTACK_PUSH(s,result); /* Untagged, will be out of GC reach */ - if (p->extra_root == NULL) { - p->extra_root = erts_alloc(ERTS_ALC_T_EXTRA_ROOT, sizeof(ErlExtraRootSet)); - p->extra_root->objv = NULL; - p->extra_root->sz = 0; - p->extra_root->cleanup = cleanup_ttb_extra_root; - } - ESTACK_SAVE(s, p->extra_root->objv, p->extra_root->sz); - --p->extra_root->sz; /* Hide result from GC */ + ctx->obj = obj; + ctx->result = result; + ESTACK_SAVE(s, &ctx->estack); return -1; } switch (tag_val_def(obj)) { @@ -4001,11 +3979,8 @@ encode_size_struct_int(Process *p, ErtsAtomCacheMap *acmp, Eterm obj, } DESTROY_ESTACK(s); - if (p && p->extra_root) { - cleanup_ttb_extra_root(p->extra_root); - p->extra_root = NULL; - } - if (count_reds) { + if (ctx) { + ASSERT(ctx->estack.start == NULL); *reds = r; } *res = result; @@ -4074,7 +4049,9 @@ init_done: switch (tag) { case INTEGER_EXT: SKIP(4); +#if !defined(ARCH_64) || HALFWORD_HEAP heap_size += BIG_UINT_HEAP_SIZE; +#endif break; case SMALL_INTEGER_EXT: SKIP(1); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 6e5d352e5b..c183c519ff 100755 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -370,231 +370,233 @@ extern int stackdump_on_exit; * DESTROY_ESTACK(Stack) */ +typedef struct { + UWord* start; + UWord* sp; + UWord* end; + ErtsAlcType_t alloc_type; +}ErtsEStack; -void erl_grow_stack(ErtsAlcType_t a_type, Eterm** start, Eterm** sp, Eterm** end); -#define ESTK_CONCAT(a,b) a##b -#define ESTK_SUBSCRIPT(s,i) *((Eterm *)((byte *)ESTK_CONCAT(s,_start) + (i))) #define DEF_ESTACK_SIZE (16) -#define DECLARE_ESTACK(s) \ - Eterm ESTK_CONCAT(s,_default_stack)[DEF_ESTACK_SIZE]; \ - Eterm* ESTK_CONCAT(s,_start) = ESTK_CONCAT(s,_default_stack); \ - Eterm* ESTK_CONCAT(s,_sp) = ESTK_CONCAT(s,_start); \ - Eterm* ESTK_CONCAT(s,_end) = ESTK_CONCAT(s,_start) + DEF_ESTACK_SIZE;\ - ErtsAlcType_t ESTK_CONCAT(s,_alloc_type) = ERTS_ALC_T_ESTACK +void erl_grow_estack(ErtsEStack*, Eterm* def_stack); +#define ESTK_CONCAT(a,b) a##b +#define ESTK_DEF_STACK(s) ESTK_CONCAT(s,_default_estack) + +#define DECLARE_ESTACK(s) \ + UWord ESTK_DEF_STACK(s)[DEF_ESTACK_SIZE]; \ + ErtsEStack s = { \ + ESTK_DEF_STACK(s), /* start */ \ + ESTK_DEF_STACK(s), /* sp */ \ + ESTK_DEF_STACK(s) + DEF_ESTACK_SIZE, /* end */ \ + ERTS_ALC_T_ESTACK /* alloc_type */ \ + } #define ESTACK_CHANGE_ALLOCATOR(s,t) \ do { \ - if (ESTK_CONCAT(s,_start) != ESTK_CONCAT(s,_default_stack)) { \ + if (s.start != ESTK_DEF_STACK(s)) { \ erl_exit(1, "Internal error - trying to change allocator " \ "type of active estack\n"); \ } \ - ESTK_CONCAT(s,_alloc_type) = (t); \ + s.alloc_type = (t); \ } while (0) +#define DESTROY_ESTACK(s) \ +do { \ + if (s.start != ESTK_DEF_STACK(s)) { \ + erts_free(s.alloc_type, s.start); \ + } \ +} while(0) + + /* - * Do not free the stack after this, it may have pointers into what - * was saved in 'v'. 'v' and 'vsize' are changed by this macro. If - * 'v' points to anything, it should have been allocated by a previous - * call to this macro. Be careful to set a correct allocator prior to - * saving. - * 'v' can be any lvalue pointer, it will point to an array of UWord - * after calling this macro. + * Do not free the stack after this, it may have pointers into what + * was saved in 'dst'. */ -#define ESTACK_SAVE(s,v,vsize) /* v and vsize are "name parameters" */ \ -do { \ - Uint _esz = ESTACK_COUNT(s); \ - if (ESTK_CONCAT(s,_start) == ESTK_CONCAT(s,_default_stack)) { \ - if ((v) == NULL) { \ - (v) = erts_alloc(ESTK_CONCAT(s,_alloc_type), \ - DEF_ESTACK_SIZE * sizeof(Eterm)); \ - } \ - memcpy((v),ESTK_CONCAT(s,_start),_esz*sizeof(Eterm)); \ - } else { \ - (v) = (void *) ESTK_CONCAT(s,_start); \ - } \ - (vsize) = _esz; \ +#define ESTACK_SAVE(s,dst)\ +do {\ + if (s.start == ESTK_DEF_STACK(s)) {\ + UWord _wsz = ESTACK_COUNT(s);\ + (dst)->start = erts_alloc(s.alloc_type,\ + DEF_ESTACK_SIZE * sizeof(UWord));\ + memcpy((dst)->start, s.start,_wsz*sizeof(UWord));\ + (dst)->sp = (dst)->start + _wsz;\ + (dst)->end = (dst)->start + DEF_ESTACK_SIZE;\ + (dst)->alloc_type = s.alloc_type;\ + } else\ + *(dst) = s;\ } while (0) -/* - * Use on empty stack, only the allocator can be changed before this - * The vector parameter is reset to NULL if the vector is moved to stack, - * otherwise it's kept for reuse, so a saved and restored vector might - * need freeing using the correct allocator parameter. - * 'v' can be any lvalue pointer, it's cast to an (Eterm *). +#define DESTROY_SAVED_ESTACK(estack)\ +do {\ + if ((estack)->start) {\ + erts_free((estack)->alloc_type, (estack)->start);\ + (estack)->start = NULL;\ + }\ +} while(0) + +/* + * Use on empty stack, only the allocator can be changed before this. + * The src stack is reset to NULL. */ -#define ESTACK_RESTORE(s, v, vsize) /*v is a "name parameter"*/ \ -do { \ - if ((vsize) > DEF_ESTACK_SIZE) { \ - Uint _ca = DEF_ESTACK_SIZE; \ - while (_ca < (vsize)) \ - _ca = _ca * 2; \ - ESTK_CONCAT(s,_start) = (Eterm *) (v); \ - ESTK_CONCAT(s,_end) = ((Eterm *)(v)) + _ca; \ - ESTK_CONCAT(s,_sp) = ESTK_CONCAT(s,_start) + (vsize); \ - (v) = NULL; \ - } else { \ - memcpy(ESTK_CONCAT(s,_start),(v),(vsize)*sizeof(Eterm));\ - ESTK_CONCAT(s,_sp) = ESTK_CONCAT(s,_start) + (vsize); \ - } \ - } while (0) +#define ESTACK_RESTORE(s, src) \ +do { \ + ASSERT(s.start == ESTK_DEF_STACK(s)); \ + s = *(src); /* struct copy */ \ + (src)->start = NULL; \ + ASSERT(s.sp >= s.start); \ + ASSERT(s.sp <= s.end); \ +} while (0) -#define ESTACK_IS_STATIC(s) (ESTK_CONCAT(s,_start) == ESTK_CONCAT(s,_default_stack)) +#define ESTACK_IS_STATIC(s) (s.start == ESTK_DEF_STACK(s))) -#define DESTROY_ESTACK(s) \ -do { \ - if (ESTK_CONCAT(s,_start) != ESTK_CONCAT(s,_default_stack)) { \ - erts_free(ESTK_CONCAT(s,_alloc_type), ESTK_CONCAT(s,_start)); \ - } \ +#define ESTACK_PUSH(s, x) \ +do { \ + if (s.sp == s.end) { \ + erl_grow_estack(&s, ESTK_DEF_STACK(s)); \ + } \ + *s.sp++ = (x); \ } while(0) -#define ESTACK_PUSH(s, x) \ -do { \ - if (ESTK_CONCAT(s,_sp) == ESTK_CONCAT(s,_end)) { \ - erl_grow_stack(ESTK_CONCAT(s,_alloc_type),&ESTK_CONCAT(s,_start), \ - &ESTK_CONCAT(s,_sp), &ESTK_CONCAT(s,_end)); \ - } \ - *ESTK_CONCAT(s,_sp)++ = (x); \ +#define ESTACK_PUSH2(s, x, y) \ +do { \ + if (s.sp > s.end - 2) { \ + erl_grow_estack(&s, ESTK_DEF_STACK(s)); \ + } \ + *s.sp++ = (x); \ + *s.sp++ = (y); \ } while(0) -#define ESTACK_PUSH2(s, x, y) \ -do { \ - if (ESTK_CONCAT(s,_sp) > ESTK_CONCAT(s,_end) - 2) { \ - erl_grow_stack(ESTK_CONCAT(s,_alloc_type),&ESTK_CONCAT(s,_start), \ - &ESTK_CONCAT(s,_sp), &ESTK_CONCAT(s,_end)); \ - } \ - *ESTK_CONCAT(s,_sp)++ = (x); \ - *ESTK_CONCAT(s,_sp)++ = (y); \ +#define ESTACK_PUSH3(s, x, y, z) \ +do { \ + if (s.sp > s.end - 3) { \ + erl_grow_estack(&s, ESTK_DEF_STACK(s)); \ + } \ + *s.sp++ = (x); \ + *s.sp++ = (y); \ + *s.sp++ = (z); \ } while(0) -#define ESTACK_PUSH3(s, x, y, z) \ -do { \ - if (ESTK_CONCAT(s,_sp) > ESTK_CONCAT(s,_end) - 3) { \ - erl_grow_stack(&ESTK_CONCAT(s,_start), &ESTK_CONCAT(s,_sp), \ - &ESTK_CONCAT(s,_end)); \ - } \ - *ESTK_CONCAT(s,_sp)++ = (x); \ - *ESTK_CONCAT(s,_sp)++ = (y); \ - *ESTK_CONCAT(s,_sp)++ = (z); \ -} while(0) +#define ESTACK_COUNT(s) (s.sp - s.start) +#define ESTACK_ISEMPTY(s) (s.sp == s.start) +#define ESTACK_POP(s) (*(--s.sp)) -#define ESTACK_COUNT(s) (ESTK_CONCAT(s,_sp) - ESTK_CONCAT(s,_start)) -#define ESTACK_ISEMPTY(s) (ESTK_CONCAT(s,_sp) == ESTK_CONCAT(s,_start)) -#define ESTACK_POP(s) (*(--ESTK_CONCAT(s,_sp))) +/* + * WSTACK: same as ESTACK but with UWord instead of Eterm + */ +typedef struct { + UWord* wstart; + UWord* wsp; + UWord* wend; + ErtsAlcType_t alloc_type; +}ErtsWStack; -void erl_grow_wstack(ErtsAlcType_t a_type, UWord** start, UWord** sp, UWord** end); -#define WSTK_CONCAT(a,b) a##b -#define WSTK_SUBSCRIPT(s,i) *((UWord *)((byte *)WSTK_CONCAT(s,_start) + (i))) #define DEF_WSTACK_SIZE (16) -#define DECLARE_WSTACK(s) \ - UWord WSTK_CONCAT(s,_default_stack)[DEF_WSTACK_SIZE]; \ - UWord* WSTK_CONCAT(s,_start) = WSTK_CONCAT(s,_default_stack); \ - UWord* WSTK_CONCAT(s,_sp) = WSTK_CONCAT(s,_start); \ - UWord* WSTK_CONCAT(s,_end) = WSTK_CONCAT(s,_start) + DEF_WSTACK_SIZE; \ - ErtsAlcType_t WSTK_CONCAT(s,_alloc_type) = ERTS_ALC_T_ESTACK +void erl_grow_wstack(ErtsWStack*, Eterm* def_stack); +#define WSTK_CONCAT(a,b) a##b +#define WSTK_DEF_STACK(s) WSTK_CONCAT(s,_default_wstack) + +#define DECLARE_WSTACK(s) \ + UWord WSTK_DEF_STACK(s)[DEF_WSTACK_SIZE]; \ + ErtsWStack s = { \ + WSTK_DEF_STACK(s), /* wstart */ \ + WSTK_DEF_STACK(s), /* wsp */ \ + WSTK_DEF_STACK(s) + DEF_WSTACK_SIZE, /* wend */ \ + ERTS_ALC_T_ESTACK /* alloc_type */ \ + } #define WSTACK_CHANGE_ALLOCATOR(s,t) \ do { \ - if (WSTK_CONCAT(s,_start) != WSTK_CONCAT(s,_default_stack)) { \ + if (s.wstart != WSTK_DEF_STACK(s)) { \ erl_exit(1, "Internal error - trying to change allocator " \ "type of active wstack\n"); \ } \ - WSTK_CONCAT(s,_alloc_type) = (t); \ + s.alloc_type = (t); \ } while (0) -#define DESTROY_WSTACK(s) \ -do { \ - if (WSTK_CONCAT(s,_start) != WSTK_CONCAT(s,_default_stack)) { \ - erts_free(WSTK_CONCAT(s,_alloc_type), WSTK_CONCAT(s,_start)); \ - } \ +#define DESTROY_WSTACK(s) \ +do { \ + if (s.wstart != WSTK_DEF_STACK(s)) { \ + erts_free(s.alloc_type, s.wstart); \ + } \ } while(0) + /* - * Do not free the stack after this, it may have pointers into what - * was saved in 'v'. 'v' and 'vsize' are changed by this macro. If - * 'v' points to anything, it should have been allocated by a previous - * call to this macro. Be careful to set a correct allocator prior to - * saving. - * 'v' can be any lvalue pointer, it will point to an array of UWord - * after calling this macro. + * Do not free the stack after this, it may have pointers into what + * was saved in 'dst'. */ -#define WSTACK_SAVE(s,v,vsize) /* v and vsize are "name parameters" */ \ -do { \ - Uint _wsz = WSTACK_COUNT(s); \ - if (WSTK_CONCAT(s,_start) == WSTK_CONCAT(s,_default_stack)) { \ - if ((v) == NULL) { \ - (v) = erts_alloc(WSTK_CONCAT(s,_alloc_type), \ - DEF_WSTACK_SIZE * sizeof(UWord)); \ - } \ - memcpy((v),WSTK_CONCAT(s,_start),_wsz*sizeof(UWord)); \ - } else { \ - (v) = (void *) WSTK_CONCAT(s,_start); \ - } \ - (vsize) = _wsz; \ +#define WSTACK_SAVE(s,dst)\ +do {\ + if (s.wstart == WSTK_DEF_STACK(s)) {\ + UWord _wsz = WSTACK_COUNT(s);\ + (dst)->wstart = erts_alloc(s.alloc_type,\ + DEF_WSTACK_SIZE * sizeof(UWord));\ + memcpy((dst)->wstart, s.wstart,_wsz*sizeof(UWord));\ + (dst)->wsp = (dst)->wstart + _wsz;\ + (dst)->wend = (dst)->wstart + DEF_WSTACK_SIZE;\ + (dst)->alloc_type = s.alloc_type;\ + } else\ + *(dst) = s;\ } while (0) -/* - * Use on empty stack, only the allocator can be changed before this - * The vector parameter is reset to NULL if the vector is moved to stack, - * otherwise it's kept for reuse, so a saved and restored vector might - * need freeing using the correct allocator parameter. - * 'v' can be any lvalue pointer, it's cast to an (UWord *). +#define DESTROY_SAVED_WSTACK(wstack)\ +do {\ + if ((wstack)->wstart) {\ + erts_free((wstack)->alloc_type, (wstack)->wstart);\ + (wstack)->wstart = NULL;\ + }\ +} while(0) + +/* + * Use on empty stack, only the allocator can be changed before this. + * The src stack is reset to NULL. */ -#define WSTACK_RESTORE(s, v, vsize) /*v is a "name parameter"*/ \ -do { \ - if ((vsize) > DEF_WSTACK_SIZE) { \ - Uint _ca = DEF_WSTACK_SIZE; \ - while (_ca < (vsize)) \ - _ca = _ca * 2; \ - WSTK_CONCAT(s,_start) = (UWord *) (v); \ - WSTK_CONCAT(s,_end) = ((UWord *)(v)) + _ca; \ - WSTK_CONCAT(s,_sp) = WSTK_CONCAT(s,_start) + (vsize); \ - (v) = NULL; \ - } else { \ - memcpy(WSTK_CONCAT(s,_start),(v),(vsize)*sizeof(UWord));\ - WSTK_CONCAT(s,_sp) = WSTK_CONCAT(s,_start) + (vsize); \ - } \ - } while (0) +#define WSTACK_RESTORE(s, src) \ +do { \ + ASSERT(s.wstart == WSTK_DEF_STACK(s)); \ + s = *(src); /* struct copy */ \ + (src)->wstart = NULL; \ + ASSERT(s.wsp >= s.wstart); \ + ASSERT(s.wsp <= s.wend); \ +} while (0) -#define WSTACK_IS_STATIC(s) (WSTK_CONCAT(s,_start) == WSTK_CONCAT(s,_default_stack)) +#define WSTACK_IS_STATIC(s) (s.wstart == WSTK_DEF_STACK(s))) -#define WSTACK_PUSH(s, x) \ -do { \ - if (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_end)) { \ - erl_grow_wstack(WSTK_CONCAT(s,_alloc_type), &WSTK_CONCAT(s,_start), \ - &WSTK_CONCAT(s,_sp), &WSTK_CONCAT(s,_end)); \ - } \ - *WSTK_CONCAT(s,_sp)++ = (x); \ +#define WSTACK_PUSH(s, x) \ +do { \ + if (s.wsp == s.wend) { \ + erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \ + } \ + *s.wsp++ = (x); \ } while(0) -#define WSTACK_PUSH2(s, x, y) \ -do { \ - if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 2) { \ - erl_grow_wstack(WSTK_CONCAT(s,_alloc_type), &WSTK_CONCAT(s,_start), \ - &WSTK_CONCAT(s,_sp), &WSTK_CONCAT(s,_end)); \ - } \ - *WSTK_CONCAT(s,_sp)++ = (x); \ - *WSTK_CONCAT(s,_sp)++ = (y); \ +#define WSTACK_PUSH2(s, x, y) \ +do { \ + if (s.wsp > s.wend - 2) { \ + erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \ + } \ + *s.wsp++ = (x); \ + *s.wsp++ = (y); \ } while(0) -#define WSTACK_PUSH3(s, x, y, z) \ -do { \ - if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 3) { \ - erl_grow_wstack(WSTK_CONCAT(s,_alloc_type), &WSTK_CONCAT(s,_start), \ - &WSTK_CONCAT(s,_sp), &WSTK_CONCAT(s,_end)); \ - } \ - *WSTK_CONCAT(s,_sp)++ = (x); \ - *WSTK_CONCAT(s,_sp)++ = (y); \ - *WSTK_CONCAT(s,_sp)++ = (z); \ +#define WSTACK_PUSH3(s, x, y, z) \ +do { \ + if (s.wsp > s.wend - 3) { \ + erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \ + } \ + *s.wsp++ = (x); \ + *s.wsp++ = (y); \ + *s.wsp++ = (z); \ } while(0) -#define WSTACK_COUNT(s) (WSTK_CONCAT(s,_sp) - WSTK_CONCAT(s,_start)) +#define WSTACK_COUNT(s) (s.wsp - s.wstart) +#define WSTACK_ISEMPTY(s) (s.wsp == s.wstart) +#define WSTACK_POP(s) (*(--s.wsp)) -#define WSTACK_ISEMPTY(s) (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_start)) -#define WSTACK_POP(s) (*(--WSTK_CONCAT(s,_sp))) /* binary.c */ diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 297c4bf439..7f8bdcb2ca 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -185,39 +185,41 @@ erts_set_hole_marker(Eterm* ptr, Uint sz) * Helper function for the ESTACK macros defined in global.h. */ void -erl_grow_stack(ErtsAlcType_t a_type, Eterm** start, Eterm** sp, Eterm** end) +erl_grow_estack(ErtsEStack* s, Eterm* default_estack) { - Uint old_size = (*end - *start); + Uint old_size = (s->end - s->start); Uint new_size = old_size * 2; - Uint sp_offs = *sp - *start; - if (new_size > 2 * DEF_ESTACK_SIZE) { - *start = erts_realloc(a_type, (void *) *start, new_size*sizeof(Eterm)); + Uint sp_offs = s->sp - s->start; + if (s->start != default_estack) { + s->start = erts_realloc(s->alloc_type, s->start, + new_size*sizeof(Eterm)); } else { - Eterm* new_ptr = erts_alloc(a_type, new_size*sizeof(Eterm)); - sys_memcpy(new_ptr, *start, old_size*sizeof(Eterm)); - *start = new_ptr; + Eterm* new_ptr = erts_alloc(s->alloc_type, new_size*sizeof(Eterm)); + sys_memcpy(new_ptr, s->start, old_size*sizeof(Eterm)); + s->start = new_ptr; } - *end = *start + new_size; - *sp = *start + sp_offs; + s->end = s->start + new_size; + s->sp = s->start + sp_offs; } /* - * Helper function for the ESTACK macros defined in global.h. + * Helper function for the WSTACK macros defined in global.h. */ void -erl_grow_wstack(ErtsAlcType_t a_type, UWord** start, UWord** sp, UWord** end) +erl_grow_wstack(ErtsWStack* s, UWord* default_wstack) { - Uint old_size = (*end - *start); + Uint old_size = (s->wend - s->wstart); Uint new_size = old_size * 2; - Uint sp_offs = *sp - *start; - if (new_size > 2 * DEF_ESTACK_SIZE) { - *start = erts_realloc(a_type, (void *) *start, new_size*sizeof(UWord)); + Uint sp_offs = s->wsp - s->wstart; + if (s->wstart != default_wstack) { + s->wstart = erts_realloc(s->alloc_type, s->wstart, + new_size*sizeof(UWord)); } else { - UWord* new_ptr = erts_alloc(a_type, new_size*sizeof(UWord)); - sys_memcpy(new_ptr, *start, old_size*sizeof(UWord)); - *start = new_ptr; + UWord* new_ptr = erts_alloc(s->alloc_type, new_size*sizeof(UWord)); + sys_memcpy(new_ptr, s->wstart, old_size*sizeof(UWord)); + s->wstart = new_ptr; } - *end = *start + new_size; - *sp = *start + sp_offs; + s->wend = s->wstart + new_size; + s->wsp = s->wstart + sp_offs; } /* CTYPE macros */ @@ -2846,7 +2848,7 @@ pop_next: return 0; not_equal: - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return j; #undef CMP_NODES diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index bce4278337..a390c536bb 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -58,10 +58,10 @@ ordering/1,unaligned_order/1,gc_test/1, bit_sized_binary_sizes/1, otp_6817/1,deep/1,obsolete_funs/1,robustness/1,otp_8117/1, - otp_8180/1, ttb_trap/1]). + otp_8180/1, trapping/1]). %% Internal exports. --export([sleeper/0,ttb_loop/2]). +-export([sleeper/0,trapping_loop/4]). suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. @@ -76,7 +76,7 @@ all() -> bad_term_to_binary, more_bad_terms, otp_5484, otp_5933, ordering, unaligned_order, gc_test, bit_sized_binary_sizes, otp_6817, otp_8117, deep, - obsolete_funs, robustness, otp_8180, ttb_trap]. + obsolete_funs, robustness, otp_8180, trapping]. groups() -> []. @@ -506,8 +506,8 @@ external_size(Config) when is_list(Config) -> io:format("Unaligned size: ~p\n", [Sz2]), ?line ?t:fail() end, - ?line erlang:external_size(Bin) =:= erlang:external_size(Bin, [{minor_version, 1}]), - ?line erlang:external_size(Unaligned) =:= erlang:external_size(Unaligned, [{minor_version, 1}]). + true = (erlang:external_size(Bin) =:= erlang:external_size(Bin, [{minor_version, 1}])), + true = (erlang:external_size(Unaligned) =:= erlang:external_size(Unaligned, [{minor_version, 1}])). external_size_1(Term, Size0, Limit) when Size0 < Limit -> case erlang:external_size(Term) of @@ -1241,16 +1241,27 @@ bsbs_1(A) -> Bin = binary_to_term_stress(<<131,$M,5:32,A,0,0,0,0,0>>), BinSize = bit_size(Bin). +%% lists:foldl(_,_,lists:seq(_,_)) with less heap consumption +lists_foldl_seq(Fun, Acc0, N, To) when N =< To -> + Acc1 = Fun(N, Acc0), + lists_foldl_seq(Fun, Acc1, N+1, To); + +lists_foldl_seq(_, Acc, _, _) -> + Acc. + deep(Config) when is_list(Config) -> - ?line deep_roundtrip(lists:foldl(fun(E, A) -> - [E,A] - end, [], lists:seq(1, 1000000))), - ?line deep_roundtrip(lists:foldl(fun(E, A) -> - {E,A} - end, [], lists:seq(1, 1000000))), - ?line deep_roundtrip(lists:foldl(fun(E, A) -> - fun() -> {E,A} end - end, [], lists:seq(1, 1000000))), + deep_roundtrip(lists_foldl_seq(fun(E, A) -> + [E,A] + end, [], 1, 1000000)), + erlang:garbage_collect(), + deep_roundtrip(lists_foldl_seq(fun(E, A) -> + {E,A} + end, [], 1, 1000000)), + erlang:garbage_collect(), + deep_roundtrip(lists_foldl_seq(fun(E, A) -> + fun() -> {E,A} end + end, [], 1, 1000000)), + erlang:garbage_collect(), ok. deep_roundtrip(T) -> @@ -1334,36 +1345,44 @@ run_otp_8180(Name) -> end || Bin <- Bins], ok. -%% Test that exit and GC during term_to_binary trap does not crash. -ttb_trap(Config) when is_list(Config)-> - case erlang:system_info(wordsize) of - N when N < 8 -> - {skipped, "Only on 64bit machines"}; - _ -> - do_ttb_trap(5) - end. +%% Test that exit and GC during trapping term_to_binary and binary_to_term +%% does not crash. +trapping(Config) when is_list(Config)-> + do_trapping(5, term_to_binary, + fun() -> [lists:duplicate(2000000,2000000)] end), + do_trapping(5, binary_to_term, + fun() -> [term_to_binary(lists:duplicate(2000000,2000000))] end). -do_ttb_trap(0) -> +do_trapping(0, _, _) -> ok; -do_ttb_trap(N) -> - Pid = spawn(?MODULE,ttb_loop,[1000,self()]), +do_trapping(N, Bif, ArgFun) -> + io:format("N=~p: Do ~p ~s gc.\n", [N, Bif, case N rem 2 of 0 -> "with"; 1 -> "without" end]), + Pid = spawn(?MODULE,trapping_loop,[Bif, ArgFun, 1000, self()]), receive ok -> ok end, receive after 100 -> ok end, - erlang:garbage_collect(Pid), - receive after 100 -> ok end, + Ref = make_ref(), + case N rem 2 of + 0 -> erlang:garbage_collect(Pid, [{async,Ref}]), + receive after 100 -> ok end; + 1 -> void + end, exit(Pid,kill), + case N rem 2 of + 0 -> receive {garbage_collect, Ref, _} -> ok end; + 1 -> void + end, receive after 1 -> ok end, - do_ttb_trap(N-1). + do_trapping(N-1, Bif, ArgFun). -ttb_loop(N,Pid) -> - Term = lists:duplicate(2000000,2000000), +trapping_loop(Bif, ArgFun, N, Pid) -> + Args = ArgFun(), Pid ! ok, - ttb_loop2(N,Term). -ttb_loop2(0,_T) -> + trapping_loop2(Bif,Args,N). +trapping_loop2(_,_,0) -> ok; -ttb_loop2(N,T) -> - apply(erlang,term_to_binary,[T]), - ttb_loop2(N-1,T). +trapping_loop2(Bif,Args,N) -> + apply(erlang,Bif,Args), + trapping_loop2(Bif, Args, N-1). %% Utilities. diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index 7087542899..06211406b4 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -2075,6 +2075,21 @@ thr_msg_blast(Config) when is_list(Config) -> Res end. +-define(IN_RANGE(LoW_, VaLuE_, HiGh_), + case in_range(LoW_, VaLuE_, HiGh_) of + true -> ok; + false -> + case erlang:system_info(lock_checking) of + true -> + ?t:format("~p:~p: Ignore bad sched count due to " + "lock checking~n", + [?MODULE,?LINE]); + false -> + ?t:fail({unexpected_sched_counts, VaLuE_}) + end + end). + + consume_timeslice(Config) when is_list(Config) -> %% %% Verify that erl_drv_consume_timeslice() works. @@ -2131,15 +2146,8 @@ consume_timeslice(Config) when is_list(Config) -> Proc1 ! Go, wait_command_msgs(Port, 10), [{Port, Sprt1}, {Proc1, Sproc1}] = count_pp_sched_stop([Port, Proc1]), - case Sprt1 of - 10 -> - true = in_range(5, Sproc1-10, 7); - _ -> - case erlang:system_info(lock_checking) of - true -> ?t:format("Ignore bad sched count due to lock checking", []); - false -> ?t:fail({unexpected_sched_counts, Sprt1, Sproc1}) - end - end, + ?IN_RANGE(10, Sprt1, 10), + ?IN_RANGE(5, Sproc1-10, 7), "disabled" = port_control(Port, $D, ""), Proc2 = spawn_link(fun () -> @@ -2160,15 +2168,8 @@ consume_timeslice(Config) when is_list(Config) -> Proc2 ! Go, wait_command_msgs(Port, 10), [{Port, Sprt2}, {Proc2, Sproc2}] = count_pp_sched_stop([Port, Proc2]), - case Sprt2 of - 10 -> - true = in_range(1, Sproc2-10, 2); - _ -> - case erlang:system_info(lock_checking) of - true -> ?t:format("Ignore bad sched count due to lock checking", []); - false -> ?t:fail({unexpected_sched_counts, Sprt2, Sproc2}) - end - end, + ?IN_RANGE(10, Sprt2, 10), + ?IN_RANGE(1, Sproc2-10, 2), "enabled" = port_control(Port, $E, ""), Proc3 = spawn_link(fun () -> @@ -2188,15 +2189,8 @@ consume_timeslice(Config) when is_list(Config) -> Proc3 ! Go, wait_command_msgs(Port, 10), [{Port, Sprt3}, {Proc3, Sproc3}] = count_pp_sched_stop([Port, Proc3]), - case Sprt3 of - 10 -> - true = in_range(5, Sproc3-10, 7); - _ -> - case erlang:system_info(lock_checking) of - true -> ?t:format("Ignore bad sched count due to lock checking", []); - false -> ?t:fail({unexpected_sched_counts, Sprt3, Sproc3}) - end - end, + ?IN_RANGE(10, Sprt3, 10), + ?IN_RANGE(5, Sproc3-10, 7), "disabled" = port_control(Port, $D, ""), Proc4 = spawn_link(fun () -> @@ -2216,15 +2210,8 @@ consume_timeslice(Config) when is_list(Config) -> Proc4 ! Go, wait_command_msgs(Port, 10), [{Port, Sprt4}, {Proc4, Sproc4}] = count_pp_sched_stop([Port, Proc4]), - case Sprt4 of - 10 -> - true = in_range(1, Sproc4-10, 2); - _ -> - case erlang:system_info(lock_checking) of - true -> ?t:format("Ignore bad sched count due to lock checking", []); - false -> ?t:fail({unexpected_sched_counts, Sprt4, Sproc4}) - end - end, + ?IN_RANGE(10, Sprt4, 10), + ?IN_RANGE(1, Sproc4-10, 2), SOnl = erlang:system_info(schedulers_online), %% If only one scheduler use port with parallelism set to true, @@ -2272,8 +2259,8 @@ consume_timeslice(Config) when is_list(Config) -> wait_procs_exit([W5, Proc5]), wait_command_msgs(Port2, 10), [{Port2, Sprt5}, {Proc5, Sproc5}] = count_pp_sched_stop([Port2, Proc5]), - true = in_range(2, Sproc5, 3), - true = in_range(7, Sprt5, 20), + ?IN_RANGE(2, Sproc5, 3), + ?IN_RANGE(6, Sprt5, 20), count_pp_sched_start(), "disabled" = port_control(Port2, $D, ""), @@ -2307,8 +2294,8 @@ consume_timeslice(Config) when is_list(Config) -> wait_procs_exit([W6, Proc6]), wait_command_msgs(Port2, 10), [{Port2, Sprt6}, {Proc6, Sproc6}] = count_pp_sched_stop([Port2, Proc6]), - true = in_range(2, Sproc6, 3), - true = in_range(3, Sprt6, 6), + ?IN_RANGE(2, Sproc6, 3), + ?IN_RANGE(2, Sprt6, 6), process_flag(scheduler, 0), @@ -2316,6 +2303,7 @@ consume_timeslice(Config) when is_list(Config) -> receive {Port2, closed} -> ok end, ok. + wait_command_msgs(_, 0) -> ok; wait_command_msgs(Port, N) -> diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl index 109cec25cb..09a7a87a9a 100644 --- a/erts/emulator/test/exception_SUITE.erl +++ b/erts/emulator/test/exception_SUITE.erl @@ -589,6 +589,13 @@ line_numbers(Config) when is_list(Config) -> [{file,ModFile},{line,_}]}|_]}} = (catch build_binary2(8, bad_binary)), + <<"abc",357:16>> = build_binary3(<<"abc">>), + {'EXIT',{badarg,[{?MODULE,build_binary3,1, + [{file,"bit_syntax.erl"},{line,72511}]}, + {?MODULE,line_numbers,1, + [{file,ModFile},{line,_}]}|_]}} = + (catch build_binary3(no_binary)), + {'EXIT',{function_clause, [{?MODULE,do_call_abs,[y,y], [{file,"gc_bif.erl"},{line,18}]}, @@ -691,6 +698,10 @@ build_binary2(Size, Bin) -> %Line 72505 id(0), %Line 72506 <<7:Size,Bin/binary>>. %Line 72507 +build_binary3(Bin) -> %Line 72509 + id(0), %Line 72510 + <<Bin/binary,357:16>>. %Line 72511 + -file("gc_bif.erl", 17). do_call_abs(x, Arg) -> %Line 18 abs(Arg). %Line 19 diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index 81539faa09..6a43e2b0e7 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -1495,7 +1495,7 @@ mcall(Node, Funs) -> end, Refs). erl_rel_flag_var() -> - "ERL_"++erlang:system_info(otp_release)++"_FLAGS". + "ERL_OTP"++erlang:system_info(otp_release)++"_FLAGS". clear_erl_rel_flags() -> EnvVar = erl_rel_flag_var(), diff --git a/erts/emulator/utils/make_version b/erts/emulator/utils/make_version index 7757fa8138..02b68f2b39 100755 --- a/erts/emulator/utils/make_version +++ b/erts/emulator/utils/make_version @@ -41,6 +41,9 @@ if ($ARGV[0] eq '-o') { my $release = shift; defined $release or die "No release specified"; +my $correction_package = shift; +defined $correction_package or die "No correction package specified"; + my $version = shift; defined $version or die "No version name specified"; @@ -53,6 +56,7 @@ open(FILE, ">$outputfile") or die "Can't create $outputfile: $!"; print FILE <<EOF; /* This file was created by 'make_version' -- don't modify. */ #define ERLANG_OTP_RELEASE "$release" +#define ERLANG_OTP_CORRECTION_PACKAGE "$correction_package" #define ERLANG_VERSION "$version" #define ERLANG_COMPILE_DATE "$time_str" #define ERLANG_ARCHITECTURE "$architecture" diff --git a/erts/epmd/src/epmd_cli.c b/erts/epmd/src/epmd_cli.c index 8817bde8d7..bd30bc35d9 100644 --- a/erts/epmd/src/epmd_cli.c +++ b/erts/epmd/src/epmd_cli.c @@ -118,7 +118,7 @@ void epmd_call(EpmdVars *g,int what) if (!g->silent) { rval = erts_snprintf(buf, OUTBUF_SIZE, "epmd: up and running on port %d with data:\n", j); - write(1, buf, rval); + fwrite(buf, 1, rval, stdout); } while(1) { if ((rval = read(fd,buf,OUTBUF_SIZE)) <= 0) { @@ -126,7 +126,7 @@ void epmd_call(EpmdVars *g,int what) epmd_cleanup_exit(g,0); } if (!g->silent) - write(1, buf, rval); /* Potentially UTF-8 encoded */ + fwrite(buf, 1, rval, stdout); /* Potentially UTF-8 encoded */ } } diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl index cc24a556a3..a752abf33b 100644 --- a/erts/epmd/test/epmd_SUITE.erl +++ b/erts/epmd/test/epmd_SUITE.erl @@ -69,6 +69,8 @@ returns_valid_empty_extra/1, returns_valid_populated_extra_with_nulls/1, + names_stdout/1, + buffer_overrun_1/1, buffer_overrun_2/1, no_nonlocal_register/1, @@ -118,6 +120,7 @@ all() -> too_large, alive_req_too_small_1, alive_req_too_small_2, alive_req_too_large, returns_valid_empty_extra, returns_valid_populated_extra_with_nulls, + names_stdout, {group, buffer_overrun}, no_nonlocal_register, no_nonlocal_kill, no_live_killing]. @@ -759,6 +762,24 @@ returns_valid_populated_extra_with_nulls(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +names_stdout(doc) -> + ["Test that epmd -names prints registered nodes to stdout"]; +names_stdout(suite) -> + []; +names_stdout(Config) when is_list(Config) -> + ?line ok = epmdrun(), + ?line {ok,Sock} = register_node("foobar"), + ?line ok = epmdrun("-names"), + ?line {ok, Data} = receive {_Port, {data, D}} -> {ok, D} + after 10000 -> {error, timeout} + end, + ?line {match,_} = re:run(Data, "^epmd: up and running", [multiline]), + ?line {match,_} = re:run(Data, "^name foobar at port", [multiline]), + ?line ok = close(Sock), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + buffer_overrun_1(suite) -> []; buffer_overrun_1(doc) -> @@ -968,7 +989,7 @@ epmdrun(Epmd,Args0) -> O -> " "++O end, - osrun("\"" ++ Epmd ++ "\"" ++ Args ++ " " ?EPMDARGS " -port " ++ integer_to_list(?PORT)). + osrun("\"" ++ Epmd ++ "\"" ++ " " ?EPMDARGS " -port " ++ integer_to_list(?PORT) ++ Args). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 1d7811d570..c30203c632 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -1972,35 +1972,8 @@ get_file_args(char *filename, argv_buf *abp, argv_buf *xabp) } static void -write_erl_otp_flags(char *bufp) -{ - /* ERL_OTP<MAJOR-VSN>_FLAGS */ - int ix = 0; - char *otp_p; - char otp[] = OTP_SYSTEM_VERSION; - - bufp[ix++] = 'E'; - bufp[ix++] = 'R'; - bufp[ix++] = 'L'; - bufp[ix++] = '_'; - bufp[ix++] = 'O'; - bufp[ix++] = 'T'; - bufp[ix++] = 'P'; - for (otp_p = &otp[0]; '0' <= *otp_p && *otp_p <= '9'; otp_p++) - bufp[ix++] = *otp_p; - bufp[ix++] = '_'; - bufp[ix++] = 'F'; - bufp[ix++] = 'L'; - bufp[ix++] = 'A'; - bufp[ix++] = 'G'; - bufp[ix++] = 'S'; - bufp[ix] = '\0'; -} - -static void initial_argv_massage(int *argc, char ***argv) { - char erl_otp_flags_buf[] = "ERL_OTP" OTP_SYSTEM_VERSION "_FLAGS"; argv_buf ab = {0}, xab = {0}; int ix, vix, ac; char **av; @@ -2016,8 +1989,7 @@ initial_argv_massage(int *argc, char ***argv) vix = 0; - write_erl_otp_flags(erl_otp_flags_buf); - av = build_args_from_env(erl_otp_flags_buf); + av = build_args_from_env("ERL_OTP" OTP_SYSTEM_VERSION "_FLAGS"); if (av) avv[vix++].argv = av; diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 73887931cc..8520d58f47 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -652,7 +652,7 @@ end define etp-ct-atom-1 # Args: int # -# Determines if integer is a atom first character +# Determines if integer is an atom first character # # Non-reentrant # Returns: $etp_ct_atom @@ -1278,6 +1278,250 @@ document etpf-stackdump %--------------------------------------------------------------------------- end +define etp-heapdump +# Args: Process* +# +# Non-reentrant + etp-heapdump-1 ($arg0)->heap ($arg0)->htop +end + +document etp-heapdump +%--------------------------------------------------------------------------- +% etp-heapdump Process* +% +% Take an Process* and print a heapdump for the process heap. +%--------------------------------------------------------------------------- +end + +define etp-heapdump-old +# Args: Process* +# +# Non-reentrant + etp-heapdump-1 ($arg0)->old_heap ($arg0)->old_htop +end + +document etp-heapdump +%--------------------------------------------------------------------------- +% etp-heapdump-old Process* +% +% Take an Process* and print a heapdump for the process old heap (gen-heap). +%--------------------------------------------------------------------------- +end + + +define etp-heapdump-1 +# Args: Eterm* heap, Eterm* htop +# +# Non-reentrant + set $etp_heapdump_heap = (Eterm*)($arg0) + set $etp_heapdump_p = (Eterm*)($arg0) + set $etp_heapdump_end = (Eterm*)($arg1) + set $etp_heapdump_skips = 0 + printf "%% heapdump (%u):\n", $etp_heapdump_end-$etp_heapdump_p + while $etp_heapdump_p < $etp_heapdump_end + set $etp_heapdump_ix = 0 + printf " %p: ", $etp_heapdump_p + while $etp_heapdump_p < $etp_heapdump_end && $etp_heapdump_ix < 8 + if ($etp_heapdump_skips > 0) + printf "| 0x%08x ", ($etp_heapdump_p) + set $etp_heapdump_skips-- + else + etp-term-dump $etp_heapdump_p[0] + end + set $etp_heapdump_p++ + set $etp_heapdump_ix++ + end + printf "\n" + end +end + + +define etp-term-dump +# Args: Eterm + if (($arg0) & 0x3) == 0 + etp-term-dump-header ($arg0) + else + if (($arg0) & 0x3) == 1 + # Cons pointer + set $etp_term_dump_cons_p = ((Eterm*)(($arg0) & ~0x3)) + if $etp_term_dump_cons_p > $etp_heapdump_heap && $etp_term_dump_cons_p < $etp_heapdump_end + printf "| C:0x%08x ", $etp_term_dump_cons_p + #printf "| C: --> %5d ", $etp_heapdump_p - $etp_term_dump_cons_p - 1 + else + printf "| C:0x%08x ", $etp_term_dump_cons_p + end + else + if (($arg0) & 0x3) == 2 + # Box pointer + printf "| B:0x%08x ", ($arg0) + else + if (($arg0) & 0x3) == 3 + # immediate + etp-term-dump-immediate ($arg0) + else + printf "| U:0x%08x ", ($arg0) + end + end + end + end +end + +define etp-term-dump-immediate +# Args: immediate term + if (($arg0) & 0xF) == 0xf + # Fixnum + etp-ct-printable-1 ((long)((Sint)($arg0)>>4)) + if $etp_ct_printable + if $etp_ct_printable < 0 + printf "| I: %c (%3ld) ", (long)((Sint)($arg0)>>4), (long)((Sint)($arg0)>>4) + else + printf "| I: \\%c (%3ld) ", (long)((Sint)($arg0)>>4), (long)((Sint)($arg0)>>4) + end + else + printf "| I:%10ld ", (long)((Sint)($arg0)>>4) + end + else + if (($arg0) & 0xF) == 0x3 + etp-term-dump-pid ($arg0) + else + if (($arg0) & 0xF) == 0x7 + printf "| port:0x%05x ", ($arg0) + else + # Immediate2 - 0xB + if (($arg0) & 0x3f) == 0x0b + etp-term-dump-atom ($arg0) + else + if (($arg0) & 0x3f) == 0x1b + printf "| #Catch<%06d> ", ($arg0)>>6 + else + if (($arg0) == $etp_nil) + printf "| [] (NIL) " + else + printf "| I:0x%08x ", ($arg0) + end + end + end + end + end + end +end + +define etp-term-dump-atom +# Args: atom term + set $etp_atom_1_ap = (Atom*)erts_atom_table.seg_table[(Eterm)($arg0)>>16][((Eterm)($arg0)>>6)&0x3FF] + set $etp_atom_1_i = ($etp_atom_1_ap)->len + set $etp_atom_1_p = ($etp_atom_1_ap)->name + set $etp_atom_1_quote = 1 + set $etp_atom_indent = 13 + + if ($etp_atom_1_i < 11) + if ($etp_atom_1_i > 0) + etp-ct-atom-1 (*$etp_atom_1_p) + if $etp_ct_atom + set $etp_atom_indent = 13 + else + set $etp_atom_indent = 11 + end + end + # perform indentation + printf "|" + while ($etp_atom_1_i < $etp_atom_indent) + printf " " + set $etp_atom_1_i++ + end + set $etp_atom_1_i = ($etp_atom_1_ap)->len + # Check if atom has to be quoted + if ($etp_atom_1_i > 0) + etp-ct-atom-1 (*$etp_atom_1_p) + if $etp_ct_atom + # Atom start character + set $etp_atom_1_p++ + set $etp_atom_1_i-- + set $etp_atom_1_quote = 0 + else + set $etp_atom_1_i = 0 + end + end + while $etp_atom_1_i > 0 + etp-ct-name-1 (*$etp_atom_1_p) + if $etp_ct_name + # Name character + set $etp_atom_1_p++ + set $etp_atom_1_i-- + else + set $etp_atom_1_quote = 1 + set $etp_atom_1_i = 0 + end + end + # Print the atom + if $etp_atom_1_quote + printf "'" + end + set $etp_atom_1_i = ($etp_atom_1_ap)->len + set $etp_atom_1_p = ($etp_atom_1_ap)->name + while $etp_atom_1_i > 0 + etp-char-1 (*$etp_atom_1_p) '\'' + set $etp_atom_1_p++ + set $etp_atom_1_i-- + end + if $etp_atom_1_quote + printf "'" + end + printf " " + else + printf "| A:0x%08x ", ($arg0) + end +end + +define etp-term-dump-pid +# Args: Eterm pid +# +# Non-reentrant +# + set $etp_pid_1 = (Eterm)($arg0) + if ($etp_pid_1 & 0xF) == 0x3 + if (etp_arch_bits == 64 && etp_halfword == 0) + if (etp_big_endian) + set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 36) & 0x0fffffff) + else + set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 4) & 0x0fffffff) + end + else + set $etp_pid_data = (unsigned) (((((Uint32) $etp_pid_1) >> 4) & ~erts_proc.r.o.pix_mask) | ((((Uint32) $etp_pid_1) >> (erts_proc.r.o.pix_cl_shift + 4)) & erts_proc.r.o.pix_cl_mask) | (((((Uint32) $etp_pid_1) >> 4) & erts_proc.r.o.pix_cli_mask) << erts_proc.r.o.pix_cli_shift)) + end + # Internal pid + printf "| <0.%04u.%03u> ", $etp_pid_data & 0x7fff, ($etp_pid_data >> 15) & 0x1fff + else + printf "| #NotPid<%#x> ", ($arg0) + end +end + +define etp-term-dump-header +# Args: Header term + if (($arg0) & 0x3f) == 0 + printf "| H:%4d-tuple ", ($arg0) >> 6 + else + set $etp_heapdump_skips = ($arg0) >> 6 + if ((($arg0) & 0x3f) == 0x18) + printf "| H: float %3d ", ($arg0) >> 6 + else + if ((($arg0) & 0x3f) == 0x28) + # sub-binary + printf "| H: sub-bin " + else + if ((($arg0) & 0x3f) == 0x8) + # pos-bignum + printf "| H:bignum %3u ", ($arg0) >> 6 + else + printf "| header %5d ", ($arg0) >> 6 + end + end + end + end +end + + + define etp-pid2pix-1 # Args: Eterm # @@ -1445,7 +1689,7 @@ define etp-process-info # Args: Process* # printf " Pid: " - etp-1 $arg0->common.id + etp-1 ($arg0)->common.id printf "\n State: " etp-proc-state $arg0 if $proxy_process != 0 @@ -1523,11 +1767,104 @@ end document etp-processes %--------------------------------------------------------------------------- % etp-processes -% +% % Print misc info about all processes %--------------------------------------------------------------------------- end +define etp-processes-memory + if (!erts_initialized) + printf "No processes, since system isn't initialized!\n" + else + set $proc_ix = 0 + printf "--- (%ld processes in wheel)\n", erts_proc.r.o.max + while $proc_ix < erts_proc.r.o.max + set $proc = (Process *) *((UWord *) &erts_proc.r.o.tab[$proc_ix]) + if ($proc != ((Process *) 0) && $proc != &erts_invalid_process) + etp-process-memory-info $proc + end + set $proc_ix++ + end + printf "---\n", + end +end + +document etp-processes-memory +%--------------------------------------------------------------------------- +% etp-processes-memory +% +% Print memory info about all processes +%--------------------------------------------------------------------------- +end + +define etp-process-memory-info +# Args: Process* +# + if ((*(((Uint32 *) &(((Process *) $arg0)->state)))) & 0x400000) + set $proxy_process = 1 + else + set $proxy_process = 0 + end + printf " " + etp-1 $arg0->common.id + printf ": (Process *) %p ", $arg0 + if $proxy_process != 0 + printf "(Process *) %p ", $arg0 + printf " *** PROXY process struct *** refer to next: \n" + etp-pid2proc-1 $arg0->common.id + printf " -" + etp-process-memory-info $proc + else + printf " [Heap: %5ld", $arg0->heap_sz + if ($arg0->old_heap) + printf " | %5ld", $arg0->old_hend - $arg0->old_heap + else + printf " | none " + end + printf "] [Mbuf: %5ld", $arg0->mbuf_sz + if (etp_smp_compiled) + printf " | %3ld (%3ld | %3ld)", ($arg0->msg.len + $arg0->msg_inq.len), $arg0->msg.len, $arg0->msg_inq.len + else + printf " | %3ld", $arg0->msg.len + end + printf "] " + if ($arg0->i) + printf " I: " + etp-cp-1 $arg0->i + printf " " + end + + if ($arg0->current) + etp-1 $arg0->current[0] + printf ":" + etp-1 $arg0->current[1] + printf "/%d ", $arg0->current[2] + end + + if (*(((Uint32 *) &(((Process *) $arg0)->state))) & 0x4) == 0 + if ($arg0->common.u.alive.reg) + etp-1 $arg0->common.u.alive.reg->name + printf " " + end + end + + if ($arg0->cp) + printf " CP: " + etp-cp-1 $arg0->cp + printf " " + end + printf "\n" + end +end + +document etp-process-memory-info +%--------------------------------------------------------------------------- +% etp-process-memory-info Process* +% +% Print memory info about process +%--------------------------------------------------------------------------- +end + define etp-port-id2pix-1 # Args: Eterm # diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 73fac27161..3c77d6ae0f 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 0ed677c3d8..f99d5bfdd0 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -2246,6 +2246,7 @@ tuple_to_list(_Tuple) -> (modified_timing_level) -> integer() | undefined; (multi_scheduling) -> disabled | blocked | enabled; (multi_scheduling_blockers) -> [PID :: pid()]; + (otp_correction_package) -> string(); (otp_release) -> string(); (port_count) -> non_neg_integer(); (port_limit) -> pos_integer(); diff --git a/erts/vsn.mk b/erts/vsn.mk index 30aa870144..8e77a9a26e 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,11 @@ # VSN = 6.0 -SYSTEM_VSN = 17.0-rc0 + +# OTP major version +SYSTEM_VSN = 17 +# OTP correction package version +SYSTEM_CP_VSN = 17.0-rc0 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 38a733751a..3db7ffc4d2 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -612,7 +612,7 @@ core_passes() -> ?pass(core_fold_module), {core_inline_module,fun test_core_inliner/1,fun core_inline_module/1}, {iff,dinline,{listing,"inline"}}, - {core_fold_after_inline,fun test_core_inliner/1,fun core_fold_module/1}, + {core_fold_after_inlining,fun test_core_inliner/1,fun core_fold_module_after_inlining/1}, ?pass(core_transforms)]}, {iff,dcopt,{listing,"copt"}}, {iff,'to_core',{done,"core"}}]} @@ -1134,6 +1134,12 @@ core_fold_module(#compile{code=Code0,options=Opts,warnings=Warns}=St) -> {ok,Code,Ws} = sys_core_fold:module(Code0, Opts), {ok,St#compile{code=Code,warnings=Warns ++ Ws}}. +core_fold_module_after_inlining(#compile{code=Code0,options=Opts}=St) -> + %% Inlining may produce code that generates spurious warnings. + %% Ignore all warnings. + {ok,Code,_Ws} = sys_core_fold:module(Code0, Opts), + {ok,St#compile{code=Code}}. + test_old_inliner(#compile{options=Opts}) -> %% The point of this test is to avoid loading the old inliner %% if we know that it will not be used. diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index e2002c8e48..a388960312 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -70,7 +70,7 @@ -export([module/2,format_error/1]). -import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,all/2,any/2, - reverse/1,reverse/2,member/2,nth/2,flatten/1]). + reverse/1,reverse/2,member/2,nth/2,flatten/1,unzip/1]). -import(cerl, [ann_c_cons/3,ann_c_tuple/2]). @@ -302,18 +302,49 @@ expr(#c_letrec{defs=Fs0,body=B0}=Letrec, Ctxt, Sub) -> B1 = body(B0, value, Sub), Letrec#c_letrec{defs=Fs1,body=B1}; expr(#c_case{}=Case0, Ctxt, Sub) -> + %% Ideally, the compiler should only emit warnings when there is + %% a real mistake in the code being compiled. We use the follow + %% heuristics in an attempt to approach that ideal: + %% + %% * If the guard for a clause always fails, we will emit a + %% warning. + %% + %% * If a case expression is a literal, we will emit no warnings + %% for clauses that will not match or for clauses that are + %% shadowed after a clause that will always match. That means + %% that code such as: + %% + %% case ?DEBUG of + %% false -> ok; + %% true -> ... + %% end + %% + %% (where ?DEBUG expands to either 'true' or 'false') will not + %% produce any warnings. + %% + %% * If the case expression is not literal, warnings will be + %% emitted for every clause that don't match and for all + %% clauses following a clause that will always match. + %% + %% * If no clause will ever match, there will be a warning + %% (in addition to any warnings that may have been emitted + %% according to the rules above). + %% case opt_bool_case(Case0) of #c_case{arg=Arg0,clauses=Cs0}=Case1 -> Arg1 = body(Arg0, value, Sub), - {Arg2,Cs1} = case_opt(Arg1, Cs0), - Cs2 = clauses(Arg2, Cs1, Case1, Ctxt, Sub), - Case = eval_case(Case1#c_case{arg=Arg2,clauses=Cs2}, Sub), - bsm_an(Case); + LitExpr = cerl:is_literal(Arg1), + {Arg2,Cs1} = case_opt(Arg1, Cs0, Sub), + Cs2 = clauses(Arg2, Cs1, Ctxt, Sub, LitExpr), + Case = Case1#c_case{arg=Arg2,clauses=Cs2}, + warn_no_clause_match(Case1, Case), + Expr = eval_case(Case, Sub), + bsm_an(Expr); Other -> expr(Other, Ctxt, Sub) end; expr(#c_receive{clauses=Cs0,timeout=T0,action=A0}=Recv, Ctxt, Sub) -> - Cs1 = clauses(#c_var{name='_'}, Cs0, Recv, Ctxt, Sub), %This is all we know + Cs1 = clauses(#c_var{name='_'}, Cs0, Ctxt, Sub, false), T1 = expr(T0, value, Sub), A1 = body(A0, Ctxt, Sub), Recv#c_receive{clauses=Cs1,timeout=T1,action=A1}; @@ -1582,39 +1613,39 @@ v_is_value(Var, [{_,#c_var{name=Var}}|_]) -> true; v_is_value(Var, [_|T]) -> v_is_value(Var, T); v_is_value(_, []) -> false. -%% clauses(E, [Clause], TopLevel, Context, Sub) -> [Clause]. -%% Trim the clauses by removing all clauses AFTER the first one which -%% is guaranteed to match. Also remove all trivially false clauses. +%% warn_no_clause_match(CaseOrig, CaseOpt) -> ok +%% Generate a warning if none of the user-specified clauses +%% will match. -clauses(E, Cs0, TopLevel, Ctxt, Sub) -> - Cs = clauses_1(E, Cs0, Ctxt, Sub), - - %% Here we want to warn if no clauses whatsoever will ever - %% match, because that is probably a mistake. - case all(fun is_compiler_generated/1, Cs) andalso - any(fun(C) -> not is_compiler_generated(C) end, Cs0) of +warn_no_clause_match(CaseOrig, CaseOpt) -> + OrigCs = cerl:case_clauses(CaseOrig), + OptCs = cerl:case_clauses(CaseOpt), + case any(fun(C) -> not is_compiler_generated(C) end, OrigCs) andalso + all(fun is_compiler_generated/1, OptCs) of true -> %% The original list of clauses did contain at least one %% user-specified clause, but none of them will match. %% That is probably a mistake. - add_warning(TopLevel, no_clause_match); + add_warning(CaseOrig, no_clause_match); false -> %% Either there were user-specified clauses left in %% the transformed clauses, or else none of the original %% clauses were user-specified to begin with (as in 'andalso'). ok - end, + end. - Cs. +%% clauses(E, [Clause], TopLevel, Context, Sub) -> [Clause]. +%% Trim the clauses by removing all clauses AFTER the first one which +%% is guaranteed to match. Also remove all trivially false clauses. -clauses_1(E, [C0|Cs], Ctxt, Sub) -> +clauses(E, [C0|Cs], Ctxt, Sub, LitExpr) -> #c_clause{pats=Ps,guard=G} = C1 = clause(C0, E, Ctxt, Sub), %%ok = io:fwrite("~w: ~p~n", [?LINE,{E,Ps}]), case {will_match(E, Ps),will_succeed(G)} of {yes,yes} -> - Line = get_line(core_lib:get_anno(C1)), - case core_lib:is_literal(E) of + case LitExpr of false -> + Line = get_line(core_lib:get_anno(C1)), shadow_warning(Cs, Line); true -> %% If the case expression is a literal, @@ -1623,15 +1654,13 @@ clauses_1(E, [C0|Cs], Ctxt, Sub) -> ok end, [C1]; %Skip the rest - {no,_Suc} -> - clauses_1(E, Cs, Ctxt, Sub); %Skip this clause - {_Mat,no} -> + {_Mat,no} -> %Guard fails. add_warning(C1, nomatch_guard), - clauses_1(E, Cs, Ctxt, Sub); %Skip this clause + clauses(E, Cs, Ctxt, Sub, LitExpr); %Skip this clause {_Mat,_Suc} -> - [C1|clauses_1(E, Cs, Ctxt, Sub)] + [C1|clauses(E, Cs, Ctxt, Sub, LitExpr)] end; -clauses_1(_, [], _, _) -> []. +clauses(_, [], _, _, _) -> []. shadow_warning([C|Cs], none) -> add_warning(C, nomatch_shadow), @@ -1649,69 +1678,18 @@ will_succeed(#c_literal{val=true}) -> yes; will_succeed(#c_literal{val=false}) -> no; will_succeed(_Guard) -> maybe. -%% will_match(Expr, [Pattern]) -> yes | maybe | no. -%% Test if we know whether a match will succeed/fail or just don't -%% know. Be conservative. +%% will_match(Expr, [Pattern]) -> yes | maybe. +%% We KNOW that this function is only used after optimizations +%% in case_opt/4. Therefore clauses that can definitely not match +%% have already been pruned. will_match(#c_values{es=Es}, Ps) -> - will_match_list(Es, Ps, yes); + will_match_1(cerl_clauses:match_list(Ps, Es)); will_match(E, [P]) -> - will_match_1(E, P). - -will_match_1(_E, #c_var{}) -> yes; %Will always match -will_match_1(E, #c_alias{pat=P}) -> %Pattern decides - will_match_1(E, P); -will_match_1(#c_var{}, _P) -> maybe; -will_match_1(#c_tuple{es=Es}, #c_tuple{es=Ps}) -> - will_match_list(Es, Ps, yes); -will_match_1(#c_literal{val=Lit}, P) -> - will_match_lit(Lit, P); -will_match_1(_, _) -> maybe. - -will_match_list([E|Es], [P|Ps], M) -> - case will_match_1(E, P) of - yes -> will_match_list(Es, Ps, M); - maybe -> will_match_list(Es, Ps, maybe); - no -> no - end; -will_match_list([], [], M) -> M. - -will_match_lit(Cons, #c_cons{hd=Hp,tl=Tp}) -> - case Cons of - [H|T] -> - case will_match_lit(H, Hp) of - yes -> will_match_lit(T, Tp); - Other -> Other - end; - _ -> - no - end; -will_match_lit(Tuple, #c_tuple{es=Es}) -> - case is_tuple(Tuple) andalso tuple_size(Tuple) =:= length(Es) of - true -> will_match_lit_list(tuple_to_list(Tuple), Es); - false -> no - end; -will_match_lit(Bin, #c_binary{}) -> - case is_bitstring(Bin) of - true -> maybe; - false -> no - end; -will_match_lit(_, #c_var{}) -> - yes; -will_match_lit(Lit, #c_alias{pat=P}) -> - will_match_lit(Lit, P); -will_match_lit(Lit1, #c_literal{val=Lit2}) -> - case Lit1 =:= Lit2 of - true -> yes; - false -> no - end. + will_match_1(cerl_clauses:match(P, E)). -will_match_lit_list([H|T], [P|Ps]) -> - case will_match_lit(H, P) of - yes -> will_match_lit_list(T, Ps); - Other -> Other - end; -will_match_lit_list([], []) -> yes. +will_match_1({false,_}) -> maybe; +will_match_1({true,_}) -> yes. %% opt_bool_case(CoreExpr) - CoreExpr'. %% Do various optimizations to case statement that has a @@ -1910,166 +1888,243 @@ opt_bool_case_guard(Arg, [#c_clause{pats=[#c_literal{val=false}]}=Fc,Tc]) -> %% last clause is guaranteed to match so if there is only one clause %% with a pattern containing only variables then rewrite to a let. -eval_case(#c_case{arg=#c_var{name=V}, - clauses=[#c_clause{pats=[P],guard=G,body=B}|_]}=Case, - #sub{t=Tdb}=Sub) -> - case orddict:find(V, Tdb) of - {ok,Type} -> - case {will_match_type(P, Type),will_succeed(G)} of - {yes,yes} -> - {Ps,Es} = remove_non_vars(P, Type), - expr(#c_let{vars=Ps,arg=#c_values{es=Es},body=B}, - sub_new(Sub)); - {_,_} -> - eval_case_1(Case, Sub) - end; - error -> eval_case_1(Case, Sub) - end; -eval_case(Case, Sub) -> eval_case_1(Case, Sub). - -eval_case_1(#c_case{arg=E,clauses=[#c_clause{pats=Ps,body=B}]}=Case, Sub) -> - case is_var_pat(Ps) of - true -> expr(#c_let{vars=Ps,arg=E,body=B}, sub_new(Sub)); - false -> eval_case_2(E, Ps, B, Case) - end; -eval_case_1(Case, _) -> Case. - -eval_case_2(E, [P], B, Case) -> - %% Recall that there is only one clause and that it is guaranteed to match. - %% If E and P are literals, they must be the same literal and the body - %% can be used directly as there are no variables that need to be bound. - %% Otherwise, P could be an alias meaning that two or more variables - %% would be bound to E. We don't bother to optimize that case as it - %% is rather uncommon. - case core_lib:is_literal(E) andalso core_lib:is_literal(P) of - false -> Case; - true -> B - end; -eval_case_2(_, _, _, Case) -> Case. - -is_var_pat(Ps) -> - all(fun (#c_var{}) -> true; - (_Pat) -> false - end, Ps). - -will_match_type(#c_tuple{es=Es}, #c_tuple{es=Ps}) -> - will_match_list_type(Es, Ps); -will_match_type(#c_literal{val=Atom}, #c_literal{val=Atom}) -> yes; -will_match_type(#c_var{}, #c_var{}) -> yes; -will_match_type(#c_var{}, #c_alias{}) -> yes; -will_match_type(_, _) -> no. - -will_match_list_type([E|Es], [P|Ps]) -> - case will_match_type(E, P) of - yes -> will_match_list_type(Es, Ps); - no -> no - end; -will_match_list_type([], []) -> yes; -will_match_list_type(_, _) -> no. %Different length - -remove_non_vars(Ps0, Es0) -> - {Ps,Es} = remove_non_vars(Ps0, Es0, [], []), - {reverse(Ps),reverse(Es)}. - -remove_non_vars(#c_tuple{es=Ps}, #c_tuple{es=Es}, Pacc, Eacc) -> - remove_non_vars_list(Ps, Es, Pacc, Eacc); -remove_non_vars(#c_var{}=Var, #c_alias{var=Evar}, Pacc, Eacc) -> - {[Var|Pacc],[Evar|Eacc]}; -remove_non_vars(#c_var{}=Var, #c_var{}=Evar, Pacc, Eacc) -> - {[Var|Pacc],[Evar|Eacc]}; -remove_non_vars(P, E, Pacc, Eacc) -> - true = core_lib:is_literal(P) andalso core_lib:is_literal(E), %Assertion. - {Pacc,Eacc}. - -remove_non_vars_list([P|Ps], [E|Es], Pacc0, Eacc0) -> - {Pacc,Eacc} = remove_non_vars(P, E, Pacc0, Eacc0), - remove_non_vars_list(Ps, Es, Pacc, Eacc); -remove_non_vars_list([], [], Pacc, Eacc) -> - {Pacc,Eacc}. +eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,body=B}]}, Sub) -> + Es = case cerl:is_c_values(E) of + true -> cerl:values_es(E); + false -> [E] + end, + {true,Bs} = cerl_clauses:match_list(Ps0, Es), + {Ps,As} = unzip(Bs), + expr(#c_let{vars=Ps,arg=core_lib:make_values(As),body=B}, sub_new(Sub)); +eval_case(Case, _) -> Case. %% case_opt(CaseArg, [Clause]) -> {CaseArg,[Clause]}. -%% Try and optimise case by avoid building a tuple in -%% the case expression. Instead of building a tuple -%% in the case expression, combine the elements into -%% multiple "values". If a clause refers to the tuple -%% in the case expression (that was not built), introduce -%% a let into the guard and/or body to build the tuple. +%% Try and optimise a case by avoid building tuples or lists +%% in the case expression. Instead combine the variable parts +%% of the case expression to multiple "values". If a clause +%% refers to the constructed term in the case expression (which +%% was not built), introduce a let into the guard and/or body to +%% build the term. %% -%% case {Expr1,Expr2} of case <Expr1,Expr2> of -%% {P1,P2} -> ... <P1,P2> -> ... +%% case {ok,[Expr1,Expr2]} of case <Expr1,Expr2> of +%% {ok,[P1,P2]} -> ... <P1,P2> -> ... %% . ==> . %% . . %% . . -%% Var -> <Var1,Var2> -> -%% ... Var ... let <Var> = {Var1,Var2} -%% in ... Var ... +%% Var -> <Var1,Var2> -> +%% ... Var ... let <Var> = {ok,[Var1,Var2]} +%% in ... Var ... %% . . %% . . %% . . -%% end. end. +%% end. end. %% -case_opt(#c_tuple{anno=A,es=Es}, Cs0) -> - Cs1 = case_opt_cs(Cs0, length(Es)), - {core_lib:set_anno(core_lib:make_values(Es), A),Cs1}; -case_opt(Arg, Cs) -> {Arg,Cs}. - -case_opt_cs([#c_clause{pats=Ps0,guard=G,body=B}=C|Cs], Arity) -> - case case_tuple_pat(Ps0, Arity) of - {ok,Ps1,Avs} -> - Flet = fun ({V,Pat}, Body) -> letify(V, Pat, Body) end, - [C#c_clause{pats=Ps1, - guard=foldl(Flet, G, Avs), - body=foldl(Flet, B, Avs)}|case_opt_cs(Cs, Arity)]; - error -> %Can't match - add_warning(C, nomatch_clause_type), - case_opt_cs(Cs, Arity) +case_opt(Arg, Cs0, Sub) -> + Cs1 = [{cerl:clause_pats(C),C,[],[]} || C <- Cs0], + Args0 = case cerl:is_c_values(Arg) of + false -> [Arg]; + true -> cerl:values_es(Arg) + end, + LitExpr = cerl:is_literal(Arg), + {Args,Cs2} = case_opt_args(Args0, Cs1, Sub, LitExpr, []), + Cs = [cerl:update_c_clause(C, + reverse(Ps), + letify(Bs, cerl:clause_guard(C)), + letify(Bs, cerl:clause_body(C))) || + {[],C,Ps,Bs} <- Cs2], + {core_lib:make_values(Args),Cs}. + +case_opt_args([A0|As0], Cs0, Sub, LitExpr, Acc) -> + case case_opt_arg(A0, Sub, Cs0, LitExpr) of + error -> + %% Nothing to be done. Move on to the next argument. + Cs = [{Ps,C,[P|PsAcc],Bs} || {[P|Ps],C,PsAcc,Bs} <- Cs0], + case_opt_args(As0, Cs, Sub, LitExpr, [A0|Acc]); + {ok,As1,Cs} -> + %% The argument was either expanded (from tuple/list) or + %% removed (literal). + case_opt_args(As1++As0, Cs, Sub, LitExpr, Acc) + end; +case_opt_args([], Cs, _Sub, _LitExpr, Acc) -> + {reverse(Acc),Cs}. + +%% case_opt_arg(Expr, Sub, Clauses0, LitExpr) -> +%% {ok,Args,Clauses} | error +%% Try to expand one argument to several arguments (if tuple/list) +%% or to remove a literal argument. +%% +case_opt_arg(E0, Sub, Cs, LitExpr) -> + E = maybe_replace_var(E0, Sub), + case cerl:is_data(E) of + false -> + error; + true -> + case cerl:data_type(E) of + {atomic,_} -> + case_opt_lit(E, Cs, LitExpr); + _ -> + case_opt_data(E, Cs, LitExpr) + end + end. + +%% maybe_replace_var(Expr0, Sub) -> Expr +%% If Expr0 is a variable that has been previously matched and +%% is known to be a tuple, return the tuple instead. Otherwise +%% return Expr0 unchanged. +%% +maybe_replace_var(E, Sub) -> + case cerl:is_c_var(E) of + false -> E; + true -> maybe_replace_var_1(E, Sub) + end. + +maybe_replace_var_1(E, #sub{t=Tdb}) -> + case orddict:find(cerl:var_name(E), Tdb) of + {ok,T0} -> + case cerl:is_c_tuple(T0) of + false -> + E; + true -> + cerl_trees:map(fun(C) -> + case cerl:is_c_alias(C) of + false -> C; + true -> cerl:alias_pat(C) + end + end, T0) + end; + error -> + E + end. + +%% case_opt_lit(Literal, Clauses0, LitExpr) -> +%% {ok,[],Clauses} | error +%% The current part of the case expression is a literal. That +%% means that we will know at compile-time whether a clause +%% will match, and we can remove the corresponding pattern from +%% each clause. +%% +%% The only complication is if the literal is a binary. Binary +%% pattern matching is tricky, so we will give up in that case. + +case_opt_lit(Lit, Cs0, LitExpr) -> + try case_opt_lit_1(Cs0, Lit, LitExpr) of + Cs -> + {ok,[],Cs} + catch + throw:impossible -> + error + end. + +case_opt_lit_1([{[P|Ps],C,PsAcc,Bs0}|Cs], E, LitExpr) -> + case cerl_clauses:match(P, E) of + none -> + %% The pattern will not match the literal. Remove the clause. + %% Unless the entire case expression is a literal, also + %% emit a warning. + case LitExpr of + false -> add_warning(C, nomatch_clause_type); + true -> ok + end, + case_opt_lit_1(Cs, E, LitExpr); + {true,Bs} -> + %% The pattern matches the literal. Remove the pattern + %% and update the bindings. + [{Ps,C,PsAcc,Bs++Bs0}|case_opt_lit_1(Cs, E, LitExpr)]; + {false,_} -> + %% Binary literal and pattern. We are not sure whether + %% the pattern will match. + throw(impossible) + end; +case_opt_lit_1([], _, _) -> []. + +%% case_opt_data(Expr, Clauses0, LitExpr) -> {ok,Exprs,Clauses} + +case_opt_data(E, Cs0, LitExpr) -> + Es = cerl:data_es(E), + Cs = case_opt_data_1(Cs0, Es, + {cerl:data_type(E),cerl:data_arity(E)}, + LitExpr), + {ok,Es,Cs}. + +case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig, LitExpr) -> + case case_data_pat(P, TypeSig) of + {ok,Ps1,Bs1} -> + [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}| + case_opt_data_1(Cs, Es, TypeSig,LitExpr)]; + error -> + case LitExpr of + false -> add_warning(C, nomatch_clause_type); + true -> ok + end, + case_opt_data_1(Cs, Es, TypeSig, LitExpr) end; -case_opt_cs([], _) -> []. +case_opt_data_1([], _, _, _) -> []. -%% case_tuple_pat([Pattern], Arity) -> {ok,[Pattern],[{AliasVar,Pat}]} | error. +%% case_data_pat(Pattern, Type, Arity) -> {ok,[Pattern],[{AliasVar,Pat}]} | error. -case_tuple_pat([#c_tuple{es=Ps}], Arity) when length(Ps) =:= Arity -> - {ok,Ps,[]}; -case_tuple_pat([#c_literal{val=T}], Arity) when tuple_size(T) =:= Arity -> - Ps = [#c_literal{val=E} || E <- tuple_to_list(T)], - {ok,Ps,[]}; -case_tuple_pat([#c_var{anno=Anno0}=V], Arity) -> - Vars = make_vars(Anno0, 1, Arity), +case_data_pat(P, TypeSig) -> + case cerl:is_data(P) of + false -> + case_data_pat_var(P, TypeSig); + true -> + case {cerl:data_type(P),cerl:data_arity(P)} of + TypeSig -> + {ok,cerl:data_es(P),[]}; + {_,_} -> + error + end + end. +%% case_data_pat_var(Pattern, {DataType,ArityType}) -> +%% {ok,[Pattern],[{AliasVar,Pat}]} + +case_data_pat_var(P, {Type,Arity}=TypeSig) -> %% If the entire case statement is evaluated in an effect %% context (e.g. "case {A,B} of ... end, ok"), there will %% be a warning that a term is constructed but never used. - %% To avoid that warning, we must annotate the tuple as - %% compiler generated. - - Anno = [compiler_generated|Anno0], - {ok,Vars,[{V,#c_tuple{anno=Anno,es=Vars}}]}; -case_tuple_pat([#c_alias{var=V,pat=P}], Arity) -> - case case_tuple_pat([P], Arity) of - {ok,Ps,Avs} -> - Anno0 = core_lib:get_anno(P), - Anno = [compiler_generated|Anno0], - {ok,Ps,[{V,#c_tuple{anno=Anno,es=unalias_pat_list(Ps)}}|Avs]}; - error -> + %% To avoid that warning, we must annotate the data + %% constructor as compiler generated. + Ann = [compiler_generated|cerl:get_ann(P)], + case cerl:type(P) of + var -> + Vars = make_vars(cerl:get_ann(P), Arity), + {ok,Vars,[{P,cerl:ann_make_data(Ann, Type, Vars)}]}; + alias -> + V = cerl:alias_var(P), + Apat = cerl:alias_pat(P), + case case_data_pat(Apat, TypeSig) of + {ok,Ps,Bs} -> + {ok,Ps,[{V,cerl:ann_make_data(Ann, Type, unalias_pat_list(Ps))}|Bs]}; + error -> + error + end; + _ -> error - end; -case_tuple_pat(_, _) -> error. + end. %% unalias_pat(Pattern) -> Pattern. %% Remove all the aliases in a pattern but using the alias variables %% instead of the values. We KNOW they will be bound. -unalias_pat(#c_alias{var=V}) -> V; -unalias_pat(#c_cons{anno=Anno,hd=H0,tl=T0}) -> - H1 = unalias_pat(H0), - T1 = unalias_pat(T0), - ann_c_cons(Anno, H1, T1); -unalias_pat(#c_tuple{anno=Anno,es=Ps}) -> - ann_c_tuple(Anno, unalias_pat_list(Ps)); -unalias_pat(Atomic) -> Atomic. +unalias_pat(P) -> + case cerl:is_c_alias(P) of + true -> + cerl:alias_var(P); + false -> + case cerl:is_data(P) of + false -> + P; + true -> + Es = unalias_pat_list(cerl:data_es(P)), + cerl:update_data(P, cerl:data_type(P), Es) + end + end. unalias_pat_list(Ps) -> [unalias_pat(P) || P <- Ps]. +make_vars(A, Max) -> + make_vars(A, 1, Max). + make_vars(A, I, Max) when I =< Max -> [make_var(A)|make_vars(A, I+1, Max)]; make_vars(_, _, _) -> []. @@ -2082,6 +2137,11 @@ make_var_name() -> put(new_var_num, N+1), list_to_atom("fol"++integer_to_list(N)). +letify(Bs, Body) -> + foldr(fun({V,Val}, B) -> + letify(V, Val, B) + end, Body, Bs). + letify(#c_var{name=Vname}=Var, Val, Body) -> case core_lib:is_var_used(Vname, Body) of true -> @@ -2102,7 +2162,7 @@ opt_case_in_let_0([#c_var{name=V}], Arg, case is_simple_case_arg(Arg) andalso not core_lib:is_var_used(V, Case#c_case{arg=#c_literal{val=nil}}) of true -> - opt_bool_case(Case#c_case{arg=Arg}); + expr(opt_bool_case(Case#c_case{arg=Arg,clauses=Cs}), sub_new()); false -> Let end; diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 6a13495523..f534500671 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -1466,10 +1466,11 @@ set_cg([{var,R}], Con, Le, Vdb, Bef, St) -> cg_binary([{bs_put_binary,Fail,{atom,all},U,_Flags,Src}|PutCode], Target, Temp, Fail, MaxRegs, Anno) -> + Line = line(Anno), Live = cg_live(Target, MaxRegs), SzCode = cg_bitstr_size(PutCode, Target, Temp, Fail, Live), BinFlags = {field_flags,[]}, - Code = SzCode ++ + Code = [Line|SzCode] ++ [case member(single_use, Anno) of true -> {bs_private_append,Fail,Target,U,Src,BinFlags,Target}; diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 321cf7af1c..a5f31f3844 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -563,7 +563,8 @@ expr({'try',L,Es0,[],[],As0}, St0) -> guard=[#c_literal{val=true}], body=As1}], fc=Fc}, - App = #iapply{anno=Lanno,op=#c_var{anno=LA,name={Name,0}},args=[]}, + App = #iapply{anno=#a{anno=[compiler_generated|LA]}, + op=#c_var{anno=LA,name={Name,0}},args=[]}, {Evs,Hs,St5} = try_after([App], St4), Try = #itry{anno=Lanno,args=Es1,vars=[V],body=[App,V],evars=Evs,handler=Hs}, Letrec = #iletrec{anno=Lanno,defs=[{{Name,0},Fun}], diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index a5a4e62a42..69f61a046f 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -249,6 +249,12 @@ coverage(Config) when is_list(Config) -> case list_to_pid("<0.42.0>") of Pid when is_pid(Pid) -> ok end, + + %% Cover the non-variable case in bsm_do_an/4. + ok = bsm_an_inlined(<<1>>, Config), + error = bsm_an_inlined(<<1,2,3>>, Config), + error = bsm_an_inlined([], Config), + ok. cover_will_match_list_type(A) -> @@ -290,6 +296,9 @@ cover_is_safe_bool_expr(X) -> false end. +bsm_an_inlined(<<_:8>>, _) -> ok; +bsm_an_inlined(_, _) -> error. + id(I) -> I. unused_multiple_values_error(Config) when is_list(Config) -> diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index 810b2b48c9..7186956603 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -117,6 +117,7 @@ pattern2(Config) when is_list(Config) -> Source, [nowarn_unused_vars], {warnings,[{2,sys_core_fold,{nomatch_shadow,1}}, + {4,sys_core_fold,no_clause_match}, {5,sys_core_fold,nomatch_clause_type}, {6,sys_core_fold,nomatch_clause_type}]}}], ?line [] = run(Config, Ts), diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 310a741b0b..925ad0c091 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -384,100 +384,6 @@ static ErlNifFunc nif_funcs[] = { {"ecdh_compute_key_nif", 3, ecdh_compute_key_nif} }; -#if defined(HAVE_EC) -struct nid_map { - char *name; - int nid; - ERL_NIF_TERM atom; -}; - -static struct nid_map ec_curves[] = { - /* prime field curves */ - /* secg curves */ - { "secp112r1", NID_secp112r1 }, - { "secp112r2", NID_secp112r2 }, - { "secp128r1", NID_secp128r1 }, - { "secp128r2", NID_secp128r2 }, - { "secp160k1", NID_secp160k1 }, - { "secp160r1", NID_secp160r1 }, - { "secp160r2", NID_secp160r2 }, - /* SECG secp192r1 is the same as X9.62 prime192v1 */ - { "secp192r1", NID_X9_62_prime192v1 }, - { "secp192k1", NID_secp192k1 }, - { "secp224k1", NID_secp224k1 }, - { "secp224r1", NID_secp224r1 }, - { "secp256k1", NID_secp256k1 }, - /* SECG secp256r1 is the same as X9.62 prime256v1 */ - { "secp256r1", NID_X9_62_prime256v1 }, - { "secp384r1", NID_secp384r1 }, - { "secp521r1", NID_secp521r1 }, - /* X9.62 curves */ - { "prime192v1", NID_X9_62_prime192v1 }, - { "prime192v2", NID_X9_62_prime192v2 }, - { "prime192v3", NID_X9_62_prime192v3 }, - { "prime239v1", NID_X9_62_prime239v1 }, - { "prime239v2", NID_X9_62_prime239v2 }, - { "prime239v3", NID_X9_62_prime239v3 }, - { "prime256v1", NID_X9_62_prime256v1 }, - /* characteristic two field curves */ - /* NIST/SECG curves */ - { "sect113r1", NID_sect113r1 }, - { "sect113r2", NID_sect113r2 }, - { "sect131r1", NID_sect131r1 }, - { "sect131r2", NID_sect131r2 }, - { "sect163k1", NID_sect163k1 }, - { "sect163r1", NID_sect163r1 }, - { "sect163r2", NID_sect163r2 }, - { "sect193r1", NID_sect193r1 }, - { "sect193r2", NID_sect193r2 }, - { "sect233k1", NID_sect233k1 }, - { "sect233r1", NID_sect233r1 }, - { "sect239k1", NID_sect239k1 }, - { "sect283k1", NID_sect283k1 }, - { "sect283r1", NID_sect283r1 }, - { "sect409k1", NID_sect409k1 }, - { "sect409r1", NID_sect409r1 }, - { "sect571k1", NID_sect571k1 }, - { "sect571r1", NID_sect571r1 }, - /* X9.62 curves */ - { "c2pnb163v1", NID_X9_62_c2pnb163v1 }, - { "c2pnb163v2", NID_X9_62_c2pnb163v2 }, - { "c2pnb163v3", NID_X9_62_c2pnb163v3 }, - { "c2pnb176v1", NID_X9_62_c2pnb176v1 }, - { "c2tnb191v1", NID_X9_62_c2tnb191v1 }, - { "c2tnb191v2", NID_X9_62_c2tnb191v2 }, - { "c2tnb191v3", NID_X9_62_c2tnb191v3 }, - { "c2pnb208w1", NID_X9_62_c2pnb208w1 }, - { "c2tnb239v1", NID_X9_62_c2tnb239v1 }, - { "c2tnb239v2", NID_X9_62_c2tnb239v2 }, - { "c2tnb239v3", NID_X9_62_c2tnb239v3 }, - { "c2pnb272w1", NID_X9_62_c2pnb272w1 }, - { "c2pnb304w1", NID_X9_62_c2pnb304w1 }, - { "c2tnb359v1", NID_X9_62_c2tnb359v1 }, - { "c2pnb368w1", NID_X9_62_c2pnb368w1 }, - { "c2tnb431r1", NID_X9_62_c2tnb431r1 }, - /* the WAP/WTLS curves - * [unlike SECG, spec has its own OIDs for curves from X9.62] */ - { "wtls1", NID_wap_wsg_idm_ecid_wtls1 }, - { "wtls3", NID_wap_wsg_idm_ecid_wtls3 }, - { "wtls4", NID_wap_wsg_idm_ecid_wtls4 }, - { "wtls5", NID_wap_wsg_idm_ecid_wtls5 }, - { "wtls6", NID_wap_wsg_idm_ecid_wtls6 }, - { "wtls7", NID_wap_wsg_idm_ecid_wtls7 }, - { "wtls8", NID_wap_wsg_idm_ecid_wtls8 }, - { "wtls9", NID_wap_wsg_idm_ecid_wtls9 }, - { "wtls10", NID_wap_wsg_idm_ecid_wtls10 }, - { "wtls11", NID_wap_wsg_idm_ecid_wtls11 }, - { "wtls12", NID_wap_wsg_idm_ecid_wtls12 }, - /* IPSec curves */ - { "ipsec3", NID_ipsec3 }, - { "ipsec4", NID_ipsec4 } -}; - -#define EC_CURVES_CNT (sizeof(ec_curves)/sizeof(struct nid_map)) - -#endif /* HAVE_EC */ - ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload) @@ -632,12 +538,6 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info) atom_tpbasis = enif_make_atom(env,"tpbasis"); atom_ppbasis = enif_make_atom(env,"ppbasis"); atom_onbasis = enif_make_atom(env,"onbasis"); - - { - int i; - for (i = 0; i < EC_CURVES_CNT; i++) - ec_curves[i].atom = enif_make_atom(env,ec_curves[i].name); - } #endif init_digest_types(env); @@ -725,7 +625,7 @@ static void unload(ErlNifEnv* env, void* priv_data) static int algo_hash_cnt; static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */ static int algo_pubkey_cnt; -static ERL_NIF_TERM algo_pubkey[2]; /* increase when extending the list */ +static ERL_NIF_TERM algo_pubkey[3]; /* increase when extending the list */ static int algo_cipher_cnt; static ERL_NIF_TERM algo_cipher[2]; /* increase when extending the list */ @@ -751,6 +651,9 @@ static void init_algorithms_types(ErlNifEnv* env) algo_pubkey_cnt = 0; #if defined(HAVE_EC) +#if !defined(OPENSSL_NO_EC2M) + algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ec_gf2m"); +#endif algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdsa"); algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdh"); #endif @@ -2962,21 +2865,9 @@ static ERL_NIF_TERM blowfish_ofb64_encrypt(ErlNifEnv* env, int argc, const ERL_N } #if defined(HAVE_EC) -static int term2curve_id(ERL_NIF_TERM nid) -{ - int i; - - for (i = 0; i < EC_CURVES_CNT; i++) - if (ec_curves[i].atom == nid) - return ec_curves[i].nid; - - return 0; -} - static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) { EC_KEY *key = NULL; - int nid = 0; int c_arity = -1; const ERL_NIF_TERM* curve; ErlNifBinary seed; @@ -2988,18 +2879,12 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) EC_GROUP *group = NULL; EC_POINT *point = NULL; - if (enif_is_atom(env, curve_arg)) { - nid = term2curve_id(curve_arg); - if (nid == 0) - return NULL; - key = EC_KEY_new_by_curve_name(nid); - } - else if (enif_is_tuple(env, curve_arg) - && enif_get_tuple(env,curve_arg,&c_arity,&curve) - && c_arity == 5 - && get_bn_from_bin(env, curve[3], &bn_order) - && (curve[4] != atom_none && get_bn_from_bin(env, curve[4], &cofactor))) { - /* {Field, Prime, Point, Order, CoFactor} = Curve */ + /* {Field, Prime, Point, Order, CoFactor} = Curve */ + if (enif_is_tuple(env, curve_arg) + && enif_get_tuple(env,curve_arg,&c_arity,&curve) + && c_arity == 5 + && get_bn_from_bin(env, curve[3], &bn_order) + && (curve[4] != atom_none && get_bn_from_bin(env, curve[4], &cofactor))) { int f_arity = -1; const ERL_NIF_TERM* field; @@ -3033,6 +2918,8 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) /* create the EC_GROUP structure */ group = EC_GROUP_new_curve_GFp(p, a, b, NULL); +#if !defined(OPENSSL_NO_EC2M) + } else if (f_arity == 3 && field[0] == atom_characteristic_two_field) { /* {characteristic_two_field, M, Basis} */ @@ -3091,6 +2978,7 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) goto out_err; group = EC_GROUP_new_curve_GF2m(p, a, b, NULL); +#endif } else goto out_err; diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 406fd5e59a..aa60bba96a 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -99,7 +99,9 @@ <p><code>ecdh_private() = key_value() </code></p> - <p><code>ecdh_params() = ec_named_curve() | + <p><code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code></p> + + <p><code>ec_explicit_curve() = {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} </code></p> <p><code>ec_field() = {prime_field, Prime :: integer()} | @@ -114,7 +116,15 @@ secp192k1| secp160r2| secp128r2| secp128r1| sect233r1| sect233k1| sect193r2| sect193r1| sect131r2| sect131r1| sect283r1| sect283k1| sect163r2| secp256k1| secp160k1| secp160r1| secp112r2| secp112r1| sect113r2| sect113r1| sect239k1| sect163r1| sect163k1| secp256r1| - secp192r1 </code></p> + secp192r1| + brainpoolP160r1| brainpoolP160t1| brainpoolP192r1| brainpoolP192t1| brainpoolP224r1| + brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1| + brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1 + </code> + Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the + underlying OpenSSL has support for them. + See also <seealso marker="#supports-0">crypto:supports/0</seealso> + </p> <p><code>stream_cipher() = rc4 | aes_ctr </code></p> @@ -143,8 +153,11 @@ </p> <p><code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb128| aes_cbc256 | aes_ige256 | rc2_cbc | aes_ctr| rc4 </code> </p> - <p><code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh </code> </p> - + <p><code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code> + Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported + with ecdsa and ecdh. + </p> + </section> <funcs> @@ -680,7 +693,29 @@ </desc> </func> - + <func> + <name>ec_curves() -> EllipticCurveList </name> + <fsummary>Provide a list of available named elliptic curves.</fsummary> + <type> + <v>EllipticCurveList = [ec_named_curve()]</v> + </type> + <desc> + <p>Can be used to determine which named elliptic curves are supported.</p> + </desc> + </func> + + <func> + <name>ec_curve(NamedCurve) -> EllipticCurve </name> + <fsummary>Get the defining parameters of a elliptic curve.</fsummary> + <type> + <v>NamedCurve = ec_named_curve()</v> + <v>EllipticCurve = ec_explicit_curve()</v> + </type> + <desc> + <p>Return the defining parameters of a elliptic curve.</p> + </desc> + </func> + <func> <name>verify(Algorithm, DigestType, Msg, Signature, Key) -> boolean()</name> <fsummary>Verifies a digital signature.</fsummary> diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile index 574c2076f2..eabfd676c5 100644 --- a/lib/crypto/src/Makefile +++ b/lib/crypto/src/Makefile @@ -37,6 +37,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/crypto-$(VSN) MODULES= \ crypto_app \ crypto \ + crypto_ec_curves \ crypto_server \ crypto_sup diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src index 5548b6a1b5..161ea7c9fe 100644 --- a/lib/crypto/src/crypto.app.src +++ b/lib/crypto/src/crypto.app.src @@ -20,6 +20,7 @@ [{description, "CRYPTO version 2"}, {vsn, "%VSN%"}, {modules, [crypto, + crypto_ec_curves, crypto_app, crypto_sup, crypto_server]}, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 12ff060bf9..d953bd3bca 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -34,6 +34,7 @@ -export([public_encrypt/4, private_decrypt/4]). -export([private_encrypt/4, public_decrypt/4]). -export([dh_generate_parameters/2, dh_check/1]). %% Testing see +-export([ec_curve/1, ec_curves/0]). %% DEPRECATED %% Replaced by hash_* @@ -557,7 +558,7 @@ generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg) user_srp_gen_key(Private, Generator, Prime); generate_key(ecdh, Curve, undefined) -> - ec_key_generate(Curve). + ec_key_generate(nif_curve_params(Curve)). compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) -> @@ -1502,21 +1503,27 @@ ec_key_generate(_Key) -> ?nif_stub. ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub. +ec_curves() -> + crypto_ec_curves:curves(). + +ec_curve(X) -> + crypto_ec_curves:curve(X). + %% %% EC %% term_to_nif_prime({prime_field, Prime}) -> - {prime_field, int_to_bin(Prime)}; + {prime_field, ensure_int_as_bin(Prime)}; term_to_nif_prime(PrimeField) -> PrimeField. term_to_nif_curve({A, B, Seed}) -> {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}. nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) -> - {term_to_nif_prime(PrimeField), term_to_nif_curve(Curve), ensure_int_as_bin(BasePoint), int_to_bin(Order), int_to_bin(CoFactor)}; + {term_to_nif_prime(PrimeField), term_to_nif_curve(Curve), ensure_int_as_bin(BasePoint), ensure_int_as_bin(Order), ensure_int_as_bin(CoFactor)}; nif_curve_params(Curve) when is_atom(Curve) -> %% named curve - Curve. + crypto_ec_curves:curve(Curve). %% MISC -------------------------------------------------------------------- diff --git a/lib/crypto/src/crypto_ec_curves.erl b/lib/crypto/src/crypto_ec_curves.erl new file mode 100644 index 0000000000..fe17643d96 --- /dev/null +++ b/lib/crypto/src/crypto_ec_curves.erl @@ -0,0 +1,1215 @@ +-module(crypto_ec_curves). + +-export([curve/1, curves/0]). + +curves() -> + CryptoSupport = crypto:supports(), + HasGF2m = proplists:get_bool(ec_gf2m, proplists:get_value(public_keys, CryptoSupport)), + prime_curves() ++ characteristic_two_curves(HasGF2m). + + +prime_curves() -> + [secp112r1,secp112r2,secp128r1,secp128r2,secp160k1,secp160r1,secp160r2, + secp192r1,secp192k1,secp224k1,secp224r1,secp256k1,secp256r1,secp384r1, + secp521r1,prime192v1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3, + prime256v1,wtls6,wtls7,wtls8,wtls9,wtls12, + brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1, + brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1, + brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1, + brainpoolP512r1,brainpoolP512t1]. + +characteristic_two_curves(true) -> + [sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1, + sect163r2,sect193r1,sect193r2,sect233k1,sect233r1,sect239k1,sect283k1, + sect283r1,sect409k1,sect409r1,sect571k1,sect571r1,c2pnb163v1,c2pnb163v2, + c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1, + c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359v1,c2pnb368w1,c2tnb431r1, + wtls1,wtls3,wtls4,wtls5,wtls10,wtls11,ipsec3,ipsec4]; +characteristic_two_curves(_) -> + []. + +curve(secp112r1) -> + { + {prime_field, <<16#DB7C2ABF62E35E668076BEAD208B:112>>}, %% Prime + {<<16#DB7C2ABF62E35E668076BEAD2088:112>>, %% A + <<16#659EF8BA043916EEDE8911702B22:112>>, %% B + <<16#00F50B028E4D696E676875615175290472783FB1:160>>}, %% Seed + <<16#04:8, + 16#09487239995A5EE76B55F9C2F098:112, %% X(p0) + 16#A89CE5AF8724C0A23E0E0FF77500:112>>, %% Y(p0) + <<16#DB7C2ABF62E35E7628DFAC6561C5:112>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp112r2) -> + { + {prime_field, <<16#DB7C2ABF62E35E668076BEAD208B:112>>}, %% Prime + {<<16#6127C24C05F38A0AAAF65C0EF02C:112>>, %% A + <<16#51DEF1815DB5ED74FCC34C85D709:112>>, %% B + <<16#002757A1114D696E6768756151755316C05E0BD4:160>>}, %% Seed + <<16#04:8, + 16#4BA30AB5E892B4E1649DD0928643:112, %% X(p0) + 16#ADCD46F5882E3747DEF36E956E97:112>>, %% Y(p0) + <<16#36DF0AAFD8B8D7597CA10520D04B:112>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(secp128r1) -> + { + {prime_field, <<16#FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF:128>>}, %% Prime + {<<16#FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC:128>>, %% A + <<16#E87579C11079F43DD824993C2CEE5ED3:128>>, %% B + <<16#000E0D4D696E6768756151750CC03A4473D03679:160>>}, %% Seed + <<16#04:8, + 16#161FF7528B899B2D0C28607CA52C5B86:128, %% X(p0) + 16#CF5AC8395BAFEB13C02DA292DDED7A83:128>>, %% Y(p0) + <<16#FFFFFFFE0000000075A30D1B9038A115:128>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp128r2) -> + { + {prime_field, <<16#FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF:128>>}, %% Prime + {<<16#D6031998D1B3BBFEBF59CC9BBFF9AEE1:128>>, %% A + <<16#5EEEFCA380D02919DC2C6558BB6D8A5D:128>>, %% B + <<16#004D696E67687561517512D8F03431FCE63B88F4:160>>}, %% Seed + <<16#04:8, + 16#7B6AA5D85E572983E6FB32A7CDEBC140:128, %% X(p0) + 16#27B6916A894D3AEE7106FE805FC34B44:128>>, %% Y(p0) + <<16#3FFFFFFF7FFFFFFFBE0024720613B5A3:128>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(secp160k1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73:160>>}, %% Prime + {<<16#00:8>>, %% A + <<16#07:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#3B4C382CE37AA192A4019E763036F4F5DD4D7EBB:160, %% X(p0) + 16#938CF935318FDCED6BC28286531733C3F03C4FEE:160>>, %% Y(p0) + <<16#0100000000000000000001B8FA16DFAB9ACA16B6B3:168>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp160r1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF:160>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC:160>>, %% A + <<16#1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45:160>>, %% B + <<16#1053CDE42C14D696E67687561517533BF3F83345:160>>}, %% Seed + <<16#04:8, + 16#4A96B5688EF573284664698968C38BB913CBFC82:160, %% X(p0) + 16#23A628553168947D59DCC912042351377AC5FB32:160>>, %% Y(p0) + <<16#0100000000000000000001F4C8F927AED3CA752257:168>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp160r2) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73:160>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70:160>>, %% A + <<16#B4E134D3FB59EB8BAB57274904664D5AF50388BA:160>>, %% B + <<16#B99B99B099B323E02709A4D696E6768756151751:160>>}, %% Seed + <<16#04:8, + 16#52DCB034293A117E1F4FF11B30F7199D3144CE6D:160, %% X(p0) + 16#FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E:160>>, %% Y(p0) + <<16#0100000000000000000000351EE786A818F3A1A16B:168>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp192r1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF:192>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC:192>>, %% A + <<16#64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1:192>>, %% B + <<16#3045AE6FC8422F64ED579528D38120EAE12196D5:160>>}, %% Seed + <<16#04:8, + 16#188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012:192, %% X(p0) + 16#07192B95FFC8DA78631011ED6B24CDD573F977A11E794811:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp192k1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37:192>>}, %% Prime + {<<16#00:8>>, %% A + <<16#03:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D:192, %% X(p0) + 16#9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp224k1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D:224>>}, %% Prime + {<<16#00:8>>, %% A + <<16#05:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C:224, %% X(p0) + 16#7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5:224>>, %% Y(p0) + <<16#010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7:232>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp224r1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001:224>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE:224>>, %% A + <<16#B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4:224>>, %% B + <<16#BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5:160>>}, %% Seed + <<16#04:8, + 16#B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21:224, %% X(p0) + 16#BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34:224>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D:224>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp256k1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F:256>>}, %% Prime + {<<16#00:8>>, %% A + <<16#07:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798:256, %% X(p0) + 16#483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8:256>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141:256>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp256r1) -> + { + {prime_field, <<16#FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF:256>>}, %% Prime + {<<16#FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC:256>>, %% A + <<16#5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B:256>>, %% B + <<16#C49D360886E704936A6678E1139D26B7819F7E90:160>>}, %% Seed + <<16#04:8, + 16#6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296:256, %% X(p0) + 16#4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5:256>>, %% Y(p0) + <<16#FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551:256>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(secp384r1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE:256, %% Prime + 16#FFFFFFFF0000000000000000FFFFFFFF:128>>}, + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE:256, %% A + 16#FFFFFFFF0000000000000000FFFFFFFC:128>>, + <<16#B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875A:256, %% B + 16#C656398D8A2ED19D2A85C8EDD3EC2AEF:128>>, + <<16#A335926AA319A27A1D00896A6773A4827ACDAC73:160>>}, %% Seed + <<16#04:8, + 16#AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A38:256, %% X(p0) + 16#5502F25DBF55296C3A545E3872760AB7:128, + 16#3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C0:256, %% Y(p0) + 16#0A60B1CE1D7E819D7A431D7C90EA0E5F:128>>, + <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF:256, %% Order + 16#581A0DB248B0A77AECEC196ACCC52973:128>>, + <<16#01:8>> %% CoFactor + }; + +curve(secp521r1) -> + { + {prime_field, <<16#01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, %% Prime + 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, + 16#FFFF:16>>}, + {<<16#01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, %% A + 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, + 16#FFFC:16>>, + <<16#51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109:256, %% B + 16#E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F:256, + 16#00:8>>, + <<16#D09E8800291CB85396CC6717393284AAA0DA64BA:160>>}, %% Seed + <<16#04:8, + 16#00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D:256, %% X(p0) + 16#3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5:256, + 16#BD66:16, + 16#011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E:256, %% Y(p0) + 16#662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1:256, + 16#6650:16>>, + <<16#01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, %% Order + 16#FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138:256, + 16#6409:16>>, + <<16#01:8>> %% CoFactor + }; + +curve(prime192v1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF:192>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC:192>>, %% A + <<16#64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1:192>>, %% B + <<16#3045AE6FC8422F64ED579528D38120EAE12196D5:160>>}, %% Seed + <<16#04:8, + 16#188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012:192, %% X(p0) + 16#07192B95FFC8DA78631011ED6B24CDD573F977A11E794811:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime192v2) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF:192>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC:192>>, %% A + <<16#CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953:192>>, %% B + <<16#31A92EE2029FD10D901B113E990710F0D21AC6B6:160>>}, %% Seed + <<16#04:8, + 16#EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A:192, %% X(p0) + 16#6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime192v3) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF:192>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC:192>>, %% A + <<16#22123DC2395A05CAA7423DAECCC94760A7D462256BD56916:192>>, %% B + <<16#C469684435DEB378C4B65CA9591E2A5763059A2E:160>>}, %% Seed + <<16#04:8, + 16#7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896:192, %% X(p0) + 16#38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime239v1) -> + { + {prime_field, <<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF:240>>}, %% Prime + {<<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC:240>>, %% A + <<16#6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A:240>>, %% B + <<16#E43BB460F0B80CC0C0B075798E948060F8321B7D:160>>}, %% Seed + <<16#04:8, + 16#0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF:240, %% X(p0) + 16#7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE:240>>, %% Y(p0) + <<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B:240>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime239v2) -> + { + {prime_field, <<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF:240>>}, %% Prime + {<<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC:240>>, %% A + <<16#617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C:240>>, %% B + <<16#E8B4011604095303CA3B8099982BE09FCB9AE616:160>>}, %% Seed + <<16#04:8, + 16#38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7:240, %% X(p0) + 16#5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA:240>>, %% Y(p0) + <<16#7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063:240>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime239v3) -> + { + {prime_field, <<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF:240>>}, %% Prime + {<<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC:240>>, %% A + <<16#255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E:240>>, %% B + <<16#7D7374168FFE3471B60A857686A19475D3BFA2FF:160>>}, %% Seed + <<16#04:8, + 16#6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A:240, %% X(p0) + 16#1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3:240>>, %% Y(p0) + <<16#7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551:240>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(prime256v1) -> + { + {prime_field, <<16#FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF:256>>}, %% Prime + {<<16#FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC:256>>, %% A + <<16#5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B:256>>, %% B + <<16#C49D360886E704936A6678E1139D26B7819F7E90:160>>}, %% Seed + <<16#04:8, + 16#6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296:256, %% X(p0) + 16#4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5:256>>, %% Y(p0) + <<16#FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551:256>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(sect113r1) -> + { + {characteristic_two_field, 113, {tpbasis,9}}, + {<<16#3088250CA6E7C7FE649CE85820F7:112>>, %% A + <<16#E8BEE4D3E2260744188BE0E9C723:112>>, %% B + <<16#10E723AB14D696E6768756151756FEBF8FCB49A9:160>>}, %% Seed + <<16#04:8, + 16#009D73616F35F4AB1407D73562C10F:120, %% X(p0) + 16#00A52830277958EE84D1315ED31886:120>>, %% Y(p0) + <<16#0100000000000000D9CCEC8A39E56F:120>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect113r2) -> + { + {characteristic_two_field, 113, {tpbasis,9}}, + {<<16#689918DBEC7E5A0DD6DFC0AA55C7:112>>, %% A + <<16#95E9A9EC9B297BD4BF36E059184F:112>>, %% B + <<16#10C0FB15760860DEF1EEF4D696E676875615175D:160>>}, %% Seed + <<16#04:8, + 16#01A57A6A7B26CA5EF52FCDB8164797:120, %% X(p0) + 16#00B3ADC94ED1FE674C06E695BABA1D:120>>, %% Y(p0) + <<16#010000000000000108789B2496AF93:120>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect131r1) -> + { + {characteristic_two_field, 131, {ppbasis,2,3,8}}, + {<<16#07A11B09A76B562144418FF3FF8C2570B8:136>>, %% A + <<16#0217C05610884B63B9C6C7291678F9D341:136>>, %% B + <<16#4D696E676875615175985BD3ADBADA21B43A97E2:160>>}, %% Seed + <<16#04:8, + 16#0081BAF91FDF9833C40F9C181343638399:136, %% X(p0) + 16#078C6E7EA38C001F73C8134B1B4EF9E150:136>>, %% Y(p0) + <<16#0400000000000000023123953A9464B54D:136>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect131r2) -> + { + {characteristic_two_field, 131, {ppbasis,2,3,8}}, + {<<16#03E5A88919D7CAFCBF415F07C2176573B2:136>>, %% A + <<16#04B8266A46C55657AC734CE38F018F2192:136>>, %% B + <<16#985BD3ADBAD4D696E676875615175A21B43A97E3:160>>}, %% Seed + <<16#04:8, + 16#0356DCD8F2F95031AD652D23951BB366A8:136, %% X(p0) + 16#0648F06D867940A5366D9E265DE9EB240F:136>>, %% Y(p0) + <<16#0400000000000000016954A233049BA98F:136>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect163k1) -> + { + {characteristic_two_field, 163, {ppbasis,3,6,7}}, + {<<16#01:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8:168, %% X(p0) + 16#0289070FB05D38FF58321F2E800536D538CCDAA3D9:168>>, %% Y(p0) + <<16#04000000000000000000020108A2E0CC0D99F8A5EF:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect163r1) -> + { + {characteristic_two_field, 163, {ppbasis,3,6,7}}, + {<<16#07B6882CAAEFA84F9554FF8428BD88E246D2782AE2:168>>, %% A + <<16#0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9:168>>, %% B + none}, %% Seed + <<16#04:8, + 16#0369979697AB43897789566789567F787A7876A654:168, %% X(p0) + 16#00435EDB42EFAFB2989D51FEFCE3C80988F41FF883:168>>, %% Y(p0) + <<16#03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect163r2) -> + { + {characteristic_two_field, 163, {ppbasis,3,6,7}}, + {<<16#01:8>>, %% A + <<16#020A601907B8C953CA1481EB10512F78744A3205FD:168>>, %% B + none}, %% Seed + <<16#04:8, + 16#03F0EBA16286A2D57EA0991168D4994637E8343E36:168, %% X(p0) + 16#00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1:168>>, %% Y(p0) + <<16#040000000000000000000292FE77E70C12A4234C33:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect193r1) -> + { + {characteristic_two_field, 193, {tpbasis,15}}, + {<<16#17858FEB7A98975169E171F77B4087DE098AC8A911DF7B01:192>>, %% A + <<16#FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814:192>>, %% B + <<16#103FAEC74D696E676875615175777FC5B191EF30:160>>}, %% Seed + <<16#04:8, + 16#01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1:200, %% X(p0) + 16#0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05:200>>, %% Y(p0) + <<16#01000000000000000000000000C7F34A778F443ACC920EBA49:200>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect193r2) -> + { + {characteristic_two_field, 193, {tpbasis,15}}, + {<<16#0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B:200>>, %% A + <<16#C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE:192>>, %% B + <<16#10B7B4D696E676875615175137C8A16FD0DA2211:160>>}, %% Seed + <<16#04:8, + 16#00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F:200, %% X(p0) + 16#01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C:200>>, %% Y(p0) + <<16#010000000000000000000000015AAB561B005413CCD4EE99D5:200>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect233k1) -> + { + {characteristic_two_field, 233, {tpbasis,74}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126:240, %% X(p0) + 16#01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3:240>>, %% Y(p0) + <<16#8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF:232>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(sect233r1) -> + { + {characteristic_two_field, 233, {tpbasis,74}}, + {<<16#01:8>>, %% A + <<16#66647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD:232>>, %% B + <<16#74D59FF07F6B413D0EA14B344B20A2DB049B50C3:160>>}, %% Seed + <<16#04:8, + 16#00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B:240, %% X(p0) + 16#01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052:240>>, %% Y(p0) + <<16#01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7:240>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(sect239k1) -> + { + {characteristic_two_field, 239, {tpbasis,158}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC:240, %% X(p0) + 16#76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA:240>>, %% Y(p0) + <<16#2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5:240>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(sect283k1) -> + { + {characteristic_two_field, 283, {ppbasis,5,7,12}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC24:256, %% X(p0) + 16#58492836:32, + 16#01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E341161:256, %% Y(p0) + 16#77DD2259:32>>, + <<16#01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E06:256, %% Order + 16#1E163C61:32>>, + <<16#04:8>> %% CoFactor + }; + +curve(sect283r1) -> + { + {characteristic_two_field, 283, {ppbasis,5,7,12}}, + {<<16#01:8>>, %% A + <<16#027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E31:256, %% B + 16#3B79A2F5:32>>, + <<16#77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE:160>>}, %% Seed + <<16#04:8, + 16#05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD:256, %% X(p0) + 16#86B12053:32, + 16#03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45:256, %% Y(p0) + 16#BE8112F4:32>>, + <<16#03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7C:256, %% Order + 16#EFADB307:32>>, + <<16#02:8>> %% CoFactor + }; + +curve(sect409k1) -> + { + {characteristic_two_field, 409, {tpbasis,87}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2:256, %% X(p0) + 16#C460189EB5AAAA62EE222EB1B35540CFE9023746:160, + 16#01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3:256, %% Y(p0) + 16#DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B:160>>, + <<16#7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20:256, %% Order + 16#400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF:152>>, + <<16#04:8>> %% CoFactor + }; + +curve(sect409r1) -> + { + {characteristic_two_field, 409, {tpbasis,87}}, + {<<16#01:8>>, %% A + <<16#21A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9:256, %% B + 16#A197B272822F6CD57A55AA4F50AE317B13545F:152>>, + <<16#4099B5A457F9D69F79213D094C4BCD4D4262210B:160>>}, %% Seed + <<16#04:8, + 16#015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703:256, %% X(p0) + 16#DC255A868A1180515603AEAB60794E54BB7996A7:160, + 16#0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F:256, %% Y(p0) + 16#38514F1FDF4B4F40D2181B3681C364BA0273C706:160>>, + <<16#010000000000000000000000000000000000000000000000000001E2AAD6A612:256, %% Order + 16#F33307BE5FA47C3C9E052F838164CD37D9A21173:160>>, + <<16#02:8>> %% CoFactor + }; + +curve(sect571k1) -> + { + {characteristic_two_field, 571, {ppbasis,2,5,10}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA4:256, %% X(p0) + 16#4370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7:256, + 16#E2945283A01C8972:64, + 16#0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C:256, %% Y(p0) + 16#9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F6:256, + 16#01CD4C143EF1C7A3:64>>, + <<16#0200000000000000000000000000000000000000000000000000000000000000:256, %% Order + 16#00000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB4:256, + 16#5CFE778F637C1001:64>>, + <<16#04:8>> %% CoFactor + }; + +curve(sect571r1) -> + { + {characteristic_two_field, 571, {ppbasis,2,5,10}}, + {<<16#01:8>>, %% A + <<16#02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD:256, %% B + 16#84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C:256, + 16#7FFEFF7F2955727A:64>>, + <<16#2AA058F73A0E33AB486B0F610410C53A7F132310:160>>}, %% Seed + <<16#04:8, + 16#0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABD:256, %% X(p0) + 16#BDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927:256, + 16#E1E7769C8EEC2D19:64, + 16#037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A6:256, %% Y(p0) + 16#84423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C:256, + 16#1A4827AF1B8AC15B:64>>, + <<16#03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:256, %% Order + 16#FFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E:256, + 16#8382E9BB2FE84E47:64>>, + <<16#02:8>> %% CoFactor + }; + +curve(c2pnb163v1) -> + { + {characteristic_two_field, 163, {ppbasis,1,2,8}}, + {<<16#072546B5435234A422E0789675F432C89435DE5242:168>>, %% A + <<16#C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9:160>>, %% B + <<16#D2C0FB15760860DEF1EEF4D696E6768756151754:160>>}, %% Seed + <<16#04:8, + 16#07AF69989546103D79329FCC3D74880F33BBE803CB:168, %% X(p0) + 16#01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F:168>>, %% Y(p0) + <<16#0400000000000000000001E60FC8821CC74DAEAFC1:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(c2pnb163v2) -> + { + {characteristic_two_field, 163, {ppbasis,1,2,8}}, + {<<16#0108B39E77C4B108BED981ED0E890E117C511CF072:168>>, %% A + <<16#0667ACEB38AF4E488C407433FFAE4F1C811638DF20:168>>, %% B + <<16#53814C050D44D696E67687561517580CA4E29FFD:160>>}, %% Seed + <<16#04:8, + 16#0024266E4EB5106D0A964D92C4860E2671DB9B6CC5:168, %% X(p0) + 16#079F684DDF6684C5CD258B3890021B2386DFD19FC5:168>>, %% Y(p0) + <<16#03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(c2pnb163v3) -> + { + {characteristic_two_field, 163, {ppbasis,1,2,8}}, + {<<16#07A526C63D3E25A256A007699F5447E32AE456B50E:168>>, %% A + <<16#03F7061798EB99E238FD6F1BF95B48FEEB4854252B:168>>, %% B + <<16#50CBF1D95CA94D696E676875615175F16A36A3B8:160>>}, %% Seed + <<16#04:8, + 16#02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB:168, %% X(p0) + 16#05B935590C155E17EA48EB3FF3718B893DF59A05D0:168>>, %% Y(p0) + <<16#03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(c2pnb176v1) -> + { + {characteristic_two_field, 176, {ppbasis,1,2,43}}, + {<<16#E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B:176>>, %% A + <<16#5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2:176>>, %% B + none}, %% Seed + <<16#04:8, + 16#8D16C2866798B600F9F08BB4A8E860F3298CE04A5798:176, %% X(p0) + 16#6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C:176>>, %% Y(p0) + <<16#010092537397ECA4F6145799D62B0A19CE06FE26AD:168>>, %% Order + <<16#FF6E:16>> %% CoFactor + }; + +curve(c2tnb191v1) -> + { + {characteristic_two_field, 191, {tpbasis,9}}, + {<<16#2866537B676752636A68F56554E12640276B649EF7526267:192>>, %% A + <<16#2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC:192>>, %% B + <<16#4E13CA542744D696E67687561517552F279A8C84:160>>}, %% Seed + <<16#04:8, + 16#36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D:192, %% X(p0) + 16#765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB:192>>, %% Y(p0) + <<16#40000000000000000000000004A20E90C39067C893BBB9A5:192>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(c2tnb191v2) -> + { + {characteristic_two_field, 191, {tpbasis,9}}, + {<<16#401028774D7777C7B7666D1366EA432071274F89FF01E718:192>>, %% A + <<16#0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01:192>>, %% B + <<16#0871EF2FEF24D696E6768756151758BEE0D95C15:160>>}, %% Seed + <<16#04:8, + 16#3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10:192, %% X(p0) + 16#17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A:192>>, %% Y(p0) + <<16#20000000000000000000000050508CB89F652824E06B8173:192>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(c2tnb191v3) -> + { + {characteristic_two_field, 191, {tpbasis,9}}, + {<<16#6C01074756099122221056911C77D77E77A777E7E7E77FCB:192>>, %% A + <<16#71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8:192>>, %% B + <<16#E053512DC684D696E676875615175067AE786D1F:160>>}, %% Seed + <<16#04:8, + 16#375D4CE24FDE434489DE8746E71786015009E66E38A926DD:192, %% X(p0) + 16#545A39176196575D985999366E6AD34CE0A77CD7127B06BE:192>>, %% Y(p0) + <<16#155555555555555555555555610C0B196812BFB6288A3EA3:192>>, %% Order + <<16#06:8>> %% CoFactor + }; + +curve(c2pnb208w1) -> + { + {characteristic_two_field, 208, {ppbasis,1,2,83}}, + {<<16#00:8>>, %% A + <<16#C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E:208>>, %% B + none}, %% Seed + <<16#04:8, + 16#89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A:208, %% X(p0) + 16#0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3:208>>, %% Y(p0) + <<16#0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D:200>>, %% Order + <<16#FE48:16>> %% CoFactor + }; + +curve(c2tnb239v1) -> + { + {characteristic_two_field, 239, {tpbasis,36}}, + {<<16#32010857077C5431123A46B808906756F543423E8D27877578125778AC76:240>>, %% A + <<16#790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16:240>>, %% B + <<16#D34B9A4D696E676875615175CA71B920BFEFB05D:160>>}, %% Seed + <<16#04:8, + 16#57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D:240, %% X(p0) + 16#61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305:240>>, %% Y(p0) + <<16#2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447:240>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(c2tnb239v2) -> + { + {characteristic_two_field, 239, {tpbasis,36}}, + {<<16#4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F:240>>, %% A + <<16#5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B:240>>, %% B + <<16#2AA6982FDFA4D696E676875615175D266727277D:160>>}, %% Seed + <<16#04:8, + 16#28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205:240, %% X(p0) + 16#5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833:240>>, %% Y(p0) + <<16#1555555555555555555555555555553C6F2885259C31E3FCDF154624522D:240>>, %% Order + <<16#06:8>> %% CoFactor + }; + +curve(c2tnb239v3) -> + { + {characteristic_two_field, 239, {tpbasis,36}}, + {<<16#01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F:240>>, %% A + <<16#6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40:240>>, %% B + <<16#9E076F4D696E676875615175E11E9FDD77F92041:160>>}, %% Seed + <<16#04:8, + 16#70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92:240, %% X(p0) + 16#2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461:240>>, %% Y(p0) + <<16#0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF:240>>, %% Order + <<16#0A:8>> %% CoFactor + }; + +curve(c2pnb272w1) -> + { + {characteristic_two_field, 272, {ppbasis,1,3,56}}, + {<<16#91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586:256, %% A + 16#FB20:16>>, + <<16#7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E5:256, %% B + 16#40F7:16>>, + none}, %% Seed + <<16#04:8, + 16#6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171:256, %% X(p0) + 16#DD8D:16, + 16#10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE:256, %% Y(p0) + 16#9D23:16>>, + <<16#0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E6295:256, %% Order + 16#21:8>>, + <<16#FF06:16>> %% CoFactor + }; + +curve(c2pnb304w1) -> + { + {characteristic_two_field, 304, {ppbasis,1,2,11}}, + {<<16#FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C128807836:256, %% A + 16#5A0396C8E681:48>>, + <<16#BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C1403960:256, %% B + 16#1E55827340BE:48>>, + none}, %% Seed + <<16#04:8, + 16#197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A:256, %% X(p0) + 16#644F740A2614:48, + 16#E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B54:256, %% Y(p0) + 16#9FDC1B92C03B:48>>, + <<16#0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899:256, %% Order + 16#164443051D:40>>, + <<16#FE2E:16>> %% CoFactor + }; + +curve(c2tnb359v1) -> + { + {characteristic_two_field, 359, {tpbasis,68}}, + {<<16#5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223:256, %% A + 16#A5E05656FB549016A96656A557:104>>, + <<16#2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626:256, %% B + 16#089687742B6329E70680231988:104>>, + <<16#2B354920B724D696E67687561517585BA1332DC6:160>>}, %% Seed + <<16#04:8, + 16#3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6B:256, %% X(p0) + 16#DCDE98E8E707C07A2239B1B097:104, + 16#53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868:256, %% Y(p0) + 16#FE57E4AE2DE211305A407104BD:104>>, + <<16#01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20:256, %% Order + 16#A7EB964FE7719E74F490758D3B:104>>, + <<16#4C:8>> %% CoFactor + }; + +curve(c2pnb368w1) -> + { + {characteristic_two_field, 368, {ppbasis,1,2,85}}, + {<<16#E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C5:256, %% A + 16#76D62F0AB7519CCD2A1A906AE30D:112>>, + <<16#FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1:256, %% B + 16#C2112D84D164F444F8F74786046A:112>>, + none}, %% Seed + <<16#04:8, + 16#1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22:256, %% X(p0) + 16#E7E789E927BE216F02E1FB136A5F:112, + 16#7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87C:256, %% Y(p0) + 16#D1855ADAA81E2A0750B80FDA2310:112>>, + <<16#010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87:256, %% Order + 16#E909AE40A6F131E9CFCE5BD967:104>>, + <<16#FF70:16>> %% CoFactor + }; + +curve(c2tnb431r1) -> + { + {characteristic_two_field, 431, {tpbasis,120}}, + {<<16#1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF6:256, %% A + 16#20B0EB9906D0957F6C6FEACD615468DF104DE296CD8F:176>>, + <<16#10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A:256, %% B + 16#919B626D4E50A8DD731B107A9962381FB5D807BF2618:176>>, + none}, %% Seed + <<16#04:8, + 16#120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658:256, %% X(p0) + 16#EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7:176, + 16#20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F:256, %% Y(p0) + 16#3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760:176>>, + <<16#0340340340340340340340340340340340340340340340340340340323C313FA:256, %% Order + 16#B50589703B5EC68D3587FEC60D161CC149C1AD4A91:168>>, + <<16#2760:16>> %% CoFactor + }; + +curve(wtls1) -> + { + {characteristic_two_field, 113, {tpbasis,9}}, + {<<16#01:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#01667979A40BA497E5D5C270780617:120, %% X(p0) + 16#00F44B4AF1ECC2630E08785CEBCC15:120>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFDBF91AF6DEA73:112>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(wtls3) -> + { + {characteristic_two_field, 163, {ppbasis,3,6,7}}, + {<<16#01:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8:168, %% X(p0) + 16#0289070FB05D38FF58321F2E800536D538CCDAA3D9:168>>, %% Y(p0) + <<16#04000000000000000000020108A2E0CC0D99F8A5EF:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(wtls4) -> + { + {characteristic_two_field, 113, {tpbasis,9}}, + {<<16#3088250CA6E7C7FE649CE85820F7:112>>, %% A + <<16#E8BEE4D3E2260744188BE0E9C723:112>>, %% B + <<16#10E723AB14D696E6768756151756FEBF8FCB49A9:160>>}, %% Seed + <<16#04:8, + 16#009D73616F35F4AB1407D73562C10F:120, %% X(p0) + 16#00A52830277958EE84D1315ED31886:120>>, %% Y(p0) + <<16#0100000000000000D9CCEC8A39E56F:120>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(wtls5) -> + { + {characteristic_two_field, 163, {ppbasis,1,2,8}}, + {<<16#072546B5435234A422E0789675F432C89435DE5242:168>>, %% A + <<16#C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9:160>>, %% B + <<16#D2C0FB15760860DEF1EEF4D696E6768756151754:160>>}, %% Seed + <<16#04:8, + 16#07AF69989546103D79329FCC3D74880F33BBE803CB:168, %% X(p0) + 16#01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F:168>>, %% Y(p0) + <<16#0400000000000000000001E60FC8821CC74DAEAFC1:168>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(wtls6) -> + { + {prime_field, <<16#DB7C2ABF62E35E668076BEAD208B:112>>}, %% Prime + {<<16#DB7C2ABF62E35E668076BEAD2088:112>>, %% A + <<16#659EF8BA043916EEDE8911702B22:112>>, %% B + <<16#00F50B028E4D696E676875615175290472783FB1:160>>}, %% Seed + <<16#04:8, + 16#09487239995A5EE76B55F9C2F098:112, %% X(p0) + 16#A89CE5AF8724C0A23E0E0FF77500:112>>, %% Y(p0) + <<16#DB7C2ABF62E35E7628DFAC6561C5:112>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(wtls7) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73:160>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70:160>>, %% A + <<16#B4E134D3FB59EB8BAB57274904664D5AF50388BA:160>>, %% B + <<16#B99B99B099B323E02709A4D696E6768756151751:160>>}, %% Seed + <<16#04:8, + 16#52DCB034293A117E1F4FF11B30F7199D3144CE6D:160, %% X(p0) + 16#FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E:160>>, %% Y(p0) + <<16#0100000000000000000000351EE786A818F3A1A16B:168>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(wtls8) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFDE7:112>>}, %% Prime + {<<16#00:8>>, %% A + <<16#03:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#0000000000000000000000000001:112, %% X(p0) + 16#0000000000000000000000000002:112>>, %% Y(p0) + <<16#0100000000000001ECEA551AD837E9:120>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(wtls9) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F:160>>}, %% Prime + {<<16#00:8>>, %% A + <<16#03:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#0000000000000000000000000000000000000001:160, %% X(p0) + 16#0000000000000000000000000000000000000002:160>>, %% Y(p0) + <<16#0100000000000000000001CDC98AE0E2DE574ABF33:168>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(wtls10) -> + { + {characteristic_two_field, 233, {tpbasis,74}}, + {<<16#00:8>>, %% A + <<16#01:8>>, %% B + none}, %% Seed + <<16#04:8, + 16#017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126:240, %% X(p0) + 16#01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3:240>>, %% Y(p0) + <<16#8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF:232>>, %% Order + <<16#04:8>> %% CoFactor + }; + +curve(wtls11) -> + { + {characteristic_two_field, 233, {tpbasis,74}}, + {<<16#01:8>>, %% A + <<16#66647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD:232>>, %% B + <<16#74D59FF07F6B413D0EA14B344B20A2DB049B50C3:160>>}, %% Seed + <<16#04:8, + 16#00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B:240, %% X(p0) + 16#01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052:240>>, %% Y(p0) + <<16#01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7:240>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(wtls12) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001:224>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE:224>>, %% A + <<16#B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4:224>>, %% B + none}, %% Seed + <<16#04:8, + 16#B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21:224, %% X(p0) + 16#BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34:224>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D:224>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(ipsec3) -> + { + {characteristic_two_field, 155, {tpbasis,62}}, + {<<16#00:8>>, %% A + <<16#07338F:24>>, %% B + none}, %% Seed + <<16#04:8, + 16#000000000000000000000000000000000000007B:160, %% X(p0) + 16#00000000000000000000000000000000000001C8:160>>, %% Y(p0) + <<16#02AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C:160>>, %% Order + <<16#03:8>> %% CoFactor + }; + +curve(ipsec4) -> + { + {characteristic_two_field, 185, {tpbasis,69}}, + {<<16#00:8>>, %% A + <<16#1EE9:16>>, %% B + none}, %% Seed + <<16#04:8, + 16#000000000000000000000000000000000000000000000018:192, %% X(p0) + 16#00000000000000000000000000000000000000000000000D:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E:184>>, %% Order + <<16#02:8>> %% CoFactor + }; + +curve(brainpoolP160r1) -> + { + {prime_field, <<16#E95E4A5F737059DC60DFC7AD95B3D8139515620F:160>>}, %% Prime + {<<16#340E7BE2A280EB74E2BE61BADA745D97E8F7C300:160>>, %% A + <<16#1E589A8595423412134FAA2DBDEC95C8D8675E58:160>>, %% B + none}, %% Seed + <<16#04:8, + 16#BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3:160, %% X(p0) + 16#1667CB477A1A8EC338F94741669C976316DA6321:160>>, %% Y(p0) + <<16#E95E4A5F737059DC60DF5991D45029409E60FC09:160>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP160t1) -> + { + {prime_field, <<16#E95E4A5F737059DC60DFC7AD95B3D8139515620F:160>>}, %% Prime + {<<16#E95E4A5F737059DC60DFC7AD95B3D8139515620C:160>>, %% A + <<16#7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380:160>>, %% B + none}, %% Seed + <<16#04:8, + 16#B199B13B9B34EFC1397E64BAEB05ACC265FF2378:160, %% X(p0) + 16#ADD6718B7C7C1961F0991B842443772152C9E0AD:160>>, %% Y(p0) + <<16#E95E4A5F737059DC60DF5991D45029409E60FC09:160>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP192r1) -> + { + {prime_field, <<16#C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297:192>>}, %% Prime + {<<16#6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF:192>>, %% A + <<16#469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9:192>>, %% B + none}, %% Seed + <<16#04:8, + 16#C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6:192, %% X(p0) + 16#14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F:192>>, %% Y(p0) + <<16#C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP192t1) -> + { + {prime_field, <<16#C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297:192>>}, %% Prime + {<<16#C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294:192>>, %% A + <<16#13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79:192>>, %% B + none}, %% Seed + <<16#04:8, + 16#3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129:192, %% X(p0) + 16#097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9:192>>, %% Y(p0) + <<16#C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP224r1) -> + { + {prime_field, <<16#D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF:224>>}, %% Prime + {<<16#68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43:224>>, %% A + <<16#2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B:224>>, %% B + none}, %% Seed + <<16#04:8, + 16#0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D:224, %% X(p0) + 16#58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD:224>>, %% Y(p0) + <<16#D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F:224>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP224t1) -> + { + {prime_field, <<16#D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF:224>>}, %% Prime + {<<16#D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC:224>>, %% A + <<16#4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D:224>>, %% B + none}, %% Seed + <<16#04:8, + 16#6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580:224, %% X(p0) + 16#0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C:224>>, %% Y(p0) + <<16#D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F:224>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP256r1) -> + { + {prime_field, <<16#A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377:256>>}, %% Prime + {<<16#7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9:256>>, %% A + <<16#26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6:256>>, %% B + none}, %% Seed + <<16#04:8, + 16#8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262:256, %% X(p0) + 16#547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997:256>>, %% Y(p0) + <<16#A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7:256>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP256t1) -> + { + {prime_field, <<16#A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377:256>>}, %% Prime + {<<16#A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374:256>>, %% A + <<16#662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04:256>>, %% B + none}, %% Seed + <<16#04:8, + 16#A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4:256, %% X(p0) + 16#2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE:256>>, %% Y(p0) + <<16#A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7:256>>, %% Order + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP320r1) -> + { + {prime_field, <<16#D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28:256, %% Prime + 16#FCD412B1F1B32E27:64>>}, + {<<16#3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4:256, %% A + 16#92F375A97D860EB4:64>>, + <<16#520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981:256, %% B + 16#6F5EB4AC8FB1F1A6:64>>, + none}, %% Seed + <<16#04:8, + 16#43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7:256, %% X(p0) + 16#10AF8D0D39E20611:64, + 16#14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7:256, %% Y(p0) + 16#D35245D1692E8EE1:64>>, + <<16#D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E9:256, %% Order + 16#8691555B44C59311:64>>, + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP320t1) -> + { + {prime_field, <<16#D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28:256, %% Prime + 16#FCD412B1F1B32E27:64>>}, + {<<16#D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28:256, %% A + 16#FCD412B1F1B32E24:64>>, + <<16#A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE:256, %% B + 16#B5B4FEF422340353:64>>, + none}, %% Seed + <<16#04:8, + 16#925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF:256, %% X(p0) + 16#3357F624A21BED52:64, + 16#63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B:256, %% Y(p0) + 16#1B9BC0455FB0D2C3:64>>, + <<16#D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E9:256, %% Order + 16#8691555B44C59311:64>>, + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP384r1) -> + { + {prime_field, <<16#8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123:256, %% Prime + 16#ACD3A729901D1A71874700133107EC53:128>>}, + {<<16#7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F:256, %% A + 16#8AA5814A503AD4EB04A8C7DD22CE2826:128>>, + <<16#04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D5:256, %% B + 16#7CB4390295DBC9943AB78696FA504C11:128>>, + none}, %% Seed + <<16#04:8, + 16#1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8:256, %% X(p0) + 16#E826E03436D646AAEF87B2E247D4AF1E:128, + 16#8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF9912928:256, %% Y(p0) + 16#0E4646217791811142820341263C5315:128>>, + <<16#8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7:256, %% Order + 16#CF3AB6AF6B7FC3103B883202E9046565:128>>, + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP384t1) -> + { + {prime_field, <<16#8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123:256, %% Prime + 16#ACD3A729901D1A71874700133107EC53:128>>}, + {<<16#8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123:256, %% A + 16#ACD3A729901D1A71874700133107EC50:128>>, + <<16#7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D:256, %% B + 16#2074AA263B88805CED70355A33B471EE:128>>, + none}, %% Seed + <<16#04:8, + 16#18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFF:256, %% X(p0) + 16#C4FF191B946A5F54D8D0AA2F418808CC:128, + 16#25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE:256, %% Y(p0) + 16#469408584DC2B2912675BF5B9E582928:128>>, + <<16#8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7:256, %% Order + 16#CF3AB6AF6B7FC3103B883202E9046565:128>>, + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP512r1) -> + { + {prime_field, <<16#AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330871:256, %% Prime + 16#7D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3:256>>}, + {<<16#7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC:256, %% A + 16#2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA:256>>, + <<16#3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A7:256, %% B + 16#2BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723:256>>, + none}, %% Seed + <<16#04:8, + 16#81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098E:256, %% X(p0) + 16#FF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822:256, + 16#7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111:256, %% Y(p0) + 16#B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892:256>>, + <<16#AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870:256, %% Order + 16#553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069:256>>, + <<16#01:8>> %% CoFactor + }; + +curve(brainpoolP512t1) -> + { + {prime_field, <<16#AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330871:256, %% Prime + 16#7D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3:256>>}, + {<<16#AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330871:256, %% A + 16#7D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0:256>>, + <<16#7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A6:256, %% B + 16#2BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E:256>>, + none}, %% Seed + <<16#04:8, + 16#640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D:256, %% X(p0) + 16#82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA:256, + 16#5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9:256, %% Y(p0) + 16#D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332:256>>, + <<16#AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870:256, %% Order + 16#553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069:256>>, + <<16#01:8>> %% CoFactor + }. diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 42e200fcf0..d1be7cea68 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -437,7 +437,7 @@ do_generate_compute({dh, P, G}) -> SharedSecret = crypto:compute_key(dh, UserPub, HostPriv, [P, G]). do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) -> - Secret = crypto:bytes_to_integer(crypto:compute_key(Type, Pub, Priv, Curve)), + Secret = crypto:compute_key(Type, Pub, Priv, Curve), case Secret of SharedSecret -> ok; @@ -445,6 +445,9 @@ do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) -> ct:fail({{crypto, compute_key, [Type, Pub, Priv, Curve]}, {expected, SharedSecret}, {got, Other}}) end. +hexstr2point(X, Y) -> + <<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>. + hexstr2bin(S) -> list_to_binary(hexstr2list(S)). @@ -668,7 +671,7 @@ group_config(srp, Config) -> GenerateCompute = [srp3(), srp6(), srp6a()], [{generate_compute, GenerateCompute} | Config]; group_config(ecdh, Config) -> - Compute = [ecdh()], + Compute = ecdh(), [{compute, Compute} | Config]; group_config(dh, Config) -> GenerateCompute = [dh()], @@ -1498,9 +1501,89 @@ srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPriv {host, [Verifier, Prime, Version, Scrambler]}, SessionKey}. ecdh() -> - {ecdh, 10053111454769593468622878414300213417816614162107065345116848162553478019161427871683337786549966, - 1373339791687564785573162818422814591820885704654, - secp160r1, 990333295438215762119481641129490894973766052278}. + %% http://csrc.nist.gov/groups/STM/cavp/ + [{ecdh, hexstr2point("42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523"), + hexstr2bin("f17d3fea367b74d340851ca4270dcb24c271f445bed9d527"), + secp192r1, + hexstr2bin("803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0")}, + {ecdh, hexstr2point("deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125"), + hexstr2bin("56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5"), + secp192r1, + hexstr2bin("c208847568b98835d7312cef1f97f7aa298283152313c29d")}, + {ecdh, hexstr2point("af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7"), + hexstr2bin("8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd"), + secp224r1, + hexstr2bin("7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8")}, + {ecdh, hexstr2point("13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4"), + hexstr2bin("043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d"), + secp224r1, + hexstr2bin("ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09")}, + {ecdh, hexstr2point("700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287", "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"), + hexstr2bin("7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"), + secp256r1, + hexstr2bin("46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b")}, + {ecdh, hexstr2point("809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae", "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3"), + hexstr2bin("38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"), + secp256r1, + hexstr2bin("057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67")}, + {ecdh, hexstr2point("a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066", "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a"), + hexstr2bin("3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1"), + secp384r1, + hexstr2bin("5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1")}, + {ecdh, hexstr2point("30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757"), + hexstr2bin("92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783"), + secp384r1, + hexstr2bin("a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff")}, + {ecdh, hexstr2point("00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d", "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676"), + hexstr2bin("017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47"), + secp521r1, + hexstr2bin("005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831")}, + {ecdh, hexstr2point("01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", "013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0"), + hexstr2bin("00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8"), + secp521r1, + hexstr2bin("000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759")}, + + %% RFC-6954, Appendix A + {ecdh, hexstr2point("A9C21A569759DA95E0387041184261440327AFE33141CA04B82DC92E", + "98A0F75FBBF61D8E58AE5511B2BCDBE8E549B31E37069A2825F590C1"), + hexstr2bin("6060552303899E2140715816C45B57D9B42204FB6A5BF5BEAC10DB00"), + brainpoolP224r1, + hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")}, + {ecdh, hexstr2point("034A56C550FF88056144E6DD56070F54B0135976B5BF77827313F36B", + "75165AD99347DC86CAAB1CBB579E198EAF88DC35F927B358AA683681"), + hexstr2bin("39F155483CEE191FBECFE9C81D8AB1A03CDA6790E7184ACE44BCA161"), + brainpoolP224r1, + hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")}, + {ecdh, hexstr2point("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5", + "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC"), + hexstr2bin("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3"), + brainpoolP256r1, + hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")}, + {ecdh, hexstr2point("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B", + "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A"), + hexstr2bin("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D"), + brainpoolP256r1, + hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")}, + {ecdh, hexstr2point("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068", + "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59"), + hexstr2bin("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670"), + brainpoolP384r1, + hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")}, + {ecdh, hexstr2point("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4", + "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48"), + hexstr2bin("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042"), + brainpoolP384r1, + hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")}, + {ecdh, hexstr2point("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD", + "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7"), + hexstr2bin("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429"), + brainpoolP512r1, + hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")}, + {ecdh, hexstr2point("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F", + "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA"), + hexstr2bin("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422"), + brainpoolP512r1, + hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")}]. dh() -> {dh, 0087761979513264537414556992123116644042638206717762626089877284926656954974893442000747478454809111207351620687968672207938731607963470779396984752680274820156266685080223616226905101126463253150237669547023934604953898814222890239130021414026118792251620881355456432549881723310342870016961804255746630219, 2}. diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl index 6d4758bbf1..0e651a351c 100644 --- a/lib/hipe/icode/hipe_icode.erl +++ b/lib/hipe/icode/hipe_icode.erl @@ -1464,6 +1464,7 @@ successors(I) -> case fail_label(I) of [] -> []; L when is_integer(L) -> [L] end; #icode_enter{} -> []; #icode_return{} -> []; + #icode_comment{} -> []; %% the following are included here for handling linear code #icode_move{} -> []; #icode_begin_handler{} -> [] diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl index aa9f9f6774..f295453bdd 100644 --- a/lib/inets/src/http_lib/http_request.erl +++ b/lib/inets/src/http_lib/http_request.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -40,9 +40,6 @@ headers([Header | Tail], Headers) -> headers(Tail, headers(http_util:to_lower(string:strip(Key)), string:strip(Value), Headers)); {_, []} -> - Report = io_lib:format("Ignored invalid HTTP-header: ~p~n", - [Header]), - error_logger:error_report(Report), headers(Tail, Headers) end. diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile index 67555d5f1c..2660d04d16 100644 --- a/lib/inets/src/http_server/Makefile +++ b/lib/inets/src/http_server/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2005-2012. All Rights Reserved. +# Copyright Ericsson AB 2005-2013. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -43,6 +43,7 @@ MODULES = \ httpd \ httpd_acceptor \ httpd_acceptor_sup \ + httpd_connection_sup\ httpd_cgi \ httpd_conf \ httpd_example \ diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl index 93608dbf96..6052ae9022 100644 --- a/lib/inets/src/http_server/httpd.erl +++ b/lib/inets/src/http_server/httpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -36,13 +36,6 @@ %% API -export([parse_query/1, reload_config/2, info/1, info/2, info/3]). -%% Internal debugging and status info stuff... --export([ - get_status/1, get_status/2, get_status/3, - get_admin_state/0, get_admin_state/1, get_admin_state/2, - get_usage_state/0, get_usage_state/1, get_usage_state/2 - ]). - %%%======================================================================== %%% API %%%======================================================================== @@ -296,136 +289,6 @@ make_name(Addr, Port) -> httpd_util:make_name("httpd", Addr, Port). -%%%-------------------------------------------------------------- -%%% Internal debug functions - Do we want these functions here!? -%%%-------------------------------------------------------------------- - -%%% ========================================================= -%%% Function: get_admin_state/0, get_admin_state/1, get_admin_state/2 -%%% get_admin_state() -%%% get_admin_state(Port) -%%% get_admin_state(Addr,Port) -%%% -%%% Returns: {ok,State} | {error,Reason} -%%% -%%% Description: This function is used to retrieve the administrative -%%% state of the HTTP server. -%%% -%%% Types: Port -> integer() -%%% Addr -> {A,B,C,D} | string() | undefined -%%% State -> unblocked | shutting_down | blocked -%%% Reason -> term() -%%% -get_admin_state() -> get_admin_state(undefined,8888). -get_admin_state(Port) when is_integer(Port) -> get_admin_state(undefined,Port); - -get_admin_state(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - unblock(Addr,Port); - Error -> - Error - end. - -get_admin_state(Addr,Port) when is_integer(Port) -> - Name = make_name(Addr,Port), - case whereis(Name) of - Pid when is_pid(Pid) -> - httpd_manager:get_admin_state(Pid); - _ -> - {error,not_started} - end. - - - -%%% ========================================================= -%%% Function: get_usage_state/0, get_usage_state/1, get_usage_state/2 -%%% get_usage_state() -%%% get_usage_state(Port) -%%% get_usage_state(Addr,Port) -%%% -%%% Returns: {ok,State} | {error,Reason} -%%% -%%% Description: This function is used to retrieve the usage -%%% state of the HTTP server. -%%% -%%% Types: Port -> integer() -%%% Addr -> {A,B,C,D} | string() | undefined -%%% State -> idle | active | busy -%%% Reason -> term() -%%% -get_usage_state() -> get_usage_state(undefined,8888). -get_usage_state(Port) when is_integer(Port) -> get_usage_state(undefined,Port); - -get_usage_state(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - unblock(Addr,Port); - Error -> - Error - end. - -get_usage_state(Addr,Port) when is_integer(Port) -> - Name = make_name(Addr,Port), - case whereis(Name) of - Pid when is_pid(Pid) -> - httpd_manager:get_usage_state(Pid); - _ -> - {error,not_started} - end. - - - -%%% ========================================================= -%% Function: get_status(ConfigFile) -> Status -%% get_status(Port) -> Status -%% get_status(Addr,Port) -> Status -%% get_status(Port,Timeout) -> Status -%% get_status(Addr,Port,Timeout) -> Status -%% -%% Arguments: ConfigFile -> string() -%% Configuration file from which Port and -%% BindAddress will be extracted. -%% Addr -> {A,B,C,D} | string() -%% Bind Address of the http server -%% Port -> integer() -%% Port number of the http server -%% Timeout -> integer() -%% Timeout time for the call -%% -%% Returns: Status -> list() -%% -%% Description: This function is used when the caller runs in the -%% same node as the http server or if calling with a -%% program such as erl_call (see erl_interface). -%% - -get_status(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - get_status(Addr,Port); - Error -> - Error - end; - -get_status(Port) when is_integer(Port) -> - get_status(undefined,Port,5000). - -get_status(Port,Timeout) when is_integer(Port) andalso is_integer(Timeout) -> - get_status(undefined,Port,Timeout); - -get_status(Addr,Port) -> - get_status(Addr,Port,5000). - -get_status(Addr,Port,Timeout) when is_integer(Port) -> - Name = make_name(Addr,Port), - case whereis(Name) of - Pid when is_pid(Pid) -> - httpd_manager:get_status(Pid,Timeout); - _ -> - not_started - end. - do_reload_config(ConfigList, Mode) -> case (catch httpd_conf:validate_properties(ConfigList)) of {ok, Config} -> @@ -438,85 +301,6 @@ do_reload_config(ConfigList, Mode) -> Error end. - %%%-------------------------------------------------------------- %%% Deprecated %%%-------------------------------------------------------------- - -%% start() -> -%% start("/var/tmp/server_root/conf/8888.conf"). - -%% start(ConfigFile) -> -%% {ok, Pid} = inets:start(httpd, ConfigFile, stand_alone), -%% unlink(Pid), -%% {ok, Pid}. - -%% start_link() -> -%% start("/var/tmp/server_root/conf/8888.conf"). - -%% start_link(ConfigFile) when is_list(ConfigFile) -> -%% inets:start(httpd, ConfigFile, stand_alone). - -%% stop() -> -%% stop(8888). - -%% stop(Port) when is_integer(Port) -> -%% stop(undefined, Port); -%% stop(Pid) when is_pid(Pid) -> -%% old_stop(Pid); -%% stop(ConfigFile) when is_list(ConfigFile) -> -%% old_stop(ConfigFile). - -%% stop(Addr, Port) when is_integer(Port) -> -%% old_stop(Addr, Port). - -%% start_child() -> -%% start_child("/var/tmp/server_root/conf/8888.conf"). - -%% start_child(ConfigFile) -> -%% httpd_sup:start_child(ConfigFile). - -%% stop_child() -> -%% stop_child(8888). - -%% stop_child(Port) -> -%% stop_child(undefined, Port). - -%% stop_child(Addr, Port) when is_integer(Port) -> -%% httpd_sup:stop_child(Addr, Port). - -%% restart() -> reload(undefined, 8888). - -%% restart(Port) when is_integer(Port) -> -%% reload(undefined, Port). -%% restart(Addr, Port) -> -%% reload(Addr, Port). - -%% old_stop(Pid) when is_pid(Pid) -> -%% do_stop(Pid); -%% old_stop(ConfigFile) when is_list(ConfigFile) -> -%% case get_addr_and_port(ConfigFile) of -%% {ok, Addr, Port} -> -%% old_stop(Addr, Port); - -%% Error -> -%% Error -%% end; -%% old_stop(_StartArgs) -> -%% ok. - -%% old_stop(Addr, Port) when is_integer(Port) -> -%% Name = old_make_name(Addr, Port), -%% case whereis(Name) of -%% Pid when is_pid(Pid) -> -%% do_stop(Pid), -%% ok; -%% _ -> -%% not_started -%% end. - -%% do_stop(Pid) -> -%% exit(Pid, shutdown). - -%% old_make_name(Addr,Port) -> -%% httpd_util:make_name("httpd_instance_sup",Addr,Port). diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl index 1bffcc1f12..e812bc76f5 100644 --- a/lib/inets/src/http_server/httpd_acceptor.erl +++ b/lib/inets/src/http_server/httpd_acceptor.erl @@ -21,13 +21,13 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). --include("inets_internal.hrl"). +%%-include("inets_internal.hrl"). %% Internal application API --export([start_link/6, start_link/7]). +-export([start_link/7, start_link/8]). %% Other exports (for spawn's etc.) --export([acceptor_init/7, acceptor_init/8, acceptor_loop/6]). +-export([acceptor_init/8, acceptor_init/9, acceptor_loop/8]). %% %% External API @@ -36,51 +36,52 @@ %% start_link start_link(Manager, SocketType, Addr, Port, IpFamily, ConfigDb, AcceptTimeout) -> - ?hdrd("start link", - [{manager, Manager}, - {socket_type, SocketType}, - {address, Addr}, - {port, Port}, - {timeout, AcceptTimeout}]), + %% ?hdrd("start link", + %% [{manager, Manager}, + %% {socket_type, SocketType}, + %% {address, Addr}, + %% {port, Port}, + %% {timeout, AcceptTimeout}]), Args = [self(), Manager, SocketType, Addr, Port, IpFamily, ConfigDb, AcceptTimeout], proc_lib:start_link(?MODULE, acceptor_init, Args). -start_link(Manager, SocketType, ListenSocket, IpFamily, ConfigDb, AcceptTimeout) -> - ?hdrd("start link", - [{manager, Manager}, - {socket_type, SocketType}, - {listen_socket, ListenSocket}, - {timeout, AcceptTimeout}]), - Args = [self(), Manager, SocketType, ListenSocket, IpFamily, +start_link(Manager, SocketType, Addr, Port, ListenSocket, IpFamily, ConfigDb, AcceptTimeout) -> + %% ?hdrd("start link", + %% [{manager, Manager}, + %% {socket_type, SocketType}, + %% {listen_socket, ListenSocket}, + %% {timeout, AcceptTimeout}]), + Args = [self(), Manager, SocketType, Addr, Port, ListenSocket, IpFamily, ConfigDb, AcceptTimeout], proc_lib:start_link(?MODULE, acceptor_init, Args). -acceptor_init(Parent, Manager, SocketType, {ListenOwner, ListenSocket}, IpFamily, +acceptor_init(Parent, Manager, SocketType, Addr, Port, {ListenOwner, ListenSocket}, IpFamily, ConfigDb, AcceptTimeout) -> - ?hdrd("acceptor init", - [{parent, Parent}, - {manager, Manager}, - {socket_type, SocketType}, - {listen_owner, ListenOwner}, - {listen_socket, ListenSocket}, - {timeout, AcceptTimeout}]), + %% ?hdrd("acceptor init", + %% [{parent, Parent}, + %% {manager, Manager}, + %% {socket_type, SocketType}, + %% {listen_owner, ListenOwner}, + %% {listen_socket, ListenSocket}, + %% {timeout, AcceptTimeout}]), link(ListenOwner), proc_lib:init_ack(Parent, {ok, self()}), - acceptor_loop(Manager, SocketType, ListenSocket, IpFamily, ConfigDb, AcceptTimeout). + acceptor_loop(Manager, SocketType, Addr, Port, + ListenSocket, IpFamily, ConfigDb, AcceptTimeout). acceptor_init(Parent, Manager, SocketType, Addr, Port, IpFamily, ConfigDb, AcceptTimeout) -> - ?hdrd("acceptor init", - [{parent, Parent}, - {manager, Manager}, - {socket_type, SocketType}, - {address, Addr}, - {port, Port}, - {timeout, AcceptTimeout}]), + %% ?hdrd("acceptor init", + %% [{parent, Parent}, + %% {manager, Manager}, + %% {socket_type, SocketType}, + %% {address, Addr}, + %% {port, Port}, + %% {timeout, AcceptTimeout}]), case (catch do_init(SocketType, Addr, Port, IpFamily)) of {ok, ListenSocket} -> proc_lib:init_ack(Parent, {ok, self()}), - acceptor_loop(Manager, SocketType, + acceptor_loop(Manager, SocketType, Addr, Port, ListenSocket, IpFamily,ConfigDb, AcceptTimeout); Error -> proc_lib:init_ack(Parent, Error), @@ -88,67 +89,68 @@ acceptor_init(Parent, Manager, SocketType, Addr, Port, IpFamily, end. do_init(SocketType, Addr, Port, IpFamily) -> - ?hdrt("do init", []), + %% ?hdrt("do init", []), do_socket_start(SocketType), ListenSocket = do_socket_listen(SocketType, Addr, Port, IpFamily), {ok, ListenSocket}. do_socket_start(SocketType) -> - ?hdrt("do socket start", []), + %% ?hdrt("do socket start", []), case http_transport:start(SocketType) of ok -> ok; {error, Reason} -> - ?hdrv("failed starting transport", [{reason, Reason}]), + %% ?hdrv("failed starting transport", [{reason, Reason}]), throw({error, {socket_start_failed, Reason}}) end. do_socket_listen(SocketType, Addr, Port, IpFamily) -> - ?hdrt("do socket listen", []), + %% ?hdrt("do socket listen", []), case http_transport:listen(SocketType, Addr, Port, IpFamily) of {ok, ListenSocket} -> ListenSocket; {error, Reason} -> - ?hdrv("listen failed", [{reason, Reason}, - {socket_type, SocketType}, - {addr, Addr}, - {port, Port}]), + %% ?hdrv("listen failed", [{reason, Reason}, + %% {socket_type, SocketType}, + %% {addr, Addr}, + %% {port, Port}]), throw({error, {listen, Reason}}) end. %% acceptor -acceptor_loop(Manager, SocketType, ListenSocket, IpFamily, ConfigDb, AcceptTimeout) -> - ?hdrd("awaiting accept", - [{manager, Manager}, - {socket_type, SocketType}, - {listen_socket, ListenSocket}, - {timeout, AcceptTimeout}]), +acceptor_loop(Manager, SocketType, Addr, Port, ListenSocket, IpFamily, ConfigDb, AcceptTimeout) -> + %% ?hdrd("awaiting accept", + %% [{manager, Manager}, + %% {socket_type, SocketType}, + %% {listen_socket, ListenSocket}, + %% {timeout, AcceptTimeout}]), case (catch http_transport:accept(SocketType, ListenSocket, 50000)) of {ok, Socket} -> - ?hdrv("accepted", [{socket, Socket}]), - handle_connection(Manager, ConfigDb, AcceptTimeout, + %% ?hdrv("accepted", [{socket, Socket}]), + handle_connection(Addr, Port, Manager, ConfigDb, AcceptTimeout, SocketType, Socket), - ?MODULE:acceptor_loop(Manager, SocketType, + ?MODULE:acceptor_loop(Manager, SocketType, Addr, Port, ListenSocket, IpFamily, ConfigDb,AcceptTimeout); {error, Reason} -> - ?hdri("accept failed", [{reason, Reason}]), + %% ?hdri("accept failed", [{reason, Reason}]), handle_error(Reason, ConfigDb), - ?MODULE:acceptor_loop(Manager, SocketType, ListenSocket, + ?MODULE:acceptor_loop(Manager, SocketType, Addr, Port, ListenSocket, IpFamily, ConfigDb, AcceptTimeout); {'EXIT', Reason} -> - ?hdri("accept exited", [{reason, Reason}]), + %% ?hdri("accept exited", [{reason, Reason}]), ReasonString = lists:flatten(io_lib:format("Accept exit: ~p", [Reason])), accept_failed(ConfigDb, ReasonString) end. -handle_connection(Manager, ConfigDb, AcceptTimeout, SocketType, Socket) -> - {ok, Pid} = httpd_request_handler:start(Manager, ConfigDb, AcceptTimeout), +handle_connection(Address, Port, Manager, ConfigDb, AcceptTimeout, SocketType, Socket) -> + Sup = httpd_connection_sup:connection_sup(Address, Port), + {ok, Pid} = httpd_connection_sup:start_child(Sup, [Manager, ConfigDb, AcceptTimeout]), http_transport:controlling_process(SocketType, Socket, Pid), httpd_request_handler:socket_ownership_transfered(Pid, SocketType, Socket). diff --git a/lib/inets/src/http_server/httpd_acceptor_sup.erl b/lib/inets/src/http_server/httpd_acceptor_sup.erl index df837b5a24..cc2b582b52 100644 --- a/lib/inets/src/http_server/httpd_acceptor_sup.erl +++ b/lib/inets/src/http_server/httpd_acceptor_sup.erl @@ -27,7 +27,8 @@ -behaviour(supervisor). %% API --export([start_link/2, start_acceptor/6, start_acceptor/7, stop_acceptor/2]). +-export([start_link/1]). +%%, start_acceptor/6, start_acceptor/7, stop_acceptor/2]). %% Supervisor callback -export([init/1]). @@ -35,63 +36,48 @@ %%%========================================================================= %%% API %%%========================================================================= -start_link(Addr, Port) -> +start_link([Addr, Port| _] = Args) -> SupName = make_name(Addr, Port), - supervisor:start_link({local, SupName}, ?MODULE, []). - -%%---------------------------------------------------------------------- -%% Function: [start|stop]_acceptor/5 -%% Description: Starts/stops an [auth | security] worker (child) process -%%---------------------------------------------------------------------- -start_acceptor(SocketType, Addr, Port, IpFamily, ConfigDb, AcceptTimeout) -> - start_worker(httpd_acceptor, SocketType, Addr, Port, IpFamily, - ConfigDb, AcceptTimeout, self(), []). -start_acceptor(SocketType, Addr, Port, IpFamily, ConfigDb, AcceptTimeout, ListenSocket) -> - start_worker(httpd_acceptor, SocketType, Addr, Port, IpFamily, - ConfigDb, AcceptTimeout, ListenSocket, self(), []). - - -stop_acceptor(Addr, Port) -> - stop_worker(httpd_acceptor, Addr, Port). + supervisor:start_link({local, SupName}, ?MODULE, [Args]). %%%========================================================================= %%% Supervisor callback %%%========================================================================= -init(_) -> - Flags = {one_for_one, 500, 100}, - Workers = [], - {ok, {Flags, Workers}}. +init([Args]) -> + RestartStrategy = one_for_one, + MaxR = 10, + MaxT = 3600, + Children = [child_spec(Args)], + {ok, {{RestartStrategy, MaxR, MaxT}, Children}}. %%%========================================================================= %%% Internal functions %%%========================================================================= +child_spec([Address, Port, ConfigList, AcceptTimeout, ListenInfo]) -> + Name = id(Address, Port), + Manager = httpd_util:make_name("httpd", Address, Port), + SockType = proplists:get_value(socket_type, ConfigList, ip_comm), + IpFamily = proplists:get_value(ipfamily, ConfigList, inet), + StartFunc = case ListenInfo of + undefined -> + {httpd_acceptor, start_link, [Manager, SockType, Address, Port, IpFamily, + httpd_util:make_name("httpd_conf", Address, Port), + AcceptTimeout]}; + _ -> + {httpd_acceptor, start_link, [Manager, SockType, Address, Port, ListenInfo, + IpFamily, + httpd_util:make_name("httpd_conf", Address, Port), + AcceptTimeout]} + end, + Restart = transient, + Shutdown = brutal_kill, + Modules = [httpd_acceptor], + Type = worker, + {Name, StartFunc, Restart, Shutdown, Type, Modules}. -make_name(Addr,Port) -> - httpd_util:make_name("httpd_acc_sup", Addr, Port). +id(Address, Port) -> + {httpd_acceptor_sup, Address, Port}. -start_worker(M, SocketType, Addr, Port, IpFamily, ConfigDB, AcceptTimeout, Manager, Modules) -> - SupName = make_name(Addr, Port), - Args = [Manager, SocketType, Addr, Port, IpFamily, ConfigDB, AcceptTimeout], - Spec = {{M, Addr, Port}, - {M, start_link, Args}, - permanent, timer:seconds(1), worker, [M] ++ Modules}, - supervisor:start_child(SupName, Spec). - -start_worker(M, SocketType, Addr, Port, IpFamily, ConfigDB, AcceptTimeout, ListenSocket, - Manager, Modules) -> - SupName = make_name(Addr, Port), - Args = [Manager, SocketType, ListenSocket, IpFamily, ConfigDB, AcceptTimeout], - Spec = {{M, Addr, Port}, - {M, start_link, Args}, - permanent, timer:seconds(1), worker, [M] ++ Modules}, - supervisor:start_child(SupName, Spec). +make_name(Addr,Port) -> + httpd_util:make_name("httpd_acceptor_sup", Addr, Port). -stop_worker(M, Addr, Port) -> - SupName = make_name(Addr, Port), - Name = {M, Addr, Port}, - case supervisor:terminate_child(SupName, Name) of - ok -> - supervisor:delete_child(SupName, Name); - Error -> - Error - end. diff --git a/lib/inets/src/http_server/httpd_connection_sup.erl b/lib/inets/src/http_server/httpd_connection_sup.erl new file mode 100644 index 0000000000..48c2d8f076 --- /dev/null +++ b/lib/inets/src/http_server/httpd_connection_sup.erl @@ -0,0 +1,68 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2014. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose: Ssh connection supervisor. +%%---------------------------------------------------------------------- + +-module(httpd_connection_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/1]). +-export([start_child/2, connection_sup/2]). + +%% Supervisor callback +-export([init/1]). + +%%%========================================================================= +%%% API +%%%========================================================================= +start_link(Args) -> + supervisor:start_link(?MODULE, [Args]). + +start_child(Sup, Args) -> + supervisor:start_child(Sup, Args). + +connection_sup(Addr, Port) -> + httpd_util:make_name("httpd_connection_sup", Addr, Port). + +%%%========================================================================= +%%% Supervisor callback +%%%========================================================================= +init([[Addr, Port]]) -> + RegName = connection_sup(Addr, Port), + register(RegName, self()), + RestartStrategy = simple_one_for_one, + MaxR = 0, + MaxT = 3600, + + Name = undefined, % As simple_one_for_one is used. + StartFunc = {httpd_request_handler, start_link, []}, + Restart = temporary, % E.g. should not be restarted + Shutdown = 4000, + Modules = [httpd_request_handler], + Type = worker, + + ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules}, + {ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}. + + + diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl index baa60d318c..b95be44b2a 100644 --- a/lib/inets/src/http_server/httpd_instance_sup.erl +++ b/lib/inets/src/http_server/httpd_instance_sup.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% Copyright Ericsson AB 2001-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -100,7 +100,9 @@ start_link(ConfigFile, AcceptTimeout, ListenInfo, Debug) -> init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port]) -> httpd_util:enable_debug(Debug), Flags = {one_for_one, 0, 1}, - Children = [sup_spec(httpd_acceptor_sup, Address, Port), + Children = [httpd_connection_sup_spec(Address, Port), + httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout, + undefined), sup_spec(httpd_misc_sup, Address, Port), worker_spec(httpd_manager, Address, Port, ConfigFile, ConfigList,AcceptTimeout)], @@ -108,7 +110,9 @@ init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port]) -> init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port, ListenInfo]) -> httpd_util:enable_debug(Debug), Flags = {one_for_one, 0, 1}, - Children = [sup_spec(httpd_acceptor_sup, Address, Port), + Children = [httpd_connection_sup_spec(Address, Port), + httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout, + ListenInfo), sup_spec(httpd_misc_sup, Address, Port), worker_spec(httpd_manager, Address, Port, ListenInfo, ConfigFile, ConfigList, AcceptTimeout)], @@ -118,6 +122,24 @@ init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port, ListenInfo]) %%%========================================================================= %%% Internal functions %%%========================================================================= +httpd_connection_sup_spec(Address, Port) -> + Name = {httpd_connection_sup, Address, Port}, + StartFunc = {httpd_connection_sup, start_link, [[Address, Port]]}, + Restart = permanent, + Shutdown = 5000, + Modules = [httpd_connection_sup], + Type = supervisor, + {Name, StartFunc, Restart, Shutdown, Type, Modules}. + +httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout, ListenInfo) -> + Name = {httpd_acceptor_sup, Address, Port}, + StartFunc = {httpd_acceptor_sup, start_link, [[Address, Port, ConfigList, AcceptTimeout, ListenInfo]]}, + Restart = permanent, + Shutdown = infinity, + Modules = [httpd_acceptor_sup], + Type = supervisor, + {Name, StartFunc, Restart, Shutdown, Type, Modules}. + sup_spec(SupModule, Address, Port) -> Name = {SupModule, Address, Port}, StartFunc = {SupModule, start_link, [Address, Port]}, @@ -167,5 +189,3 @@ file_2_config(ConfigFile) -> Error -> Error end. - - diff --git a/lib/inets/src/http_server/httpd_manager.erl b/lib/inets/src/http_server/httpd_manager.erl index 00384fa108..e155498bb8 100644 --- a/lib/inets/src/http_server/httpd_manager.erl +++ b/lib/inets/src/http_server/httpd_manager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2013. All Rights Reserved. +%% Copyright Ericsson AB 2000-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -25,11 +25,11 @@ -behaviour(gen_server). %% Application internal API --export([start/2, start_link/2, start_link/3, start_link/4, stop/1, reload/2]). --export([new_connection/1, done_connection/1]). --export([config_lookup/2, config_lookup/3, - config_multi_lookup/2, config_multi_lookup/3, - config_match/2, config_match/3]). +-export([start/2, start_link/2, start_link/3, start_link/4, + stop/1, reload/2]). +-export([new_connection/1]). +-export([config_match/2, config_match/3]). +-export([block/2, block/3, unblock/1]). %% gen_server exports -export([init/1, @@ -37,34 +37,19 @@ terminate/2, code_change/3]). - -%% Management exports --export([block/2, block/3, unblock/1]). --export([get_admin_state/1, get_usage_state/1]). --export([is_busy/1,is_busy/2,is_busy_or_blocked/1,is_blocked/1]). %% ??????? --export([get_status/1, get_status/2]). - --export([c/1]). - -record(state,{socket_type = ip_comm, config_file, config_db = null, - connections, %% Current request handlers + connection_sup, admin_state = unblocked, blocker_ref = undefined, - blocking_tmr = undefined, + blocking_from = undefined, + shutdown_poller = undefined, status = []}). +%%%-------------------------------------------------------------------- +%%% Application internal API +%%%-------------------------------------------------------------------- - -%%TODO: Clean up this module! - -c(Port) -> - Ref = httpd_util:make_name("httpd",undefined,Port), - call(Ref, fake_close). - -%% -%% External API -%% %% Deprecated start(ConfigFile, ConfigList) -> Port = proplists:get_value(port,ConfigList,80), @@ -83,7 +68,8 @@ start_link(ConfigFile, ConfigList, AcceptTimeout) -> Name = make_name(Addr, Port), gen_server:start_link({local, Name},?MODULE, - [ConfigFile, ConfigList, AcceptTimeout, Addr, Port],[]). + [ConfigFile, ConfigList, + AcceptTimeout, Addr, Port],[]). start_link(ConfigFile, ConfigList, AcceptTimeout, ListenSocket) -> Port = proplists:get_value(port, ConfigList, 80), @@ -93,146 +79,33 @@ start_link(ConfigFile, ConfigList, AcceptTimeout, ListenSocket) -> gen_server:start_link({local, Name},?MODULE, [ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenSocket],[]). - stop(ServerRef) -> call(ServerRef, stop). reload(ServerRef, Conf) -> call(ServerRef, {reload, Conf}). - -%%%---------------------------------------------------------------- - -block(ServerRef, disturbing) -> - call(ServerRef,block); - -block(ServerRef, non_disturbing) -> - do_block(ServerRef, non_disturbing, infinity). +block(ServerRef, Method) -> + block(ServerRef, Method, infinity). block(ServerRef, Method, Timeout) -> - do_block(ServerRef, Method, Timeout). - - -%% The reason for not using call here, is that the manager cannot -%% _wait_ for completion of the requests. It must be able to do -%% do other things at the same time as the blocking goes on. -do_block(ServerRef, Method, infinity) -> - Ref = make_ref(), - cast(ServerRef, {block, Method, infinity, self(), Ref}), - receive - {block_reply, Reply, Ref} -> - Reply - end; -do_block(ServerRef,Method,Timeout) when Timeout > 0 -> - Ref = make_ref(), - cast(ServerRef,{block,Method,Timeout,self(),Ref}), - receive - {block_reply,Reply,Ref} -> - Reply - end. - - -%%%---------------------------------------------------------------- - -%% unblock + call(ServerRef, {block, self(), Method, Timeout}). unblock(ServerRef) -> - call(ServerRef,unblock). - -%% get admin/usage state - -get_admin_state(ServerRef) -> - call(ServerRef,get_admin_state). - -get_usage_state(ServerRef) -> - call(ServerRef,get_usage_state). - - -%% get_status - -get_status(ServerRef) -> - gen_server:call(ServerRef,get_status). - -get_status(ServerRef,Timeout) -> - gen_server:call(ServerRef,get_status,Timeout). - -%% -%% Internal API -%% - - -%% new_connection + call(ServerRef,{unblock, self()}). new_connection(Manager) -> - gen_server:call(Manager, {new_connection, self()}, infinity). - -%% done - -done_connection(Manager) -> - gen_server:cast(Manager, {done_connection, self()}). - - -%% is_busy(ServerRef) -> true | false -%% -%% Tests if the server is (in usage state) busy, -%% i.e. has rached the heavy load limit. -%% - -is_busy(ServerRef) -> - gen_server:call(ServerRef,is_busy). - -is_busy(ServerRef,Timeout) -> - gen_server:call(ServerRef,is_busy,Timeout). - - -%% is_busy_or_blocked(ServerRef) -> busy | blocked | false -%% -%% Tests if the server is busy (usage state), i.e. has rached, -%% the heavy load limit, or blocked (admin state) . -%% - -is_busy_or_blocked(ServerRef) -> - gen_server:call(ServerRef,is_busy_or_blocked). - - -%% is_blocked(ServerRef) -> true | false -%% -%% Tests if the server is blocked (admin state) . -%% - -is_blocked(ServerRef) -> - gen_server:call(ServerRef,is_blocked). - - -%% -%% Module API. Theese functions are intended for use from modules only. -%% - -config_lookup(Port, Query) -> - config_lookup(undefined, Port, Query). -config_lookup(Addr, Port, Query) -> - Name = httpd_util:make_name("httpd",Addr,Port), - gen_server:call(whereis(Name), {config_lookup, Query}). - -config_multi_lookup(Port, Query) -> - config_multi_lookup(undefined,Port,Query). -config_multi_lookup(Addr,Port, Query) -> - Name = httpd_util:make_name("httpd",Addr,Port), - gen_server:call(whereis(Name), {config_multi_lookup, Query}). + call(Manager, {new_connection, self()}). config_match(Port, Pattern) -> config_match(undefined,Port,Pattern). config_match(Addr, Port, Pattern) -> Name = httpd_util:make_name("httpd",Addr,Port), - gen_server:call(whereis(Name), {config_match, Pattern}). - - -%% -%% Server call-back functions -%% - -%% init + call(whereis(Name), {config_match, Pattern}). +%%%-------------------------------------------------------------------- +%%% gen_server callbacks functions +%%%-------------------------------------------------------------------- init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port]) -> process_flag(trap_exit, true), case (catch do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port)) of @@ -263,47 +136,35 @@ init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenInfo]) -> {ok, State} end. -do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port) -> - IpFamily = proplists:get_value(ipfamily, ConfigList, inet6fb4), +do_init(ConfigFile, ConfigList, _AcceptTimeout, Addr, Port) -> + Sup = httpd_util:make_name("httpd_connection_sup", Addr, Port), NewConfigFile = proplists:get_value(file, ConfigList, ConfigFile), ConfigDB = do_initial_store(ConfigList), SocketType = httpd_conf:lookup_socket_type(ConfigDB), - case httpd_acceptor_sup:start_acceptor(SocketType, Addr, - Port, IpFamily, ConfigDB, AcceptTimeout) of - {ok, _Pid} -> - Status = [{max_conn, 0}, - {last_heavy_load, never}, - {last_connection, never}], + Status = [{max_conn, 0}, + {last_heavy_load, never}, + {last_connection, never}], State = #state{socket_type = SocketType, config_file = NewConfigFile, config_db = ConfigDB, - connections = [], + connection_sup = Sup, status = Status}, - {ok, State}; - Else -> - Else - end. + {ok, State}. -do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenInfo) -> - IpFamily = proplists:get_value(ipfamily, ConfigList, inet6fb4), +do_init(ConfigFile, ConfigList, _AcceptTimeout, Addr, Port, _ListenInfo) -> + Sup = httpd_util:make_name("httpd_connection_sup", Addr, Port), NewConfigFile = proplists:get_value(file, ConfigList, ConfigFile), ConfigDB = do_initial_store(ConfigList), SocketType = httpd_conf:lookup_socket_type(ConfigDB), - case httpd_acceptor_sup:start_acceptor(SocketType, Addr, - Port, IpFamily, ConfigDB, - AcceptTimeout, ListenInfo) of - {ok, _Pid} -> - Status = [{max_conn,0}, {last_heavy_load,never}, - {last_connection,never}], + Status = [{max_conn,0}, {last_heavy_load,never}, + {last_connection,never}], State = #state{socket_type = SocketType, config_file = NewConfigFile, config_db = ConfigDB, - connections = [], + connection_sup = Sup, status = Status}, - {ok, State}; - Else -> - Else - end. + {ok, State}. + do_initial_store(ConfigList) -> case httpd_conf:store(ConfigList) of @@ -313,75 +174,14 @@ do_initial_store(ConfigList) -> throw({error, Reason}) end. - - -%% handle_call - handle_call(stop, _From, State) -> {stop, normal, ok, State}; -handle_call({config_lookup, Query}, _From, State) -> - Res = httpd_util:lookup(State#state.config_db, Query), - {reply, Res, State}; - -handle_call({config_multi_lookup, Query}, _From, State) -> - Res = httpd_util:multi_lookup(State#state.config_db, Query), - {reply, Res, State}; - handle_call({config_match, Query}, _From, State) -> Res = ets:match_object(State#state.config_db, Query), {reply, Res, State}; -handle_call(get_status, _From, State) -> - ManagerStatus = manager_status(self()), - S1 = [{current_conn,length(State#state.connections)}|State#state.status]++ - [ManagerStatus], - {reply,S1,State}; - -handle_call(is_busy, _From, State) -> - Reply = case get_ustate(State) of - busy -> - true; - _ -> - false - end, - {reply,Reply,State}; - -handle_call(is_busy_or_blocked, _From, State) -> - Reply = - case get_astate(State) of - unblocked -> - case get_ustate(State) of - busy -> - busy; - _ -> - false - end; - _ -> - blocked - end, - {reply,Reply,State}; - -handle_call(is_blocked, _From, State) -> - Reply = - case get_astate(State) of - unblocked -> - false; - _ -> - true - end, - {reply,Reply,State}; - -handle_call(get_admin_state, _From, State) -> - Reply = get_astate(State), - {reply,Reply,State}; - -handle_call(get_usage_state, _From, State) -> - Reply = get_ustate(State), - {reply,Reply,State}; - -handle_call({reload, Conf}, _From, State) - when State#state.admin_state =:= blocked -> +handle_call({reload, Conf}, _From, #state{admin_state = blocked} = State) -> case handle_reload(Conf, State) of {stop, Reply,S1} -> {stop, Reply, S1}; @@ -392,13 +192,32 @@ handle_call({reload, Conf}, _From, State) handle_call({reload, _}, _From, State) -> {reply,{error,{invalid_admin_state,State#state.admin_state}},State}; -handle_call(block, _From, State) -> - {Reply,S1} = handle_block(State), - {reply,Reply,S1}; +handle_call({block , Blocker, Mode, Timeout}, From, + #state{admin_state = unblocked, + connection_sup = CSup} = State) -> + Monitor = erlang:monitor(process, Blocker), + case count_children(CSup) of + 0 -> + %% Already in idle usage state => go directly to blocked + {reply, ok, State#state{admin_state = blocked, + blocker_ref = {Blocker, Monitor}, + blocking_from = From}}; + _ -> + handle_block(Mode, Timeout, + State#state{blocker_ref = {Blocker, Monitor}, + blocking_from = From}) + end; +handle_call({block , _, _, _}, _, State) -> + {reply, {error, blocked}, State}; + +handle_call({unblock, Blocker}, _, #state{blocker_ref = {Blocker,_}, + admin_state = blocked} = State) -> + + {reply, ok, + State#state{admin_state = unblocked, blocker_ref = undefined}}; -handle_call(unblock, {From,_Tag}, State) -> - {Reply,S1} = handle_unblock(State,From), - {reply, Reply, S1}; +handle_call({unblock, _}, _, State) -> + {reply, {error, only_blocker_may_unblock}, State}; handle_call({new_connection, Pid}, _From, State) -> {Status, NewState} = handle_new_connection(State, Pid), @@ -415,21 +234,6 @@ handle_call(Request, From, State) -> report_error(State,String), {reply, ok, State}. - -%% handle_cast - -handle_cast({done_connection, Pid}, State) -> - S1 = handle_done_connection(State, Pid), - {noreply, S1}; - -handle_cast({block, disturbing, Timeout, From, Ref}, State) -> - S1 = handle_block(State, Timeout, From, Ref), - {noreply,S1}; - -handle_cast({block, non_disturbing, Timeout, From, Ref}, State) -> - S1 = handle_nd_block(State, Timeout, From, Ref), - {noreply,S1}; - handle_cast(Message, State) -> String = lists:flatten( @@ -440,32 +244,51 @@ handle_cast(Message, State) -> report_error(State, String), {noreply, State}. -%% handle_info - -handle_info({block_timeout, Method}, State) -> - S1 = handle_block_timeout(State,Method), - {noreply, S1}; +handle_info(connections_terminated, #state{admin_state = shutting_down, + blocking_from = From} = State) -> + gen_server:reply(From, ok), + {noreply, State#state{admin_state = blocked, blocking_from = undefined, + blocker_ref = undefined}}; +handle_info(connections_terminated, State) -> + {noreply, State}; -handle_info({'DOWN', Ref, process, _Object, _Info}, State) -> - S1 = - case State#state.blocker_ref of - Ref -> - handle_blocker_exit(State); - _ -> - %% Not our blocker, so ignore - State - end, - {noreply, S1}; +handle_info({block_timeout, non_disturbing}, + #state{admin_state = shutting_down, + blocking_from = From, + blocker_ref = {_, Monitor}} = State) -> + erlang:demonitor(Monitor), + gen_server:reply(From, {error, timeout}), + {noreply, State#state{admin_state = unblocked, blocking_from = undefined, + blocker_ref = undefined}}; +handle_info({block_timeout, disturbing}, + #state{admin_state = shutting_down, + blocking_from = From, + blocker_ref = {_, Monitor}, + connection_sup = Sup} = State) -> + SupPid = whereis(Sup), + shutdown_connections(SupPid), + erlang:demonitor(Monitor), + gen_server:reply(From, ok), + {noreply, State#state{admin_state = blocked, blocker_ref = undefined, + blocking_from = undefined}}; +handle_info({block_timeout, _, _}, State) -> + {noreply, State}; + +handle_info({'DOWN', _, process, Pid, _Info}, + #state{admin_state = Admin, + blocker_ref = {Pid, _}} = State) when + Admin =/= unblocked -> + {noreply, State#state{admin_state = unblocked, + blocking_from = undefined, + blocker_ref = undefined}}; +handle_info({'DOWN', _, process, _, _}, State) -> + {noreply, State}; handle_info({'EXIT', _, normal}, State) -> {noreply, State}; -handle_info({'EXIT', _, blocked}, S) -> - {noreply, S}; - -handle_info({'EXIT', Pid, Reason}, State) -> - S1 = check_connections(State, Pid, Reason), - {noreply, S1}; +handle_info({'EXIT', _, shutdown}, State) -> + {stop, shutdown, State}; handle_info(Info, State) -> String = @@ -477,217 +300,66 @@ handle_info(Info, State) -> report_error(State, String), {noreply, State}. - -%% terminate - terminate(_, #state{config_db = Db}) -> httpd_conf:remove_all(Db), ok. - -%% code_change({down,ToVsn}, State, Extra) -%% - code_change({down,_ToVsn}, State, _Extra) -> {ok,State}; -%% code_change(FromVsn, State, Extra) -%% code_change(_FromVsn, State, _Extra) -> {ok,State}. - - -%% ------------------------------------------------------------------------- -%% check_connection -%% -%% -%% -%% - -check_connections(#state{connections = []} = State, _Pid, _Reason) -> - State; -check_connections(#state{connections = Connections} = State, Pid, _Reason) -> - State#state{connections = lists:delete(Pid, Connections)}. - - -%% ------------------------------------------------------------------------- -%% handle_[new | done]_connection -%% -%% -%% -%% - -handle_new_connection(State, Handler) -> +%%%-------------------------------------------------------------------- +%%% Internal functions +%%%-------------------------------------------------------------------- +handle_new_connection(#state{admin_state = AdminState} = State, Handler) -> UsageState = get_ustate(State), - AdminState = get_astate(State), handle_new_connection(UsageState, AdminState, State, Handler). -handle_new_connection(busy, unblocked, State, _Handler) -> - Status = update_heavy_load_status(State#state.status), - {{reject, busy}, - State#state{status = Status}}; - -handle_new_connection(_UsageState, unblocked, State, Handler) -> - Connections = State#state.connections, - Status = update_connection_status(State#state.status, - length(Connections)+1), - link(Handler), - {{ok, accept}, - State#state{connections = [Handler|Connections], status = Status}}; - -handle_new_connection(_UsageState, _AdminState, State, _Handler) -> - {{reject, blocked}, - State}. - -handle_done_connection(#state{admin_state = shutting_down, - connections = Connections} = State, Handler) -> - unlink(Handler), - case lists:delete(Handler, Connections) of - [] -> % Ok, block complete - demonitor_blocker(State#state.blocker_ref), - {Tmr,From,Ref} = State#state.blocking_tmr, - stop_block_tmr(Tmr), - From ! {block_reply,ok,Ref}, - State#state{admin_state = blocked, connections = [], - blocker_ref = undefined}; - Connections1 -> - State#state{connections = Connections1} - end; - -handle_done_connection(#state{connections = Connections} = State, Handler) -> - State#state{connections = lists:delete(Handler, Connections)}. - - -%% ------------------------------------------------------------------------- -%% handle_block -%% -%% -%% -%% -handle_block(#state{admin_state = AdminState} = S) -> - handle_block(S, AdminState). - -handle_block(S,unblocked) -> - %% Kill all connections - [kill_handler(Pid) || Pid <- S#state.connections], - {ok,S#state{connections = [], admin_state = blocked}}; -handle_block(S,blocked) -> - {ok,S}; -handle_block(S,shutting_down) -> - {{error,shutting_down},S}. - - -kill_handler(Pid) -> - exit(Pid, blocked). - -handle_block(S,Timeout,From,Ref) when Timeout >= 0 -> - do_block(S,Timeout,From,Ref); - -handle_block(S,Timeout,From,Ref) -> - Reply = {error,{invalid_block_request,Timeout}}, - From ! {block_reply,Reply,Ref}, - S. - -do_block(S,Timeout,From,Ref) -> - case S#state.connections of - [] -> - %% Already in idle usage state => go directly to blocked - From ! {block_reply,ok,Ref}, - S#state{admin_state = blocked}; +handle_new_connection(_UsageState, unblocked, + #state{config_db = Db, connection_sup = CSup} = + State, _) -> + Max = httpd_util:lookup(Db, max_clients), + case count_children(CSup) of + Count when Count =< Max -> + {{ok, accept}, State}; _ -> - %% Active or Busy usage state => go to shutting_down - %% Make sure we get to know if blocker dies... - MonitorRef = monitor_blocker(From), - Tmr = {start_block_tmr(Timeout,disturbing),From,Ref}, - S#state{admin_state = shutting_down, - blocker_ref = MonitorRef, blocking_tmr = Tmr} - end. - -handle_nd_block(S,infinity,From,Ref) -> - do_nd_block(S,infinity,From,Ref); - -handle_nd_block(S,Timeout,From,Ref) when Timeout >= 0 -> - do_nd_block(S,Timeout,From,Ref); - -handle_nd_block(S,Timeout,From,Ref) -> - Reply = {error,{invalid_block_request,Timeout}}, - From ! {block_reply,Reply,Ref}, - S. - -do_nd_block(S,Timeout,From,Ref) -> - case S#state.connections of - [] -> - %% Already in idle usage state => go directly to blocked - From ! {block_reply,ok,Ref}, - S#state{admin_state = blocked}; - _ -> - %% Active or Busy usage state => go to shutting_down - %% Make sure we get to know if blocker dies... - MonitorRef = monitor_blocker(From), - Tmr = {start_block_tmr(Timeout,non_disturbing),From,Ref}, - S#state{admin_state = shutting_down, - blocker_ref = MonitorRef, blocking_tmr = Tmr} - end. + {{reject, busy}, State} + end; -handle_block_timeout(S,Method) -> - %% Time to take this to the road... - demonitor_blocker(S#state.blocker_ref), - handle_block_timeout1(S,Method,S#state.blocking_tmr). - -handle_block_timeout1(S,non_disturbing,{_,From,Ref}) -> - From ! {block_reply,{error,timeout},Ref}, - S#state{admin_state = unblocked, - blocker_ref = undefined, blocking_tmr = undefined}; - -handle_block_timeout1(S,disturbing,{_,From,Ref}) -> - [exit(Pid,blocked) || Pid <- S#state.connections], - - From ! {block_reply,ok,Ref}, - S#state{admin_state = blocked, connections = [], - blocker_ref = undefined, blocking_tmr = undefined}; - -handle_block_timeout1(S,Method,{_,From,Ref}) -> - From ! {block_reply,{error,{unknown_block_method,Method}},Ref}, - S#state{admin_state = blocked, connections = [], - blocker_ref = undefined, blocking_tmr = undefined}; - -handle_block_timeout1(S, _Method, _TmrInfo) -> - S#state{admin_state = unblocked, - blocker_ref = undefined, blocking_tmr = undefined}. - -handle_unblock(S, FromA) -> - handle_unblock(S, FromA, S#state.admin_state). - -handle_unblock(S, _FromA, unblocked) -> - {ok,S}; -handle_unblock(S, FromA, _AdminState) -> - case S#state.blocking_tmr of - {Tmr,FromB,Ref} -> - %% Another process is trying to unblock - %% Inform the blocker - stop_block_tmr(Tmr), - FromB ! {block_reply, {error,{unblocked,FromA}},Ref}; - _ -> - ok - end, - {ok,S#state{admin_state = unblocked, blocking_tmr = undefined}}. - -%% The blocker died so we give up on the block. -handle_blocker_exit(S) -> - {Tmr,_From,_Ref} = S#state.blocking_tmr, - stop_block_tmr(Tmr), - S#state{admin_state = unblocked, - blocker_ref = undefined, blocking_tmr = undefined}. +handle_new_connection(_UsageState, _AdminState, State, _Handler) -> + {{reject, blocked}, State}. + +handle_block(disturbing, infinity, + #state{connection_sup = CSup, + blocking_from = From, + blocker_ref = {_, Monitor}} = State) -> + SupPid = whereis(CSup), + shutdown_connections(SupPid), + erlang:demonitor(Monitor), + gen_server:reply(From, ok), + {noreply, State#state{admin_state = blocked, blocker_ref = undefined, + blocking_from = undefined}}; +handle_block(disturbing, Timeout, #state{connection_sup = CSup} = State) -> + Manager = self(), + spawn_link(fun() -> wait_for_shutdown(CSup, Manager) end), + erlang:send_after(Timeout, self(), {block_timeout, disturbing}), + {noreply, State#state{admin_state = shutting_down}}; + +handle_block(non_disturbing, infinity, + #state{connection_sup = CSup} = State) -> + Manager = self(), + spawn_link(fun() -> wait_for_shutdown(CSup, Manager) end), + {noreply, State#state{admin_state = shutting_down}}; + +handle_block(non_disturbing, Timeout, + #state{connection_sup = CSup} = State) -> + Manager = self(), + spawn_link(fun() -> wait_for_shutdown(CSup, Manager) end), + erlang:send_after(Timeout, self(), {block_timeout, non_disturbing}), + {noreply, State#state{admin_state = shutting_down}}. - - -%% ------------------------------------------------------------------------- -%% handle_reload -%% -%% -%% -%% handle_reload(undefined, #state{config_file = undefined} = State) -> {continue, {error, undefined_config_file}, State}; handle_reload(undefined, #state{config_file = ConfigFile} = State) -> @@ -763,7 +435,7 @@ check_constant_values(Db, Config) -> %% Otherwise -> active %% get_ustate(State) -> - get_ustate(length(State#state.connections),State). + get_ustate(count_children(State#state.connection_sup),State). get_ustate(0,_State) -> idle; @@ -776,76 +448,6 @@ get_ustate(ConnectionCnt,State) -> active end. - -get_astate(S) -> S#state.admin_state. - - -%% Timer handling functions -start_block_tmr(infinity,_) -> - undefined; -start_block_tmr(T,M) -> - erlang:send_after(T,self(),{block_timeout,M}). - -stop_block_tmr(undefined) -> - ok; -stop_block_tmr(Ref) -> - erlang:cancel_timer(Ref). - - -%% Monitor blocker functions -monitor_blocker(Pid) when is_pid(Pid) -> - case (catch erlang:monitor(process,Pid)) of - {'EXIT', _Reason} -> - undefined; - MonitorRef -> - MonitorRef - end; -monitor_blocker(_) -> - undefined. - -demonitor_blocker(undefined) -> - ok; -demonitor_blocker(Ref) -> - (catch erlang:demonitor(Ref)). - - -%% Some status utility functions - -update_heavy_load_status(Status) -> - update_status_with_time(Status,last_heavy_load). - -update_connection_status(Status,ConnCount) -> - S1 = case lists:keysearch(max_conn,1,Status) of - {value, {max_conn, C1}} when ConnCount > C1 -> - lists:keyreplace(max_conn,1,Status,{max_conn,ConnCount}); - {value, {max_conn, _C2}} -> - Status; - false -> - [{max_conn, ConnCount} | Status] - end, - update_status_with_time(S1,last_connection). - -update_status_with_time(Status,Key) -> - lists:keyreplace(Key,1,Status,{Key,universal_time()}). - -universal_time() -> calendar:universal_time(). - -manager_status(P) -> - Items = [status, message_queue_len, reductions, - heap_size, stack_size], - {manager_status, process_status(P,Items,[])}. - - -process_status(P,[],L) -> - [{pid,P}|lists:reverse(L)]; -process_status(P,[H|T],L) -> - case (catch process_info(P,H)) of - {H, Value} -> - process_status(P,T,[{H,Value}|L]); - _ -> - process_status(P,T,[{H,undefined}|L]) - end. - make_name(Addr,Port) -> httpd_util:make_name("httpd",Addr,Port). @@ -856,10 +458,31 @@ report_error(State,String) -> mod_log:report_error(Cdb,String), mod_disk_log:report_error(Cdb,String). -%% -call(ServerRef,Request) -> - gen_server:call(ServerRef,Request). +call(ServerRef, Request) -> + try gen_server:call(ServerRef, Request, infinity) + catch + exit:_ -> + {error, closed} + end. + +count_children(Sup) -> + Children = supervisor:count_children(whereis(Sup)), + proplists:get_value(workers, Children). -cast(ServerRef,Message) -> - gen_server:cast(ServerRef,Message). +shutdown_connections(Sup) -> + Children = [Child || {_,Child,_,_} <- supervisor:which_children(Sup)], + lists:foreach(fun(Pid) -> exit(Pid, kill) end, + Children). + +wait_for_shutdown(CSup, Manager) -> + case count_children(CSup) of + 0 -> + Manager ! connections_terminated; + _ -> + receive + after 500 -> + ok + end, + wait_for_shutdown(CSup, Manager) + end. diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index ea7a17e40d..bd37066ff6 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -25,7 +25,7 @@ -behaviour(gen_server). %% Application internal API --export([start/2, start/3, socket_ownership_transfered/3]). +-export([start_link/2, start_link/3, socket_ownership_transfered/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -57,10 +57,10 @@ %% Description: Starts a httpd-request handler process. Intended to be %% called by the httpd acceptor process. %%-------------------------------------------------------------------- -start(Manager, ConfigDB) -> - start(Manager, ConfigDB, 15000). -start(Manager, ConfigDB, AcceptTimeout) -> - proc_lib:start(?MODULE, init, [[Manager, ConfigDB,AcceptTimeout]]). +start_link(Manager, ConfigDB) -> + start_link(Manager, ConfigDB, 15000). +start_link(Manager, ConfigDB, AcceptTimeout) -> + proc_lib:start_link(?MODULE, init, [[Manager, ConfigDB,AcceptTimeout]]). %%-------------------------------------------------------------------- @@ -87,34 +87,27 @@ socket_ownership_transfered(Pid, SocketType, Socket) -> %% gen_server provides is needed. %%-------------------------------------------------------------------- init([Manager, ConfigDB, AcceptTimeout]) -> - ?hdrd("initiate", - [{manager, Manager}, {cdb, ConfigDB}, {timeout, AcceptTimeout}]), + process_flag(trap_exit, true), %% Make sure this process terminates if the httpd manager process %% should die! - link(Manager), + %%link(Manager), %% At this point the function httpd_request_handler:start/2 will return. proc_lib:init_ack({ok, self()}), {SocketType, Socket} = await_socket_ownership_transfer(AcceptTimeout), - ?hdrd("socket ownership transfered", - [{socket_type, SocketType}, {socket, Socket}]), - + TimeOut = httpd_util:lookup(ConfigDB, keep_alive_timeout, 150000), Then = erlang:now(), - ?hdrd("negotiate", []), case http_transport:negotiate(SocketType, Socket, TimeOut) of - {error, Error} -> - ?hdrd("negotiation failed", [{error, Error}]), + {error, _Error} -> exit(shutdown); %% Can be 'normal'. ok -> - ?hdrt("negotiation successfull", []), NewTimeout = TimeOut - timer:now_diff(now(),Then) div 1000, continue_init(Manager, ConfigDB, SocketType, Socket, NewTimeout) end. continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> - ?hdrt("continue init", [{timeout, TimeOut}]), Resolve = http_transport:resolve(), Peername = httpd_socket:peername(SocketType, Socket), @@ -139,14 +132,10 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> max_keep_alive_request = NrOfRequest, mfa = MFA}, - ?hdrt("activate request timeout", []), - - ?hdrt("set socket options (binary, packet & active)", []), http_transport:setopts(SocketType, Socket, [binary, {packet, 0}, {active, once}]), NewState = data_receive_counter(activate_request_timeout(State), httpd_util:lookup(ConfigDB, minimum_bytes_per_second, false)), - ?hdrt("init done", []), - gen_server:enter_loop(?MODULE, [], NewState). + gen_server:enter_loop(?MODULE, [], NewState). %%==================================================================== @@ -195,18 +184,13 @@ handle_cast(Msg, #state{mod = ModData} = State) -> %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({Proto, Socket, Data}, - #state{mfa = {Module, Function, Args} = MFA, + #state{mfa = {Module, Function, Args}, mod = #mod{socket_type = SockType, socket = Socket} = ModData} = State) when (((Proto =:= tcp) orelse (Proto =:= ssl) orelse (Proto =:= dummy)) andalso is_binary(Data)) -> - ?hdrd("received data", - [{data, Data}, {proto, Proto}, - {socket, Socket}, {socket_type, SockType}, {mfa, MFA}]), - -%% case (catch Module:Function([Data | Args])) of PROCESSED = (catch Module:Function([Data | Args])), NewDataSize = case State#state.byte_limit of undefined -> @@ -214,10 +198,8 @@ handle_info({Proto, Socket, Data}, _ -> State#state.data + byte_size(Data) end, - ?hdrt("data processed", [{processing_result, PROCESSED}]), case PROCESSED of {ok, Result} -> - ?hdrd("data processed", [{result, Result}]), NewState = case NewDataSize of undefined -> cancel_request_timeout(State); @@ -227,7 +209,6 @@ handle_info({Proto, Socket, Data}, handle_http_msg(Result, NewState); {error, {uri_too_long, MaxSize}, Version} -> - ?hdrv("uri too long", [{max_size, MaxSize}, {version, Version}]), NewModData = ModData#mod{http_version = Version}, httpd_response:send_status(NewModData, 414, "URI too long"), Reason = io_lib:format("Uri too long, max size is ~p~n", @@ -236,8 +217,6 @@ handle_info({Proto, Socket, Data}, {stop, normal, State#state{response_sent = true, mod = NewModData}}; {error, {header_too_long, MaxSize}, Version} -> - ?hdrv("header too long", - [{max_size, MaxSize}, {version, Version}]), NewModData = ModData#mod{http_version = Version}, httpd_response:send_status(NewModData, 413, "Header too long"), Reason = io_lib:format("Header too long, max size is ~p~n", @@ -246,7 +225,6 @@ handle_info({Proto, Socket, Data}, {stop, normal, State#state{response_sent = true, mod = NewModData}}; NewMFA -> - ?hdrd("data processed - reactivate socket", [{new_mfa, NewMFA}]), http_transport:setopts(SockType, Socket, [{active, once}]), case NewDataSize of undefined -> @@ -293,6 +271,10 @@ handle_info(check_data, #state{data = Data, byte_limit = Byte_Limit} = State) -> _ -> {stop, normal, State#state{response_sent = true}} end; + +handle_info({'EXIT', _, Reason}, State) -> + {stop, Reason, State}; + %% Default case handle_info(Info, #state{mod = ModData} = State) -> Error = lists:flatten( @@ -324,10 +306,8 @@ terminate(Reason, #state{response_sent = false, mod = ModData} = State) -> terminate(_Reason, State) -> do_terminate(State). -do_terminate(#state{mod = ModData, manager = Manager} = State) -> - catch httpd_manager:done_connection(Manager), +do_terminate(#state{mod = ModData} = State) -> cancel_request_timeout(State), - %% receive after 5000 -> ok end, httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket). @@ -355,30 +335,24 @@ await_socket_ownership_transfer(AcceptTimeout) -> handle_http_msg({_, _, Version, {_, _}, _}, #state{status = busy, mod = ModData} = State) -> - ?hdrt("handle http msg when manager busy", [{mod, ModData}]), handle_manager_busy(State#state{mod = ModData#mod{http_version = Version}}), {stop, normal, State}; handle_http_msg({_, _, Version, {_, _}, _}, #state{status = blocked, mod = ModData} = State) -> - ?hdrt("handle http msg when manager blocket", [{mod, ModData}]), handle_manager_blocked(State#state{mod = ModData#mod{http_version = Version}}), {stop, normal, State}; handle_http_msg({Method, Uri, Version, {RecordHeaders, Headers}, Body}, #state{status = accept, mod = ModData} = State) -> - ?hdrt("handle http msg when manager accepting", - [{method, Method}, {mod, ModData}]), case httpd_request:validate(Method, Uri, Version) of ok -> - ?hdrt("request validated", []), {ok, NewModData} = httpd_request:update_mod_data(ModData, Method, Uri, Version, Headers), - ?hdrt("new mod data", [{mod, NewModData}]), case is_host_specified_if_required(NewModData#mod.absolute_uri, RecordHeaders, Version) of true -> @@ -392,23 +366,18 @@ handle_http_msg({Method, Uri, Version, {RecordHeaders, Headers}, Body}, {stop, normal, State#state{response_sent = true}} end; {error, {not_supported, What}} -> - ?hdrd("validation failed: not supported", [{what, What}]), httpd_response:send_status(ModData#mod{http_version = Version}, 501, {Method, Uri, Version}), Reason = io_lib:format("Not supported: ~p~n", [What]), error_log(Reason, ModData), {stop, normal, State#state{response_sent = true}}; {error, {bad_request, {forbidden, URI}}} -> - ?hdrd("validation failed: bad request - forbidden", - [{uri, URI}]), httpd_response:send_status(ModData#mod{http_version = Version}, 403, URI), Reason = io_lib:format("Forbidden URI: ~p~n", [URI]), error_log(Reason, ModData), {stop, normal, State#state{response_sent = true}}; {error, {bad_request, {malformed_syntax, URI}}} -> - ?hdrd("validation failed: bad request - malformed syntax", - [{uri, URI}]), httpd_response:send_status(ModData#mod{http_version = Version}, 400, URI), Reason = io_lib:format("Malformed syntax in URI: ~p~n", [URI]), @@ -417,12 +386,9 @@ handle_http_msg({Method, Uri, Version, {RecordHeaders, Headers}, Body}, end; handle_http_msg({ChunkedHeaders, Body}, State = #state{headers = Headers}) -> - ?hdrt("handle http msg", - [{chunked_headers, ChunkedHeaders}, {body, Body}]), NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders), handle_response(State#state{headers = NewHeaders, body = Body}); handle_http_msg(Body, State) -> - ?hdrt("handle http msg", [{body, Body}]), handle_response(State#state{body = Body}). handle_manager_busy(#state{mod = #mod{config_db = ConfigDB}} = State) -> @@ -445,7 +411,6 @@ is_host_specified_if_required(_, _, _) -> true. handle_body(#state{mod = #mod{config_db = ConfigDB}} = State) -> - ?hdrt("handle body", []), MaxHeaderSize = max_header_size(ConfigDB), MaxBodySize = max_body_size(ConfigDB), @@ -459,34 +424,22 @@ handle_body(#state{mod = #mod{config_db = ConfigDB}} = State) -> handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, MaxHeaderSize, MaxBodySize) -> - ?hdrt("handle body", [{headers, Headers}, {body, Body}]), case Headers#http_request_h.'transfer-encoding' of "chunked" -> - ?hdrt("chunked - attempt decode", []), case http_chunk:decode(Body, MaxBodySize, MaxHeaderSize) of {Module, Function, Args} -> - ?hdrt("chunk decoded", - [{module, Module}, - {function, Function}, - {args, Args}]), http_transport:setopts(ModData#mod.socket_type, ModData#mod.socket, [{active, once}]), {noreply, State#state{mfa = {Module, Function, Args}}}; {ok, {ChunkedHeaders, NewBody}} -> - ?hdrt("chunk decoded", - [{chunked_headers, ChunkedHeaders}, - {new_body, NewBody}]), NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders), - ?hdrt("chunked - headers handled", - [{new_headers, NewHeaders}]), handle_response(State#state{headers = NewHeaders, body = NewBody}) end; Encoding when is_list(Encoding) -> - ?hdrt("not chunked - encoding", [{encoding, Encoding}]), httpd_response:send_status(ModData, 501, "Unknown Transfer-Encoding"), Reason = io_lib:format("Unknown Transfer-Encoding: ~p~n", @@ -494,17 +447,12 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, error_log(Reason, ModData), {stop, normal, State#state{response_sent = true}}; _ -> - ?hdrt("not chunked", []), Length = list_to_integer(Headers#http_request_h.'content-length'), case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of true -> case httpd_request:whole_body(Body, Length) of {Module, Function, Args} -> - ?hdrt("whole body", - [{module, Module}, - {function, Function}, - {args, Args}]), http_transport:setopts(ModData#mod.socket_type, ModData#mod.socket, [{active, once}]), @@ -512,15 +460,11 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, {Module, Function, Args}}}; {ok, NewBody} -> - ?hdrt("whole body", - [{new_body, NewBody}]), handle_response( State#state{headers = Headers, body = NewBody}) end; false -> - ?hdrd("body too long", - [{length, Length}, {max_body_size, MaxBodySize}]), httpd_response:send_status(ModData, 413, "Body too long"), error_log("Body too long", ModData), {stop, normal, State#state{response_sent = true}} @@ -582,8 +526,6 @@ handle_response(#state{body = Body, mod = ModData, headers = Headers, max_keep_alive_request = Max} = State) when Max > 0 -> - ?hdrt("handle response", - [{body, Body}, {mod, ModData}, {headers, Headers}, {max, Max}]), {NewBody, Data} = httpd_request:body_data(Headers, Body), ok = httpd_response:generate_and_send_response( ModData#mod{entity_body = NewBody}), @@ -592,8 +534,6 @@ handle_response(#state{body = Body, handle_response(#state{body = Body, headers = Headers, mod = ModData} = State) -> - ?hdrt("handle response", - [{body, Body}, {mod, ModData}, {headers, Headers}]), {NewBody, _} = httpd_request:body_data(Headers, Body), ok = httpd_response:generate_and_send_response( ModData#mod{entity_body = NewBody}), @@ -601,7 +541,6 @@ handle_response(#state{body = Body, handle_next_request(#state{mod = #mod{connection = true} = ModData, max_keep_alive_request = Max} = State, Data) -> - ?hdrt("handle next request", [{max, Max}]), NewModData = #mod{socket_type = ModData#mod.socket_type, socket = ModData#mod.socket, @@ -630,11 +569,9 @@ handle_next_request(#state{mod = #mod{connection = true} = ModData, end; handle_next_request(State, _) -> - ?hdrt("handle next request - stop", []), {stop, normal, State}. activate_request_timeout(#state{timeout = Time} = State) -> - ?hdrt("activate request timeout", [{time, Time}]), Ref = erlang:send_after(Time, self(), timeout), State#state{timer = Ref}. data_receive_counter(State, Byte_limit) -> diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src index 4aea2ef3d7..a6dd364c2d 100644 --- a/lib/inets/src/inets_app/inets.app.src +++ b/lib/inets/src/inets_app/inets.app.src @@ -1,7 +1,7 @@ %% This is an -*- erlang -*- file. %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -59,6 +59,7 @@ httpd_acceptor, httpd_acceptor_sup, httpd_cgi, + httpd_connection_sup, httpd_conf, httpd_esi, httpd_example, diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index f18db273ec..c156b34406 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -158,12 +158,14 @@ MODULES = \ httpc_cookie_SUITE \ httpc_proxy_SUITE \ httpd_SUITE \ + old_httpd_SUITE \ httpd_basic_SUITE \ httpd_mod \ httpd_block \ httpd_load \ httpd_time_test \ httpd_1_1 \ + httpd_1_0 \ httpd_test_lib \ inets_sup_SUITE \ inets_SUITE \ @@ -201,7 +203,7 @@ INETS_FILES = inets.config $(INETS_SPECS) # inets_tftp_suite INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data -HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data httpd_basic_SUITE_data +HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data httpd_basic_SUITE_data old_httpd_SUITE_data HTTPC_DATADIRS = httpc_SUITE_data httpc_proxy_SUITE_data FTP_DATADIRS = ftp_SUITE_data diff --git a/lib/inets/test/httpd_1_0.erl b/lib/inets/test/httpd_1_0.erl new file mode 100644 index 0000000000..53f23b12e0 --- /dev/null +++ b/lib/inets/test/httpd_1_0.erl @@ -0,0 +1,33 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(httpd_1_0). + +-export([host/4]). + +%%------------------------------------------------------------------------- +%% Test cases +%%------------------------------------------------------------------------- +host(Type, Port, Host, Node) -> + %% No host needed for HTTP/1.0 + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET / HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]). diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl index 07d94ea97a..4b2a5f619d 100644 --- a/lib/inets/test/httpd_1_1.erl +++ b/lib/inets/test/httpd_1_1.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -20,8 +20,6 @@ -module(httpd_1_1). --include("test_server.hrl"). --include("test_server_line.hrl"). -include_lib("kernel/include/file.hrl"). -export([host/4, chunked/4, expect/4, range/4, if_test/5, http_trace/4, @@ -40,14 +38,10 @@ %%------------------------------------------------------------------------- -%% Test cases starts here. +%% Test cases %%------------------------------------------------------------------------- host(Type, Port, Host, Node) -> - %% No host needed for HTTP/1.0 - ok = httpd_test_lib:verify_request(Type, Host, Port, Node, - "GET / HTTP/1.0\r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/1.0"}]), + %% No host must generate an error ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET / HTTP/1.1\r\n\r\n", diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index ef801f91c7..34d701eb26 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -1,2238 +1,770 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% --module(httpd_SUITE). +%% +%% ct:run("../inets_test", httpd_SUITE). +%% --include_lib("test_server/include/test_server.hrl"). --include("test_server_line.hrl"). --include("inets_test_lib.hrl"). +-module(httpd_SUITE). -include_lib("kernel/include/file.hrl"). +-include_lib("common_test/include/ct.hrl"). +-include("inets_test_lib.hrl"). -%% Test server specific exports --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). --export([init_per_testcase/2, end_per_testcase/2, - init_per_suite/1, end_per_suite/1]). - -%% Core Server tests --export([ - ip_mod_alias/1, - ip_mod_actions/1, - ip_mod_security/1, - ip_mod_auth/1, - ip_mod_auth_api/1, - ip_mod_auth_mnesia_api/1, - ip_mod_htaccess/1, - ip_mod_cgi/1, - ip_mod_esi/1, - ip_mod_get/1, - ip_mod_head/1, - ip_mod_all/1, - ip_load_light/1, - ip_load_medium/1, - ip_load_heavy/1, - ip_dos_hostname/1, - ip_time_test/1, - ip_block_disturbing_idle/1, - ip_block_non_disturbing_idle/1, - ip_block_503/1, - ip_block_disturbing_active/1, - ip_block_non_disturbing_active/1, - ip_block_disturbing_active_timeout_not_released/1, - ip_block_disturbing_active_timeout_released/1, - ip_block_non_disturbing_active_timeout_not_released/1, - ip_block_non_disturbing_active_timeout_released/1, - ip_block_disturbing_blocker_dies/1, - ip_block_non_disturbing_blocker_dies/1, - ip_restart_no_block/1, - ip_restart_disturbing_block/1, - ip_restart_non_disturbing_block/1 - ]). - --export([ - essl_mod_alias/1, - essl_mod_actions/1, - essl_mod_security/1, - essl_mod_auth/1, - essl_mod_auth_api/1, - essl_mod_auth_mnesia_api/1, - essl_mod_htaccess/1, - essl_mod_cgi/1, - essl_mod_esi/1, - essl_mod_get/1, - essl_mod_head/1, - essl_mod_all/1, - essl_load_light/1, - essl_load_medium/1, - essl_load_heavy/1, - essl_dos_hostname/1, - essl_time_test/1, - essl_restart_no_block/1, - essl_restart_disturbing_block/1, - essl_restart_non_disturbing_block/1, - essl_block_disturbing_idle/1, - essl_block_non_disturbing_idle/1, - essl_block_503/1, - essl_block_disturbing_active/1, - essl_block_non_disturbing_active/1, - essl_block_disturbing_active_timeout_not_released/1, - essl_block_disturbing_active_timeout_released/1, - essl_block_non_disturbing_active_timeout_not_released/1, - essl_block_non_disturbing_active_timeout_released/1, - essl_block_disturbing_blocker_dies/1, - essl_block_non_disturbing_blocker_dies/1 - ]). - -%%% HTTP 1.1 tests --export([ip_host/1, ip_chunked/1, ip_expect/1, ip_range/1, - ip_if_test/1, ip_http_trace/1, ip_http1_1_head/1, - ip_mod_cgi_chunked_encoding_test/1]). - -%%% HTTP 1.0 tests --export([ip_head_1_0/1, ip_get_1_0/1, ip_post_1_0/1]). - -%%% HTTP 0.9 tests --export([ip_get_0_9/1]). - -%%% Ticket tests --export([ticket_5775/1,ticket_5865/1,ticket_5913/1,ticket_6003/1, - ticket_7304/1]). - -%%% IPv6 tests --export([ipv6_hostname_ipcomm/0, ipv6_hostname_ipcomm/1, - ipv6_address_ipcomm/0, ipv6_address_ipcomm/1, - ipv6_hostname_essl/0, ipv6_hostname_essl/1, - ipv6_address_essl/0, ipv6_address_essl/1]). - -%% Help functions --export([cleanup_mnesia/0, setup_mnesia/0, setup_mnesia/1]). - --define(IP_PORT, 8898). --define(SSL_PORT, 8899). --define(MAX_HEADER_SIZE, 256). --define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1"). - -%% Minutes before failed auths timeout. --define(FAIL_EXPIRE_TIME,1). - -%% Seconds before successful auths timeout. --define(AUTH_TIMEOUT,5). +%% Note: This directive should only be used in test suites. +-compile(export_all). -record(httpd_user, {user_name, password, user_data}). -record(httpd_group, {group_name, userlist}). - %%-------------------------------------------------------------------- -%% all(Arg) -> [Doc] | [Case] | {skip, Comment} -%% Arg - doc | suite -%% Doc - string() -%% Case - atom() -%% Name of a test case function. -%% Comment - string() -%% Description: Returns documentation/test cases in this test suite -%% or a skip tuple if the platform is not supported. +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. -all() -> +all() -> [ - {group, ip}, - {group, ssl}, - {group, http_1_1_ip}, - {group, http_1_0_ip}, - {group, http_0_9_ip}, - {group, ipv6}, - {group, tickets} + {group, http} + %{group, https} ]. -groups() -> +groups() -> [ - {ip, [], - [ip_mod_alias, ip_mod_actions, ip_mod_security, - ip_mod_auth, ip_mod_auth_api, ip_mod_auth_mnesia_api, - ip_mod_htaccess, ip_mod_cgi, ip_mod_esi, ip_mod_get, - ip_mod_head, ip_mod_all, ip_load_light, ip_load_medium, - ip_load_heavy, ip_dos_hostname, ip_time_test, - ip_restart_no_block, ip_restart_disturbing_block, - ip_restart_non_disturbing_block, - ip_block_disturbing_idle, ip_block_non_disturbing_idle, - ip_block_503, ip_block_disturbing_active, - ip_block_non_disturbing_active, - ip_block_disturbing_active_timeout_not_released, - ip_block_disturbing_active_timeout_released, - ip_block_non_disturbing_active_timeout_not_released, - ip_block_non_disturbing_active_timeout_released, - ip_block_disturbing_blocker_dies, - ip_block_non_disturbing_blocker_dies]}, - {ssl, [], [{group, essl}]}, - {essl, [], - [essl_mod_alias, essl_mod_actions, essl_mod_security, - essl_mod_auth, essl_mod_auth_api, - essl_mod_auth_mnesia_api, essl_mod_htaccess, - essl_mod_cgi, essl_mod_esi, essl_mod_get, essl_mod_head, - essl_mod_all, essl_load_light, essl_load_medium, - essl_load_heavy, essl_dos_hostname, essl_time_test, - essl_restart_no_block, essl_restart_disturbing_block, - essl_restart_non_disturbing_block, - essl_block_disturbing_idle, - essl_block_non_disturbing_idle, essl_block_503, - essl_block_disturbing_active, - essl_block_non_disturbing_active, - essl_block_disturbing_active_timeout_not_released, - essl_block_disturbing_active_timeout_released, - essl_block_non_disturbing_active_timeout_not_released, - essl_block_non_disturbing_active_timeout_released, - essl_block_disturbing_blocker_dies, - essl_block_non_disturbing_blocker_dies]}, - {http_1_1_ip, [], - [ip_host, ip_chunked, ip_expect, ip_range, ip_if_test, - ip_http_trace, ip_http1_1_head, - ip_mod_cgi_chunked_encoding_test]}, - {http_1_0_ip, [], - [ip_head_1_0, ip_get_1_0, ip_post_1_0]}, - {http_0_9_ip, [], [ip_get_0_9]}, - {ipv6, [], [ipv6_hostname_ipcomm, ipv6_address_ipcomm, - ipv6_hostname_essl, ipv6_address_essl]}, - {tickets, [], - [ticket_5775, ticket_5865, ticket_5913, ticket_6003, - ticket_7304]}]. - - -init_per_group(ipv6 = _GroupName, Config) -> - case inets_test_lib:has_ipv6_support() of - {ok, _} -> - Config; - _ -> - {skip, "Host does not support IPv6"} - end; -init_per_group(essl, Config) -> - catch crypto:stop(), - case (catch crypto:start()) of - ok -> - Config; - _ -> - {skip, "Crypto not startable"} - end; - -init_per_group(_GroupName, Config) -> - Config. + {http, [], all_groups()}, + %{https, [], all_groups()}, + {http_1_1, [], [host, chunked, expect, cgi, max_clients + ] ++ http_head() ++ http_get()}, + {http_1_0, [], [host, cgi] ++ http_head() ++ http_get()}, + {http_0_9, [], http_head() ++ http_get()} + ]. -end_per_group(_GroupName, Config) -> - Config. +all_groups ()-> + [{group, http_1_1}, + {group, http_1_0}, + {group, http_0_9} + ]. +http_head() -> + [head]. +http_get() -> + [alias, get, + basic_auth, + esi, ssi]. -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- init_per_suite(Config) -> - io:format(user, "init_per_suite -> entry with" - "~n Config: ~p" - "~n", [Config]), - - ?PRINT_SYSTEM_INFO([]), - PrivDir = ?config(priv_dir, Config), - SuiteTopDir = filename:join(PrivDir, ?MODULE), - case file:make_dir(SuiteTopDir) of - ok -> - ok; - {error, eexist} -> - ok; - Error -> - throw({error, {failed_creating_suite_top_dir, Error}}) - end, - - [{has_ipv6_support, inets_test_lib:has_ipv6_support()}, - {suite_top_dir, SuiteTopDir}, + DataDir = ?config(data_dir, Config), + inets_test_lib:stop_apps([inets]), + inets_test_lib:start_apps([inets]), + ServerRoot = filename:join(PrivDir, "server_root"), + inets_test_lib:del_dirs(ServerRoot), + DocRoot = filename:join(ServerRoot, "htdocs"), + setup_server_dirs(ServerRoot, DocRoot, DataDir), + [{server_root, ServerRoot}, + {doc_root, DocRoot}, {node, node()}, - {host, inets_test_lib:hostname()}, - {address, getaddr()} | Config]. - - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- + {host, inets_test_lib:hostname()} | Config]. end_per_suite(_Config) -> - %% SuiteTopDir = ?config(suite_top_dir, Config), - %% inets_test_lib:del_dirs(SuiteTopDir), ok. - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(Case, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - NewConfig = init_per_testcase2(Case, Config), - init_per_testcase3(Case, NewConfig). - - -init_per_testcase2(Case, Config) -> - - %% tsp("init_per_testcase2 -> entry with" - %% "~n Config: ~p", [Config]), - - IpNormal = integer_to_list(?IP_PORT) ++ ".conf", - IpHtaccess = integer_to_list(?IP_PORT) ++ "htaccess.conf", - SslNormal = integer_to_list(?SSL_PORT) ++ ".conf", - SslHtaccess = integer_to_list(?SSL_PORT) ++ "htaccess.conf", - - DataDir = ?config(data_dir, Config), - SuiteTopDir = ?config(suite_top_dir, Config), +init_per_group(https = Group, Config0) -> + case start_apps(Group) of + ok -> + init_httpd(Group, [{type, ssl} | Config0]); + _ -> + {skip, "Could not start https apps"} + end; - %% tsp("init_per_testcase2 -> " - %% "~n SuiteDir: ~p" - %% "~n DataDir: ~p", [SuiteTopDir, DataDir]), +init_per_group(http = Group, Config0) -> + init_httpd(Group, [{type, ip_comm} | Config0]); +init_per_group(http_1_1, Config) -> + [{http_version, "HTTP/1.1"} | Config]; +init_per_group(http_1_0, Config) -> + [{http_version, "HTTP/1.0"} | Config]; +init_per_group(http_0_9, Config) -> + [{http_version, "HTTP/0.9"} | Config]; +init_per_group(_, Config) -> + Config. +end_per_group(http, _Config) -> + inets:stop(); +end_per_group(https, _Config) -> + ssl:stop(), + inets:stop(); +end_per_group(_, _) -> + ok. + +init_httpd(Group, Config0) -> + Config1 = proplists:delete(port, Config0), + Config = proplists:delete(server_pid, Config1), + {Pid, Port} = server_start(Group, server_config(Group, Config)), + [{server_pid, Pid}, {port, Port} | Config]. +%%-------------------------------------------------------------------- +init_per_testcase(host = Case, Config) -> + Prop = ?config(tc_group_properties, Config), + Name = proplists:get_value(name, Prop), + Cb = case Name of + http_1_0 -> + httpd_1_0; + http_1_1 -> + httpd_1_1 + end, + common_init_per_test_case(Case, [{version_cb, Cb} | proplists:delete(version_cb, Config)]); + +%% init_per_testcase(basic_auth = Case, Config) -> +%% start_mnesia(?config(node, Config)), +%% common_init_per_test_case(Case, Config); - TcTopDir = filename:join(SuiteTopDir, Case), - ?line ok = file:make_dir(TcTopDir), +init_per_testcase(max_clients, Config) -> + Pid = ?config(server_pid, Config), + Prop = httpd:info(Pid), + Port = proplists:get_value(port, Prop), + TempProp = [{port, Port} | proplists:delete(port, server_config(http, Config))], + NewProp = [{max_clients, 1} | TempProp], + httpd:reload_config(NewProp, non_disturbing), + Config; + +init_per_testcase(_Case, Config) -> + common_init_per_test_case(_Case, Config). + +%%% Should be run by all test cases except max_clients, to make +%%% sure failiure of max_clients does not affect other test cases +common_init_per_test_case(_Case, Config) -> + Pid = ?config(server_pid, Config), + Prop = httpd:info(Pid), + case proplists:get_value(max_clients, Prop, 150) of + 150 -> + Config; + _ -> + end_per_testcase(max_clients, Config) + end. - %% tsp("init_per_testcase2 -> " - %% "~n TcTopDir: ~p", [TcTopDir]), +end_per_testcase(max_clients, Config) -> + Pid = ?config(server_pid, Config), + Prop = httpd:info(Pid), + Port = proplists:get_value(port, Prop), + TempProp = [{port, Port} | proplists:delete(port, server_config(http, Config))], + NewProp = proplists:delete(max_clients, TempProp), + httpd:reload_config(NewProp, non_disturbing), + Config; - DataSrc = filename:join([DataDir, "server_root"]), - ServerRoot = filename:join([TcTopDir, "server_root"]), - - %% tsp("init_per_testcase2 -> " - %% "~n DataSrc: ~p" - %% "~n ServerRoot: ~p", [DataSrc, ServerRoot]), +%% end_per_testcase(basic_auth, Config) -> +%% cleanup_mnesia(); +end_per_testcase(_Case, _Config) -> + ok. - ok = file:make_dir(ServerRoot), - ok = file:make_dir(filename:join([TcTopDir, "logs"])), +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- - NewConfig = [{tc_top_dir, TcTopDir}, {server_root, ServerRoot} | Config], +head() -> + [{doc, "HTTP HEAD request for static page"}]. - %% tsp("init_per_testcase2 -> copy DataSrc to ServerRoot"), +head(Config) when is_list(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + ok = httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request("HEAD /index.html ", Version, Host), + [{statuscode, head_status(Version)}, + {version, Version}]). - inets_test_lib:copy_dirs(DataSrc, ServerRoot), +get() -> + [{doc, "HTTP GET request for static page"}]. - %% tsp("init_per_testcase2 -> fix cgi"), - EnvCGI = filename:join([ServerRoot, "cgi-bin", "printenv.sh"]), - {ok, FileInfo} = file:read_file_info(EnvCGI), - ok = file:write_file_info(EnvCGI, - FileInfo#file_info{mode = 8#00755}), - - EchoCGI = case test_server:os_type() of - {win32, _} -> - "cgi_echo.exe"; - _ -> - "cgi_echo" - end, - CGIDir = filename:join([ServerRoot, "cgi-bin"]), - inets_test_lib:copy_file(EchoCGI, DataDir, CGIDir), - NewEchoCGI = filename:join([CGIDir, EchoCGI]), - {ok, FileInfo1} = file:read_file_info(NewEchoCGI), - ok = file:write_file_info(NewEchoCGI, - FileInfo1#file_info{mode = 8#00755}), - - %% To be used by IP test cases - %% tsp("init_per_testcase2 -> ip testcase setups"), - create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig], - normal_access, IpNormal), - create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig], - mod_htaccess, IpHtaccess), - - %% To be used by SSL test cases - %% tsp("init_per_testcase2 -> ssl testcase setups"), - SocketType = - case atom_to_list(Case) of - [X, $s, $s, $l | _] -> - case X of - $p -> ssl; - $e -> essl - end; - _ -> - ssl - end, +get(Config) when is_list(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + ok = httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request("GET /index.html ", Version, Host), + [{statuscode, 200}, + {header, "Content-Type", "text/html"}, + {header, "Date"}, + {header, "Server"}, + {version, Version}]). - create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], - normal_access, SslNormal), - create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], - mod_htaccess, SslHtaccess), - - %% To be used by IPv6 test cases. Case-clause is so that - %% you can do ts:run(inets, httpd_SUITE, <test case>) - %% for all cases except the ipv6 cases as they depend - %% on 'test_host_ipv6_only' that will only be present - %% when you run the whole test suite due to shortcomings - %% of the test server. - - tsp("init_per_testcase2 -> maybe generate IPv6 config file(s)"), - NewConfig2 = - case atom_to_list(Case) of - "ipv6_" ++ _ -> - case (catch inets_test_lib:has_ipv6_support(NewConfig)) of - {ok, IPv6Address0} -> - {ok, Hostname} = inet:gethostname(), - IPv6Address = http_transport:ipv6_name(IPv6Address0), - create_ipv6_config([{port, ?IP_PORT}, - {sock_type, ip_comm}, - {ipv6_host, IPv6Address} | - NewConfig], - "ipv6_hostname_ipcomm.conf", - Hostname), - create_ipv6_config([{port, ?IP_PORT}, - {sock_type, ip_comm}, - {ipv6_host, IPv6Address} | - NewConfig], - "ipv6_address_ipcomm.conf", - IPv6Address), - create_ipv6_config([{port, ?SSL_PORT}, - {sock_type, essl}, - {ipv6_host, IPv6Address} | - NewConfig], - "ipv6_hostname_essl.conf", - Hostname), - create_ipv6_config([{port, ?SSL_PORT}, - {sock_type, essl}, - {ipv6_host, IPv6Address} | - NewConfig], - "ipv6_address_essl.conf", - IPv6Address), - [{ipv6_host, IPv6Address} | NewConfig]; - _ -> - NewConfig - end; +basic_auth() -> + [{doc, "Test Basic authentication with WWW-Authenticate header"}]. +basic_auth(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + basic_auth_requiered(Config), + %% Authentication OK! ["one:OnePassword" user first in user list] + ok = auth_status(auth_request("/open/dummy.html", "one", "onePassword", Version, Host), Config, + [{statuscode, 200}]), + %% Authentication OK and a directory listing is supplied! + %% ["Aladdin:open sesame" user second in user list] + ok = auth_status(auth_request("/open/", "Aladdin", "AladdinPassword", Version, Host), Config, + [{statuscode, 200}]), + %% User correct but wrong password! ["one:one" user first in user list] + ok = auth_status(auth_request("/open/dummy.html", "one", "one", Version, Host), Config, + [{statuscode, 401}, + {header, "WWW-Authenticate"}]), + %% Make sure Authenticate header is received even the second time + %% we try a incorrect password! Otherwise a browser client will hang! + ok = auth_status(auth_request("/open/dummy.html", "one", "one", Version, Host), Config, + [{statuscode, 401}, + {header, "WWW-Authenticate"}]), + %% Neither user or password correct! ["dummy:dummy"] + ok = auth_status(auth_request("/open/dummy.html", "dummy", "dummy", Version, Host), Config, + [{statuscode, 401}]), + %% Nested secret/top_secret OK! ["Aladdin:open sesame"] + ok = http_status(auth_request("/secret/top_secret/", "Aladdin", "AladdinPassword", Version, Host), + Config, [{statuscode, 200}]), + %% Authentication still required! + basic_auth_requiered(Config). + +ssi() -> + [{doc, "HTTP GET server side include test"}]. +ssi(Config) when is_list(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + ok = httpd_test_lib:verify_request(?config(type, Config), Host, ?config(port, Config), + ?config(node, Config), + http_request("GET /fsize.shtml ", Version, Host), + [{statuscode, 200}, + {header, "Content-Type", "text/html"}, + {header, "Date"}, + {header, "Server"}, + {version, Version}]). +host() -> + [{doc, "Test host header"}]. + +host(Config) when is_list(Config) -> + Cb = ?config(version_cb, Config), + Cb:host(?config(type, Config), ?config(port, Config), + ?config(host, Config), ?config(node, Config)). + +chunked() -> + [{doc, "Check that the server accepts chunked requests."}]. + +chunked(Config) when is_list(Config) -> + httpd_1_1:chunked(?config(type, Config), ?config(port, Config), + ?config(host, Config), ?config(node, Config)). + +expect() -> + ["Check that the server handles request with the expect header " + "field appropiate"]. +expect(Config) when is_list(Config) -> + httpd_1_1:expect(?config(type, Config), ?config(port, Config), + ?config(host, Config), ?config(node, Config)). + +max_clients() -> + [{doc, "Test max clients limit"}]. + +max_clients(Config) when is_list(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + Pid = ?config(server_pid, Config), + ct:pal("Configurartion: ~p~n", [httpd:info(Pid)]), + spawn(fun() -> httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request("GET /eval?httpd_example:delay(1000) ", + Version, Host), + [{statuscode, 200}, + {version, Version}]) + end), + ok = httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request("GET /index.html ", Version, Host), + [{statuscode, 503}, + {version, Version}]), + receive + after 1000 -> + ok = httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request("GET /index.html ", Version, Host), + [{statuscode, 200}, + {version, Version}]) + end. + +esi() -> + [{doc, "Test mod_esi"}]. + +esi(Config) when is_list(Config) -> + ok = http_status("GET /eval?httpd_example:print(\"Hi!\") ", + Config, [{statuscode, 200}]), + ok = http_status("GET /eval?not_allowed:print(\"Hi!\") ", + Config, [{statuscode, 403}]), + ok = http_status("GET /eval?httpd_example:undef(\"Hi!\") ", + Config, [{statuscode, 500}]), + ok = http_status("GET /cgi-bin/erl/httpd_example ", + Config, [{statuscode, 400}]), + ok = http_status("GET /cgi-bin/erl/httpd_example:get ", + Config, [{statuscode, 200}]), + ok = http_status("GET /cgi-bin/erl/httpd_example:" + "get?input=4711 ", Config, + [{statuscode, 200}]), + ok = http_status("GET /cgi-bin/erl/httpd_example:post ", + Config, [{statuscode, 200}]), + ok = http_status("GET /cgi-bin/erl/not_allowed:post ", + Config, [{statuscode, 403}]), + ok = http_status("GET /cgi-bin/erl/httpd_example:undef ", + Config, [{statuscode, 404}]), + ok = http_status("GET /cgi-bin/erl/httpd_example/yahoo ", + Config, [{statuscode, 302}]), + %% Check "ErlScriptNoCache" directive (default: false) + ok = http_status("GET /cgi-bin/erl/httpd_example:get ", + Config, [{statuscode, 200}, + {no_header, "cache-control"}]). + +cgi() -> + [{doc, "Test mod_cgi"}]. + +cgi(Config) when is_list(Config) -> + {Script, Script2, Script3} = + case test_server:os_type() of + {win32, _} -> + {"printenv.bat", "printenv.sh", "cgi_echo.exe"}; _ -> - NewConfig + {"printenv.sh", "printenv.bat", "cgi_echo"} end, - %% tsp("init_per_testcase2 -> done when" - %% "~n NewConfig2: ~p", [NewConfig2]), - - NewConfig2. - - -init_per_testcase3(Case, Config) -> - tsp("init_per_testcase3(~w) -> entry with" - "~n Config: ~p", [Case, Config]), + %%The length (> 100) is intentional + ok = http_status("POST /cgi-bin/" ++ Script3 ++ " ", + {"Content-Length:100 \r\n", + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"}, + Config, + [{statuscode, 200}, + {header, "content-type", "text/plain"}]), + + ok = http_status("GET /cgi-bin/"++ Script ++ " ", Config, [{statuscode, 200}]), + ok = http_status("GET /cgi-bin/not_there ", Config, + [{statuscode, 404}, {statuscode, 500}]), -%% %% Create a new fresh node to be used by the server in this test-case + ok = http_status("GET /cgi-bin/"++ Script ++ "?Nisse:kkk?sss/lll ", + Config, + [{statuscode, 200}]), -%% NodeName = list_to_atom(atom_to_list(Case) ++ "_httpd"), -%% Node = inets_test_lib:start_node(NodeName), + ok = http_status("POST /cgi-bin/"++ Script ++ " ", Config, + [{statuscode, 200}]), - %% Clean up (we do not want this clean up in end_per_testcase - %% if init_per_testcase crashes for some testcase it will - %% have contaminated the environment and there will be no clean up.) - %% This init can take a few different paths so that one crashes - %% does not mean that all invocations will. - - application:unset_env(inets, services), - application:stop(inets), - application:stop(ssl), - cleanup_mnesia(), - - %% Start initialization - tsp("init_per_testcase3(~w) -> start init", [Case]), - - Dog = test_server:timetrap(inets_test_lib:minutes(10)), - NewConfig = lists:keydelete(watchdog, 1, Config), - TcTopDir = ?config(tc_top_dir, Config), - - CaseRest = - case atom_to_list(Case) of - "ip_mod_htaccess" -> - inets_test_lib:start_http_server( - filename:join(TcTopDir, - integer_to_list(?IP_PORT) ++ - "htaccess.conf")), - "mod_htaccess"; - "ip_" ++ Rest -> - inets_test_lib:start_http_server( - filename:join(TcTopDir, - integer_to_list(?IP_PORT) ++ ".conf")), - Rest; - "ticket_5913" -> - HttpdOptions = - [{file, - filename:join(TcTopDir, - integer_to_list(?IP_PORT) ++ ".conf")}, - {accept_timeout,30000}, - {debug,[{exported_functions, - [httpd_manager,httpd_request_handler]}]}], - inets_test_lib:start_http_server(HttpdOptions); - "ticket_"++Rest -> - %% OTP-5913 use the new syntax of inets.config - inets_test_lib:start_http_server([{file, - filename:join(TcTopDir, - integer_to_list(?IP_PORT) ++ ".conf")}]), - Rest; - - [X, $s, $s, $l, $_, $m, $o, $d, $_, $h, $t, $a, $c, $c, $e, $s, $s] -> - ?ENSURE_STARTED([crypto, public_key, ssl]), - SslTag = - case X of - $p -> ssl; % Plain - $e -> essl % Erlang based ssl - end, - case inets_test_lib:start_http_server_ssl( - filename:join(TcTopDir, - integer_to_list(?SSL_PORT) ++ - "htaccess.conf"), SslTag) of - ok -> - "mod_htaccess"; - Other -> - error_logger:info_msg("Other: ~p~n", [Other]), - {skip, "SSL does not seem to be supported"} - end; - [X, $s, $s, $l, $_ | Rest] -> - ?ENSURE_STARTED([crypto, public_key, ssl]), - SslTag = - case X of - $p -> ssl; - $e -> essl - end, - case inets_test_lib:start_http_server_ssl( - filename:join(TcTopDir, - integer_to_list(?SSL_PORT) ++ - ".conf"), SslTag) of - ok -> - Rest; - Other -> - error_logger:info_msg("Other: ~p~n", [Other]), - {skip, "SSL does not seem to be supported"} - end; - "ipv6_" ++ _ = TestCaseStr -> - case inets_test_lib:has_ipv6_support() of - {ok, _} -> - inets_test_lib:start_http_server( - filename:join(TcTopDir, - TestCaseStr ++ ".conf")); - - _ -> - {skip, "Host does not support IPv6"} - end - end, - - InitRes = - case CaseRest of - {skip, _} = Skip -> - Skip; - "mod_auth_" ++ _ -> - start_mnesia(?config(node, Config)), - [{watchdog, Dog} | NewConfig]; - "mod_htaccess" -> - ServerRoot = ?config(server_root, Config), - Path = filename:join([ServerRoot, "htdocs"]), - catch remove_htaccess(Path), - create_htaccess_data(Path, ?config(address, Config)), - [{watchdog, Dog} | NewConfig]; - "range" -> - ServerRoot = ?config(server_root, Config), - Path = filename:join([ServerRoot, "htdocs"]), - create_range_data(Path), - [{watchdog, Dog} | NewConfig]; - _ -> - [{watchdog, Dog} | NewConfig] - end, + ok = http_status("GET /htbin/"++ Script ++ " ", Config, + [{statuscode, 200}]), - tsp("init_per_testcase3(~w) -> done when" - "~n InitRes: ~p", [Case, InitRes]), - - InitRes. - - -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(Case, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - end_per_testcase2(Case, lists:keydelete(watchdog, 1, Config)), - ok. - -end_per_testcase2(Case, Config) -> - tsp("end_per_testcase2(~w) -> entry with" - "~n Config: ~p", [Case, Config]), - application:unset_env(inets, services), - application:stop(inets), - application:stop(ssl), - application:stop(crypto), % used by the new ssl (essl test cases) - cleanup_mnesia(), - tsp("end_per_testcase2(~w) -> done", [Case]), - ok. - - -%%------------------------------------------------------------------------- -%% Test cases starts here. -%%------------------------------------------------------------------------- - -%%------------------------------------------------------------------------- -ip_mod_alias(doc) -> - ["Module test: mod_alias"]; -ip_mod_alias(suite) -> - []; -ip_mod_alias(Config) when is_list(Config) -> - httpd_mod:alias(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_actions(doc) -> - ["Module test: mod_actions"]; -ip_mod_actions(suite) -> - []; -ip_mod_actions(Config) when is_list(Config) -> - httpd_mod:actions(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_security(doc) -> - ["Module test: mod_security"]; -ip_mod_security(suite) -> - []; -ip_mod_security(Config) when is_list(Config) -> - ServerRoot = ?config(server_root, Config), - httpd_mod:security(ServerRoot, ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_auth(doc) -> - ["Module test: mod_auth"]; -ip_mod_auth(suite) -> - []; -ip_mod_auth(Config) when is_list(Config) -> - httpd_mod:auth(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_auth_api(doc) -> - ["Module test: mod_auth_api"]; -ip_mod_auth_api(suite) -> - []; -ip_mod_auth_api(Config) when is_list(Config) -> - ServerRoot = ?config(server_root, Config), - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_mod:auth_api(ServerRoot, "", ip_comm, ?IP_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "dets_", ip_comm, ?IP_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "mnesia_", ip_comm, ?IP_PORT, Host, Node), - ok. -%%------------------------------------------------------------------------- -ip_mod_auth_mnesia_api(doc) -> - ["Module test: mod_auth_mnesia_api"]; -ip_mod_auth_mnesia_api(suite) -> - []; -ip_mod_auth_mnesia_api(Config) when is_list(Config) -> - httpd_mod:auth_mnesia_api(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_mod_htaccess(doc) -> - ["Module test: mod_htaccess"]; -ip_mod_htaccess(suite) -> - []; -ip_mod_htaccess(Config) when is_list(Config) -> - httpd_mod:htaccess(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_mod_cgi(doc) -> - ["Module test: mod_cgi"]; -ip_mod_cgi(suite) -> - []; -ip_mod_cgi(Config) when is_list(Config) -> - httpd_mod:cgi(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_mod_esi(doc) -> - ["Module test: mod_esi"]; -ip_mod_esi(suite) -> - []; -ip_mod_esi(Config) when is_list(Config) -> - httpd_mod:esi(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_get(doc) -> - ["Module test: mod_get"]; -ip_mod_get(suite) -> - []; -ip_mod_get(Config) when is_list(Config) -> - httpd_mod:get(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_mod_head(doc) -> - ["Module test: mod_head"]; -ip_mod_head(suite) -> - []; -ip_mod_head(Config) when is_list(Config) -> - httpd_mod:head(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_mod_all(doc) -> - ["All modules test"]; -ip_mod_all(suite) -> - []; -ip_mod_all(Config) when is_list(Config) -> - httpd_mod:all(ip_comm, ?IP_PORT, - ?config(host, Config), ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_load_light(doc) -> - ["Test light load"]; -ip_load_light(suite) -> - []; -ip_load_light(Config) when is_list(Config) -> - httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config), - get_nof_clients(ip_comm, light)), - ok. -%%------------------------------------------------------------------------- -ip_load_medium(doc) -> - ["Test medium load"]; -ip_load_medium(suite) -> - []; -ip_load_medium(Config) when is_list(Config) -> - httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config), - get_nof_clients(ip_comm, medium)), - ok. -%%------------------------------------------------------------------------- -ip_load_heavy(doc) -> - ["Test heavy load"]; -ip_load_heavy(suite) -> - []; -ip_load_heavy(Config) when is_list(Config) -> - httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config), - get_nof_clients(ip_comm, heavy)), - ok. - - -%%------------------------------------------------------------------------- -ip_dos_hostname(doc) -> - ["Denial Of Service (DOS) attack test case"]; -ip_dos_hostname(suite) -> - []; -ip_dos_hostname(Config) when is_list(Config) -> - dos_hostname(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config), ?MAX_HEADER_SIZE), - ok. - - -%%------------------------------------------------------------------------- -ip_time_test(doc) -> - [""]; -ip_time_test(suite) -> - []; -ip_time_test(Config) when is_list(Config) -> - %% <CONDITIONAL-SKIP> - Skippable = [win32], - Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> + ok = http_status("GET /htbin/not_there ", Config, + [{statuscode, 404},{statuscode, 500}]), - httpd_time_test:t(ip_comm, ?config(host, Config), ?IP_PORT), - ok. - -%%------------------------------------------------------------------------- -ip_block_503(doc) -> - ["Check that you will receive status code 503 when the server" - " is blocked and 200 when its not blocked."]; -ip_block_503(suite) -> - []; -ip_block_503(Config) when is_list(Config) -> - httpd_block:block_503(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_disturbing_idle(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "distribing does not really make a difference in this case."]; -ip_block_disturbing_idle(suite) -> - []; -ip_block_disturbing_idle(Config) when is_list(Config) -> - httpd_block:block_disturbing_idle(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_non_disturbing_idle(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "non distribing does not really make a difference in this case."]; -ip_block_non_disturbing_idle(suite) -> - []; -ip_block_non_disturbing_idle(Config) when is_list(Config) -> - httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_disturbing_active(doc) -> - ["Check that you can block/unblock an active server. The strategy " - "distribing means ongoing requests should be terminated."]; -ip_block_disturbing_active(suite) -> - []; -ip_block_disturbing_active(Config) when is_list(Config) -> - httpd_block:block_disturbing_active(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_non_disturbing_active(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "non distribing means the ongoing requests should be compleated."]; -ip_block_non_disturbing_active(suite) -> - []; -ip_block_non_disturbing_active(Config) when is_list(Config) -> - httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_block_disturbing_active_timeout_not_released(doc) -> - ["Check that you can block an active server. The strategy " - "distribing means ongoing requests should be compleated" - "if the timeout does not occur."]; -ip_block_disturbing_active_timeout_not_released(suite) -> - []; -ip_block_disturbing_active_timeout_not_released(Config) - when is_list(Config) -> - httpd_block:block_disturbing_active_timeout_not_released(ip_comm, - ?IP_PORT, - ?config(host, - Config), - ?config(node, - Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_disturbing_active_timeout_released(doc) -> - ["Check that you can block an active server. The strategy " - "distribing means ongoing requests should be terminated when" - "the timeout occurs."]; -ip_block_disturbing_active_timeout_released(suite) -> - []; -ip_block_disturbing_active_timeout_released(Config) - when is_list(Config) -> - httpd_block:block_disturbing_active_timeout_released(ip_comm, - ?IP_PORT, - ?config(host, - Config), - ?config(node, - Config)), - ok. - -%%------------------------------------------------------------------------- -ip_block_non_disturbing_active_timeout_not_released(doc) -> - ["Check that you can block an active server. The strategy " - "non non distribing means ongoing requests should be completed."]; -ip_block_non_disturbing_active_timeout_not_released(suite) -> - []; -ip_block_non_disturbing_active_timeout_not_released(Config) - when is_list(Config) -> - httpd_block: - block_non_disturbing_active_timeout_not_released(ip_comm, - ?IP_PORT, - ?config(host, - Config), - ?config(node, - Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_non_disturbing_active_timeout_released(doc) -> - ["Check that you can block an active server. The strategy " - "non non distribing means ongoing requests should be completed. " - "When the timeout occurs the block operation sohould be canceled." ]; -ip_block_non_disturbing_active_timeout_released(suite) -> - []; -ip_block_non_disturbing_active_timeout_released(Config) - when is_list(Config) -> - httpd_block: - block_non_disturbing_active_timeout_released(ip_comm, - ?IP_PORT, - ?config(host, - Config), - ?config(node, - Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_disturbing_blocker_dies(doc) -> - []; -ip_block_disturbing_blocker_dies(suite) -> - []; -ip_block_disturbing_blocker_dies(Config) when is_list(Config) -> - httpd_block:disturbing_blocker_dies(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_block_non_disturbing_blocker_dies(doc) -> - []; -ip_block_non_disturbing_blocker_dies(suite) -> - []; -ip_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> - httpd_block:non_disturbing_blocker_dies(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_restart_no_block(doc) -> - [""]; -ip_restart_no_block(suite) -> - []; -ip_restart_no_block(Config) when is_list(Config) -> - httpd_block:restart_no_block(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_restart_disturbing_block(doc) -> - [""]; -ip_restart_disturbing_block(suite) -> - []; -ip_restart_disturbing_block(Config) when is_list(Config) -> - %% <CONDITIONAL-SKIP> - Condition = - fun() -> - case os:type() of - {unix, linux} -> - HW = string:strip(os:cmd("uname -m"), right, $\n), - case HW of - "ppc" -> - case inet:gethostname() of - {ok, "peach"} -> - true; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end - end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_block:restart_disturbing_block(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_restart_non_disturbing_block(doc) -> - [""]; -ip_restart_non_disturbing_block(suite) -> - []; -ip_restart_non_disturbing_block(Config) when is_list(Config) -> - %% <CONDITIONAL-SKIP> - Condition = - fun() -> - case os:type() of - {unix, linux} -> - HW = string:strip(os:cmd("uname -m"), right, $\n), - case HW of - "ppc" -> - case inet:gethostname() of - {ok, "peach"} -> - true; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end - end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_block:restart_non_disturbing_block(ip_comm, ?IP_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- - -essl_mod_alias(doc) -> - ["Module test: mod_alias - using new of configure new SSL"]; -essl_mod_alias(suite) -> - []; -essl_mod_alias(Config) when is_list(Config) -> - ssl_mod_alias(essl, Config). - - -ssl_mod_alias(Tag, Config) -> - httpd_mod:alias(Tag, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_actions(doc) -> - ["Module test: mod_actions - using new of configure new SSL"]; -essl_mod_actions(suite) -> - []; -essl_mod_actions(Config) when is_list(Config) -> - ssl_mod_actions(essl, Config). - - -ssl_mod_actions(Tag, Config) -> - httpd_mod:actions(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_security(doc) -> - ["Module test: mod_security - using new of configure new SSL"]; -essl_mod_security(suite) -> - []; -essl_mod_security(Config) when is_list(Config) -> - ssl_mod_security(essl, Config). - -ssl_mod_security(Tag, Config) -> - ServerRoot = ?config(server_root, Config), - httpd_mod:security(ServerRoot, - Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_auth(doc) -> - ["Module test: mod_auth - using new of configure new SSL"]; -essl_mod_auth(suite) -> - []; -essl_mod_auth(Config) when is_list(Config) -> - ssl_mod_auth(essl, Config). - -ssl_mod_auth(Tag, Config) -> - httpd_mod:auth(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - - -essl_mod_auth_api(doc) -> - ["Module test: mod_auth - using new of configure new SSL"]; -essl_mod_auth_api(suite) -> - []; -essl_mod_auth_api(Config) when is_list(Config) -> - ssl_mod_auth_api(essl, Config). - -ssl_mod_auth_api(Tag, Config) -> - ServerRoot = ?config(server_root, Config), - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_mod:auth_api(ServerRoot, "", Tag, ?SSL_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "dets_", Tag, ?SSL_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "mnesia_", Tag, ?SSL_PORT, Host, Node), - ok. - - -%%------------------------------------------------------------------------- - - -essl_mod_auth_mnesia_api(doc) -> - ["Module test: mod_auth_mnesia_api - using new of configure new SSL"]; -essl_mod_auth_mnesia_api(suite) -> - []; -essl_mod_auth_mnesia_api(Config) when is_list(Config) -> - ssl_mod_auth_mnesia_api(essl, Config). - -ssl_mod_auth_mnesia_api(Tag, Config) -> - httpd_mod:auth_mnesia_api(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_htaccess(doc) -> - ["Module test: mod_htaccess - using new of configure new SSL"]; -essl_mod_htaccess(suite) -> - []; -essl_mod_htaccess(Config) when is_list(Config) -> - ssl_mod_htaccess(essl, Config). - -ssl_mod_htaccess(Tag, Config) -> - httpd_mod:htaccess(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_cgi(doc) -> - ["Module test: mod_cgi - using new of configure new SSL"]; -essl_mod_cgi(suite) -> - []; -essl_mod_cgi(Config) when is_list(Config) -> - ssl_mod_cgi(essl, Config). - -ssl_mod_cgi(Tag, Config) -> - httpd_mod:cgi(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_esi(doc) -> - ["Module test: mod_esi - using new of configure new SSL"]; -essl_mod_esi(suite) -> - []; -essl_mod_esi(Config) when is_list(Config) -> - ssl_mod_esi(essl, Config). - -ssl_mod_esi(Tag, Config) -> - httpd_mod:esi(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_get(doc) -> - ["Module test: mod_get - using new of configure new SSL"]; -essl_mod_get(suite) -> - []; -essl_mod_get(Config) when is_list(Config) -> - ssl_mod_get(essl, Config). - -ssl_mod_get(Tag, Config) -> - httpd_mod:get(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_head(doc) -> - ["Module test: mod_head - using new of configure new SSL"]; -essl_mod_head(suite) -> - []; -essl_mod_head(Config) when is_list(Config) -> - ssl_mod_head(essl, Config). - -ssl_mod_head(Tag, Config) -> - httpd_mod:head(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_mod_all(doc) -> - ["All modules test - using new of configure new SSL"]; -essl_mod_all(suite) -> - []; -essl_mod_all(Config) when is_list(Config) -> - ssl_mod_all(essl, Config). - -ssl_mod_all(Tag, Config) -> - httpd_mod:all(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_load_light(doc) -> - ["Test light load - using new of configure new SSL"]; -essl_load_light(suite) -> - []; -essl_load_light(Config) when is_list(Config) -> - ssl_load_light(essl, Config). - -ssl_load_light(Tag, Config) -> - httpd_load:load_test(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config), - get_nof_clients(ssl, light)), - ok. - - -%%------------------------------------------------------------------------- - -essl_load_medium(doc) -> - ["Test medium load - using new of configure new SSL"]; -essl_load_medium(suite) -> - []; -essl_load_medium(Config) when is_list(Config) -> - ssl_load_medium(essl, Config). - -ssl_load_medium(Tag, Config) -> - %% <CONDITIONAL-SKIP> - Skippable = [win32], - Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_load:load_test(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config), - get_nof_clients(ssl, medium)), - ok. - - -%%------------------------------------------------------------------------- - -essl_load_heavy(doc) -> - ["Test heavy load - using new of configure new SSL"]; -essl_load_heavy(suite) -> - []; -essl_load_heavy(Config) when is_list(Config) -> - ssl_load_heavy(essl, Config). - -ssl_load_heavy(Tag, Config) -> - %% <CONDITIONAL-SKIP> - Skippable = [win32], - Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_load:load_test(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config), - get_nof_clients(ssl, heavy)), - ok. - - -%%------------------------------------------------------------------------- - - -essl_dos_hostname(doc) -> - ["Denial Of Service (DOS) attack test case - using new of configure new SSL"]; -essl_dos_hostname(suite) -> - []; -essl_dos_hostname(Config) when is_list(Config) -> - ssl_dos_hostname(essl, Config). - -ssl_dos_hostname(Tag, Config) -> - dos_hostname(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config), - ?MAX_HEADER_SIZE), - ok. - - -%%------------------------------------------------------------------------- - - -essl_time_test(doc) -> - ["using new of configure new SSL"]; -essl_time_test(suite) -> - []; -essl_time_test(Config) when is_list(Config) -> - ssl_time_test(essl, Config). - -ssl_time_test(Tag, Config) when is_list(Config) -> - %% <CONDITIONAL-SKIP> - FreeBSDVersionVerify = - fun() -> - case os:version() of - {7, 1, _} -> % We only have one such machine, so... - true; - _ -> - false - end - end, - Skippable = [win32, {unix, [{freebsd, FreeBSDVersionVerify}]}], - Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> + ok = http_status("GET /htbin/"++ Script ++ "?Nisse:kkk?sss/lll ", Config, + [{statuscode, 200}]), - httpd_time_test:t(Tag, - ?config(host, Config), - ?SSL_PORT), - ok. - - -%%------------------------------------------------------------------------- - - -essl_block_503(doc) -> - ["Check that you will receive status code 503 when the server" - " is blocked and 200 when its not blocked - using new of configure new SSL."]; -essl_block_503(suite) -> - []; -essl_block_503(Config) when is_list(Config) -> - ssl_block_503(essl, Config). - -ssl_block_503(Tag, Config) -> - httpd_block:block_503(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_disturbing_idle(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "distribing does not really make a difference in this case." - "Using new of configure new SSL"]; -essl_block_disturbing_idle(suite) -> - []; -essl_block_disturbing_idle(Config) when is_list(Config) -> - ssl_block_disturbing_idle(essl, Config). - -ssl_block_disturbing_idle(Tag, Config) -> - httpd_block:block_disturbing_idle(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_non_disturbing_idle(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "non distribing does not really make a difference in this case." - "Using new of configure new SSL"]; -essl_block_non_disturbing_idle(suite) -> - []; -essl_block_non_disturbing_idle(Config) when is_list(Config) -> - ssl_block_non_disturbing_idle(essl, Config). - -ssl_block_non_disturbing_idle(Tag, Config) -> - httpd_block:block_non_disturbing_idle(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_disturbing_active(doc) -> - ["Check that you can block/unblock an active server. The strategy " - "distribing means ongoing requests should be terminated." - "Using new of configure new SSL"]; -essl_block_disturbing_active(suite) -> - []; -essl_block_disturbing_active(Config) when is_list(Config) -> - ssl_block_disturbing_active(essl, Config). - -ssl_block_disturbing_active(Tag, Config) -> - httpd_block:block_disturbing_active(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_non_disturbing_active(doc) -> - ["Check that you can block/unblock an idle server. The strategy " - "non distribing means the ongoing requests should be compleated." - "Using new of configure new SSL"]; -essl_block_non_disturbing_active(suite) -> - []; -essl_block_non_disturbing_active(Config) when is_list(Config) -> - ssl_block_non_disturbing_active(essl, Config). - -ssl_block_non_disturbing_active(Tag, Config) -> - httpd_block:block_non_disturbing_idle(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_disturbing_active_timeout_not_released(doc) -> - ["Check that you can block an active server. The strategy " - "distribing means ongoing requests should be compleated" - "if the timeout does not occur." - "Using new of configure new SSL"]; -essl_block_disturbing_active_timeout_not_released(suite) -> - []; -essl_block_disturbing_active_timeout_not_released(Config) - when is_list(Config) -> - ssl_block_disturbing_active_timeout_not_released(essl, Config). - -ssl_block_disturbing_active_timeout_not_released(Tag, Config) -> - Port = ?SSL_PORT, - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_block:block_disturbing_active_timeout_not_released(Tag, - Port, Host, Node), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_disturbing_active_timeout_released(doc) -> - ["Check that you can block an active server. The strategy " - "distribing means ongoing requests should be terminated when" - "the timeout occurs." - "Using new of configure new SSL"]; -essl_block_disturbing_active_timeout_released(suite) -> - []; -essl_block_disturbing_active_timeout_released(Config) - when is_list(Config) -> - ssl_block_disturbing_active_timeout_released(essl, Config). - -ssl_block_disturbing_active_timeout_released(Tag, Config) -> - Port = ?SSL_PORT, - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_block:block_disturbing_active_timeout_released(Tag, - Port, - Host, - Node), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_non_disturbing_active_timeout_not_released(doc) -> - ["Check that you can block an active server. The strategy " - "non non distribing means ongoing requests should be completed." - "Using new of configure new SSL"]; -essl_block_non_disturbing_active_timeout_not_released(suite) -> - []; -essl_block_non_disturbing_active_timeout_not_released(Config) - when is_list(Config) -> - ssl_block_non_disturbing_active_timeout_not_released(essl, Config). - -ssl_block_non_disturbing_active_timeout_not_released(Tag, Config) -> - Port = ?SSL_PORT, - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_block:block_non_disturbing_active_timeout_not_released(Tag, - Port, - Host, - Node), - ok. - - -%%------------------------------------------------------------------------- - - -essl_block_non_disturbing_active_timeout_released(doc) -> - ["Check that you can block an active server. The strategy " - "non distribing means ongoing requests should be completed. " - "When the timeout occurs the block operation sohould be canceled." - "Using new of configure new SSL"]; -essl_block_non_disturbing_active_timeout_released(suite) -> - []; -essl_block_non_disturbing_active_timeout_released(Config) - when is_list(Config) -> - ssl_block_non_disturbing_active_timeout_released(essl, Config). - -ssl_block_non_disturbing_active_timeout_released(Tag, Config) - when is_list(Config) -> - Port = ?SSL_PORT, - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_block:block_non_disturbing_active_timeout_released(Tag, - Port, - Host, - Node), - - ok. - - -%%------------------------------------------------------------------------- - - -essl_block_disturbing_blocker_dies(doc) -> - ["using new of configure new SSL"]; -essl_block_disturbing_blocker_dies(suite) -> - []; -essl_block_disturbing_blocker_dies(Config) when is_list(Config) -> - ssl_block_disturbing_blocker_dies(essl, Config). - -ssl_block_disturbing_blocker_dies(Tag, Config) -> - httpd_block:disturbing_blocker_dies(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - -essl_block_non_disturbing_blocker_dies(doc) -> - ["using new of configure new SSL"]; -essl_block_non_disturbing_blocker_dies(suite) -> - []; -essl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> - ssl_block_non_disturbing_blocker_dies(essl, Config). - -ssl_block_non_disturbing_blocker_dies(Tag, Config) -> - httpd_block:non_disturbing_blocker_dies(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - - -essl_restart_no_block(doc) -> - ["using new of configure new SSL"]; -essl_restart_no_block(suite) -> - []; -essl_restart_no_block(Config) when is_list(Config) -> - ssl_restart_no_block(essl, Config). - -ssl_restart_no_block(Tag, Config) -> - httpd_block:restart_no_block(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - - -essl_restart_disturbing_block(doc) -> - ["using new of configure new SSL"]; -essl_restart_disturbing_block(suite) -> - []; -essl_restart_disturbing_block(Config) when is_list(Config) -> - ssl_restart_disturbing_block(essl, Config). - -ssl_restart_disturbing_block(Tag, Config) -> - %% <CONDITIONAL-SKIP> - Condition = - fun() -> - case os:type() of - {unix, linux} -> - case ?OSCMD("uname -m") of - "ppc" -> - case file:read_file_info("/etc/fedora-release") of - {ok, _} -> - case ?OSCMD("awk '{print $2}' /etc/fedora-release") of - "release" -> - %% Fedora 7 and later - case ?OSCMD("awk '{print $3}' /etc/fedora-release") of - "7" -> - true; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end - end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_block:restart_disturbing_block(Tag, ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- - - -essl_restart_non_disturbing_block(doc) -> - ["using new of configure new SSL"]; -essl_restart_non_disturbing_block(suite) -> - []; -essl_restart_non_disturbing_block(Config) when is_list(Config) -> - ssl_restart_non_disturbing_block(essl, Config). - -ssl_restart_non_disturbing_block(Tag, Config) -> - %% <CONDITIONAL-SKIP> - Condition = - fun() -> - case os:type() of - {unix, linux} -> - HW = string:strip(os:cmd("uname -m"), right, $\n), - case HW of - "ppc" -> - case inet:gethostname() of - {ok, "peach"} -> - true; - _ -> - false - end; - _ -> - false - end; - _ -> - false - end - end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - - httpd_block:restart_non_disturbing_block(Tag, - ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), - ok. - - -%%------------------------------------------------------------------------- -ip_host(doc) -> - ["Control that the server accepts/rejects requests with/ without host"]; -ip_host(suite)-> - []; -ip_host(Config) when is_list(Config) -> - httpd_1_1:host(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_chunked(doc) -> - ["Control that the server accepts chunked requests"]; -ip_chunked(suite) -> - []; -ip_chunked(Config) when is_list(Config) -> - httpd_1_1:chunked(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_expect(doc) -> - ["Control that the server handles request with the expect header " - "field appropiate"]; -ip_expect(suite)-> - []; -ip_expect(Config) when is_list(Config) -> - httpd_1_1:expect(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_range(doc) -> - ["Control that the server can handle range requests to plain files"]; -ip_range(suite)-> - []; -ip_range(Config) when is_list(Config) -> - httpd_1_1:range(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_if_test(doc) -> - ["Test that the if - request header fields is handled correclty"]; -ip_if_test(suite) -> - []; -ip_if_test(Config) when is_list(Config) -> - ServerRoot = ?config(server_root, Config), - DocRoot = filename:join([ServerRoot, "htdocs"]), - httpd_1_1:if_test(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config), DocRoot), - ok. -%%------------------------------------------------------------------------- -ip_http_trace(doc) -> - ["Test the trace module "]; -ip_http_trace(suite) -> - []; -ip_http_trace(Config) when is_list(Config) -> - httpd_1_1:http_trace(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. -%%------------------------------------------------------------------------- -ip_http1_1_head(doc) -> - ["Test the trace module "]; -ip_http1_1_head(suite)-> - []; -ip_http1_1_head(Config) when is_list(Config) -> - httpd_1_1:head(ip_comm, ?IP_PORT, ?config(host, Config), - ?config(node, Config)), - ok. - -%%------------------------------------------------------------------------- -ip_get_0_9(doc) -> - ["Test simple HTTP/0.9 GET"]; -ip_get_0_9(suite)-> - []; -ip_get_0_9(Config) when is_list(Config) -> - Host = ?config(host, Config), - Node = ?config(node, Config), - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "GET / \r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/0.9"} ]), - %% Without space after uri - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "GET /\r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/0.9"} ]), - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "GET / HTTP/0.9\r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/0.9"}]), + ok = http_status("POST /htbin/"++ Script ++ " ", Config, + [{statuscode, 200}]), - ok. -%%------------------------------------------------------------------------- -ip_head_1_0(doc) -> - ["Test HTTP/1.0 HEAD"]; -ip_head_1_0(suite)-> - []; -ip_head_1_0(Config) when is_list(Config) -> - Host = ?config(host, Config), - Node = ?config(node, Config), - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "HEAD / HTTP/1.0\r\n\r\n", [{statuscode, 200}, - {version, "HTTP/1.0"}]), + ok = http_status("POST /htbin/"++ Script ++ " ", Config, + [{statuscode, 200}]), - ok. -%%------------------------------------------------------------------------- -ip_get_1_0(doc) -> - ["Test HTTP/1.0 GET"]; -ip_get_1_0(suite)-> - []; -ip_get_1_0(Config) when is_list(Config) -> - Host = ?config(host, Config), - Node = ?config(node, Config), - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "GET / HTTP/1.0\r\n\r\n", [{statuscode, 200}, - {version, "HTTP/1.0"}]), + %% Execute an existing, but bad CGI script.. + ok = http_status("POST /htbin/"++ Script2 ++ " ", Config, + [{statuscode, 404}]), - ok. -%%------------------------------------------------------------------------- -ip_post_1_0(doc) -> - ["Test HTTP/1.0 POST"]; -ip_post_1_0(suite)-> - []; -ip_post_1_0(Config) when is_list(Config) -> - Host = ?config(host, Config), - Node = ?config(node, Config), - %% Test the post message formatin 1.0! Real post are testes elsewhere - ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, - "POST / HTTP/1.0\r\n\r\n " - "Content-Length:6 \r\n\r\nfoobar", - [{statuscode, 500}, {version, "HTTP/1.0"}]), + ok = http_status("POST /cgi-bin/"++ Script2 ++ " ", Config, + [{statuscode, 404}]), - ok. -%%------------------------------------------------------------------------- -ip_mod_cgi_chunked_encoding_test(doc) -> - ["Test the trace module "]; -ip_mod_cgi_chunked_encoding_test(suite)-> - []; -ip_mod_cgi_chunked_encoding_test(Config) when is_list(Config) -> - Host = ?config(host, Config), - Script = - case test_server:os_type() of - {win32, _} -> - "/cgi-bin/printenv.bat"; - _ -> - "/cgi-bin/printenv.sh" - end, - Requests = - ["GET " ++ Script ++ " HTTP/1.1\r\nHost:"++ Host ++"\r\n\r\n", - "GET /cgi-bin/erl/httpd_example/newformat HTTP/1.1\r\nHost:" - ++ Host ++"\r\n\r\n"], - httpd_1_1:mod_cgi_chunked_encoding_test(ip_comm, ?IP_PORT, - Host, - ?config(node, Config), - Requests), - ok. - -%------------------------------------------------------------------------- - -ipv6_hostname_ipcomm() -> - [{require, ipv6_hosts}]. -ipv6_hostname_ipcomm(X) -> - SocketType = ip_comm, - Port = ?IP_PORT, - ipv6_hostname(SocketType, Port, X). - -ipv6_hostname_essl() -> - [{require, ipv6_hosts}]. -ipv6_hostname_essl(X) -> - SocketType = essl, - Port = ?SSL_PORT, - ipv6_hostname(SocketType, Port, X). - -ipv6_hostname(_SocketType, _Port, doc) -> - ["Test standard ipv6 address"]; -ipv6_hostname(_SocketType, _Port, suite)-> - []; -ipv6_hostname(SocketType, Port, Config) when is_list(Config) -> - tsp("ipv6_hostname -> entry with" - "~n SocketType: ~p" - "~n Port: ~p" - "~n Config: ~p", [SocketType, Port, Config]), - Host = ?config(host, Config), - URI = "GET HTTP://" ++ - Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n", - tsp("ipv6_hostname -> Host: ~p", [Host]), - httpd_test_lib:verify_request(SocketType, Host, Port, [inet6], - node(), - URI, - [{statuscode, 200}, {version, "HTTP/1.1"}]), - ok. - -%%------------------------------------------------------------------------- - -ipv6_address_ipcomm() -> - [{require, ipv6_hosts}]. -ipv6_address_ipcomm(X) -> - SocketType = ip_comm, - Port = ?IP_PORT, - ipv6_address(SocketType, Port, X). - -ipv6_address_essl() -> - [{require, ipv6_hosts}]. -ipv6_address_essl(X) -> - SocketType = essl, - Port = ?SSL_PORT, - ipv6_address(SocketType, Port, X). - -ipv6_address(_SocketType, _Port, doc) -> - ["Test standard ipv6 address"]; -ipv6_address(_SocketType, _Port, suite)-> - []; -ipv6_address(SocketType, Port, Config) when is_list(Config) -> - tsp("ipv6_address -> entry with" - "~n SocketType: ~p" - "~n Port: ~p" - "~n Config: ~p", [SocketType, Port, Config]), - Host = ?config(host, Config), - tsp("ipv6_address -> Host: ~p", [Host]), - URI = "GET HTTP://" ++ - Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n", - httpd_test_lib:verify_request(SocketType, Host, Port, [inet6], - node(), - URI, - [{statuscode, 200}, {version, "HTTP/1.1"}]), - ok. - - -%%-------------------------------------------------------------------- -ticket_5775(doc) -> - ["Tests that content-length is correct"]; -ticket_5775(suite) -> - []; -ticket_5775(Config) -> - ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config), - ?IP_PORT, ?config(node, Config), - "GET /cgi-bin/erl/httpd_example:get_bin " - "HTTP/1.0\r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/1.0"}]), - ok. -ticket_5865(doc) -> - ["Tests that a header without last-modified is handled"]; -ticket_5865(suite) -> - []; -ticket_5865(Config) -> - ?SKIP(as_of_r15_behaviour_of_calendar_has_changed), - Host = ?config(host,Config), - ServerRoot = ?config(server_root, Config), - DocRoot = filename:join([ServerRoot, "htdocs"]), - File = filename:join([DocRoot,"last_modified.html"]), - - Bad_mtime = case test_server:os_type() of - {win32, _} -> - {{1600,12,31},{23,59,59}}; - {unix, _} -> - {{1969,12,31},{23,59,59}} - end, + %% Check "ScriptNoCache" directive (default: false) + ok = http_status("GET /cgi-bin/" ++ Script ++ " ", Config, + [{statuscode, 200}, + {no_header, "cache-control"}]). + +alias() -> + [{doc, "Test mod_alias"}]. + +alias(Config) when is_list(Config) -> + ok = http_status("GET /pics/icon.sheet.gif ", Config, + [{statuscode, 200}, + {header, "Content-Type","image/gif"}, + {header, "Server"}, + {header, "Date"}]), - {ok,FI}=file:read_file_info(File), + ok = http_status("GET / ", Config, + [{statuscode, 200}, + {header, "Content-Type","text/html"}, + {header, "Server"}, + {header, "Date"}]), - case file:write_file_info(File,FI#file_info{mtime=Bad_mtime}) of - ok -> - ok = httpd_test_lib:verify_request(ip_comm, Host, - ?IP_PORT, ?config(node, Config), - "GET /last_modified.html" - " HTTP/1.1\r\nHost:" - ++Host++"\r\n\r\n", - [{statuscode, 200}, - {no_header, - "last-modified"}]), - ok; - {error, Reason} -> - Fault = - io_lib:format("Attempt to change the file info to set the" - " preconditions of the test case failed ~p~n", - [Reason]), - {skip, Fault} - end. - -ticket_5913(doc) -> - ["Tests that a header without last-modified is handled"]; -ticket_5913(suite) -> []; -ticket_5913(Config) -> - ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), - ?IP_PORT, ?config(node, Config), - "GET /cgi-bin/erl/httpd_example:get_bin " - "HTTP/1.0\r\n\r\n", - [{statuscode, 200}, - {version, "HTTP/1.0"}]), - ok. + ok = http_status("GET /misc/ ", Config, + [{statuscode, 200}, + {header, "Content-Type","text/html"}, + {header, "Server"}, + {header, "Date"}]), + + %% Check redirection if trailing slash is missing. + ok = http_status("GET /misc ", Config, + [{statuscode, 301}, + {header, "Location"}, + {header, "Content-Type","text/html"}]). + + +%% auth_api() -> +%% [{doc, "Test mod_auth API"}]. + +%% auth_api(Config) when is_list(Config) -> +%% Version = ?config(http_version, Config), +%% Host = ?config(host, Config), +%% ok = http_status("GET / ", Config, +%% [{statuscode, 200}]), +%% ok = auth_status(auth_request("/", "one", "WrongPassword", Version, Host), Config, +%% [{statuscode, 200}]), + +%% %% Make sure Authenticate header is received even the second time +%% %% we try a incorrect password! Otherwise a browser client will hang! +%% ok = auth_status(auth_request("/" ++ AuthStoreType ++ "open/", +%% "dummy", "WrongPassword", Host), Config, +%% [{statuscode, 401}, +%% {header, "WWW-Authenticate"}]), +%% ok = auth_status(auth_request("/" ++ AuthStoreType ++ "open/", "dummy", "WrongPassword", +%% Host), Config, [{statuscode, 401}, +%% {header, "WWW-Authenticate"}]), + +%% %% Change the password to DummyPassword then try to add a user +%% %% Get an error and set it to NoPassword +%% ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "open", "NoPassword", "DummyPassword"), +%% {error,bad_password} = +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one", +%% "onePassword", []), +%% ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++"open", +%% "DummyPassword", "NoPassword"), + +%% %% Test /*open, require user one Aladdin +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "open"), -ticket_6003(doc) -> - ["Tests that a URI with a bad hexadecimal code is handled"]; -ticket_6003(suite) -> []; -ticket_6003(Config) -> - ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), - ?IP_PORT, ?config(node, Config), - "GET http://www.erlang.org/%skalle " - "HTTP/1.0\r\n\r\n", - [{statuscode, 400}, - {version, "HTTP/1.0"}]), - ok. +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/", +%% "one", "onePassword", [{statuscode, 401}]), + +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/", +%% "two", "twoPassword", [{statuscode, 401}]), + +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/", +%% "Aladdin", "onePassword", [{statuscode, 401}]), + +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one", +%% "onePassword", []), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "two", +%% "twoPassword", []), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "Aladdin", +%% "AladdinPassword", []), + +%% {ok, [_|_]} = list_users(Node, ServerRoot, Host, Port, +%% AuthStoreType++"open"), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/", +%% "one", "WrongPassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/", +%% "one", "onePassword", [{statuscode, 200}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/", +%% "two", "twoPassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/", +%% "Aladdin", "WrongPassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/", +%% "Aladdin", "AladdinPassword", [{statuscode, 200}]), + +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"open"), +%% {ok, []} = list_users(Node, ServerRoot, Host, Port, +%% AuthStoreType++"open"), + +%% %% Phase 2 +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"secret"), +%% {ok, []} = list_users(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "secret"), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "one", "onePassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "two", "twoPassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "secret/", +%% "three", "threePassword", [{statuscode, 401}]), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret", "one", +%% "onePassword", +%% []), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret", +%% "two", "twoPassword", []), +%% add_user(Node, ServerRoot, Port, AuthStoreType++"secret", "Aladdin", +%% "AladdinPassword",[]), +%% add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret", +%% "one", "group1"), +%% add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret", +%% "two", "group1"), +%% add_group_member(Node, ServerRoot, Port, AuthStoreType ++ +%% "secret", "Aladdin", "group2"), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "one", "onePassword", [{statuscode, 200}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "two", "twoPassword", [{statuscode, 200}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "Aladdin", "AladdinPassword", [{statuscode, 200}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/", +%% "three", "threePassword", [{statuscode, 401}]), +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"), +%% {ok, []} = list_users(Node, ServerRoot, Host, Port, +%% AuthStoreType ++ "secret"), +%% remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"), +%% Directory = filename:join([ServerRoot, "htdocs", AuthStoreType ++ +%% "secret"]), +%% {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory), + +%% %% Phase 3 +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "secret/top_secret"), +%% remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "secret/top_secret"), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ +%% "secret/top_secret/", +%% "three", "threePassword", [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ +%% "secret/top_secret/", "two", "twoPassword", +%% [{statuscode, 401}]), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ +%% "secret/top_secret","three", +%% "threePassword",[]), +%% add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret/top_secret", +%% "two","twoPassword", []), +%% add_group_member(Node, ServerRoot, Port, AuthStoreType ++ +%% "secret/top_secret", +%% "three", "group3"), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ +%% "secret/top_secret/", "three", "threePassword", +%% [{statuscode, 200}]), +%% auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ +%% "secret/top_secret/", "two", "twoPassword", +%% [{statuscode, 401}]), +%% add_group_member(Node, ServerRoot, Port, AuthStoreType ++ +%% "secret/top_secret", +%% "two", "group3"), +%% auth_request(Type,Host,Port,Node,"/" ++ AuthStoreType ++ +%% "secret/top_secret/", +%% "two", "twoPassword", [{statuscode, 200}]), +%% remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "secret/top_secret"), +%% {ok, []} = list_users(Node, ServerRoot, Host, Port, +%% AuthStoreType ++ "secret/top_secret"), +%% remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++ +%% "secret/top_secret"), +%% Directory2 = filename:join([ServerRoot, "htdocs", +%% AuthStoreType ++ "secret/top_secret"]), +%% {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory2), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ +%% "secret/top_secret/", "two", "twoPassword", +%% [{statuscode, 401}]), +%% auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ +%% "secret/top_secret/","three", "threePassword", +%% [{statuscode, 401}]). -ticket_7304(doc) -> - ["Tests missing CR in delimiter"]; -ticket_7304(suite) -> - []; -ticket_7304(Config) -> - ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), - ?IP_PORT, ?config(node, Config), - "GET / HTTP/1.0\r\n\n", - [{statuscode, 200}, - {version, "HTTP/1.0"}]), - ok. %%-------------------------------------------------------------------- -%% Internal functions +%% Internal functions ----------------------------------- %%-------------------------------------------------------------------- -dos_hostname(Type, Port, Host, Node, Max) -> - H1 = {"", 200}, - H2 = {"dummy-host.ericsson.se", 200}, - TooLongHeader = lists:append(lists:duplicate(Max + 1, "a")), - H3 = {TooLongHeader, 403}, - Hosts = [H1,H2,H3], - dos_hostname_poll(Type, Host, Port, Node, Hosts). - -%% make_ipv6(T) when is_tuple(T) andalso (size(T) =:= 8) -> -%% make_ipv6(tuple_to_list(T)); - -%% make_ipv6([_, _, _, _, _, _, _, _] = IPV6) -> -%% lists:flatten(io_lib:format("~s:~s:~s:~s:~s:~s:~s:~s", IPV6)). - +setup_server_dirs(ServerRoot, DocRoot, DataDir) -> + CgiDir = filename:join(ServerRoot, "cgi-bin"), + AuthDir = filename:join(ServerRoot, "auth"), + PicsDir = filename:join(ServerRoot, "icons"), -%%-------------------------------------------------------------------- -%% Other help functions -create_config(Config, Access, FileName) -> - ServerRoot = ?config(server_root, Config), - TcTopDir = ?config(tc_top_dir, Config), - Port = ?config(port, Config), - Type = ?config(sock_type, Config), - Host = ?config(host, Config), - Mods = io_lib:format("~p", [httpd_mod]), - Funcs = io_lib:format("~p", [ssl_password_cb]), - MaxHdrSz = io_lib:format("~p", [256]), - MaxHdrAct = io_lib:format("~p", [close]), - - io:format(user, - "create_config -> " - "~n ServerRoot: ~p" - "~n TcTopDir: ~p" - "~n Type: ~p" - "~n Port: ~p" - "~n Host: ~p" - "~n", [ServerRoot, TcTopDir, Type, Port, Host]), - - SSL = - if - (Type =:= ssl) orelse - (Type =:= essl) -> - [cline(["SSLCertificateFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLCertificateKeyFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLCACertificateFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLPasswordCallbackModule ", Mods]), - cline(["SSLPasswordCallbackFunction ", Funcs]), - cline(["SSLVerifyClient 0"]), - cline(["SSLVerifyDepth 1"])]; - true -> - [] - end, - ModOrder = - case Access of - mod_htaccess -> - "Modules mod_alias mod_htaccess mod_auth " - "mod_security " - "mod_responsecontrol mod_trace mod_esi " - "mod_actions mod_cgi mod_include mod_dir " - "mod_range mod_get " - "mod_head mod_log mod_disk_log"; - _ -> - "Modules mod_alias mod_auth mod_security " - "mod_responsecontrol mod_trace mod_esi " - "mod_actions mod_cgi mod_include mod_dir " - "mod_range mod_get " - "mod_head mod_log mod_disk_log" - end, + ok = file:make_dir(ServerRoot), + ok = file:make_dir(DocRoot), + ok = file:make_dir(CgiDir), + ok = file:make_dir(AuthDir), + ok = file:make_dir(PicsDir), + + DocSrc = filename:join(DataDir, "server_root/htdocs"), + AuthSrc = filename:join(DataDir, "server_root/auth"), + CgiSrc = filename:join(DataDir, "server_root/cgi-bin"), + PicsSrc = filename:join(DataDir, "server_root/icons"), - %% The test suite currently does not handle an explicit BindAddress. - %% They assume any has been used, that is Addr is always set to undefined! - - %% {ok, Hostname} = inet:gethostname(), - %% {ok, Addr} = inet:getaddr(Hostname, inet6), - %% AddrStr = make_ipv6(Addr), - %% BindAddress = lists:flatten(io_lib:format("~s|inet6", [AddrStr])), - - BindAddress = "*|inet", - %% BindAddress = "*", - - HttpConfig = [ - cline(["Port ", integer_to_list(Port)]), - cline(["ServerName ", Host]), - cline(["SocketType ", atom_to_list(Type)]), - cline([ModOrder]), - %% cline(["LogFormat ", "erlang"]), - cline(["ServerAdmin [email protected]"]), - cline(["BindAddress ", BindAddress]), - cline(["ServerRoot ", ServerRoot]), - cline(["ErrorLog ", TcTopDir, - "/logs/error_log_", integer_to_list(Port)]), - cline(["TransferLog ", TcTopDir, - "/logs/access_log_", integer_to_list(Port)]), - cline(["SecurityLog ", TcTopDir, - "/logs/security_log_", integer_to_list(Port)]), - cline(["ErrorDiskLog ", TcTopDir, - "/logs/error_disk_log_", integer_to_list(Port)]), - cline(["ErrorDiskLogSize ", "190000 ", "11"]), - cline(["TransferDiskLog ", TcTopDir, - "/logs/access_disk_log_", integer_to_list(Port)]), - cline(["TransferDiskLogSize ", "200000 ", "10"]), - cline(["SecurityDiskLog ", TcTopDir, - "/logs/security_disk_log_", integer_to_list(Port)]), - cline(["SecurityDiskLogSize ", "210000 ", "9"]), - cline(["MaxClients 10"]), - cline(["MaxHeaderSize ", MaxHdrSz]), - cline(["MaxHeaderAction ", MaxHdrAct]), - cline(["DocumentRoot ", - filename:join(ServerRoot, "htdocs")]), - cline(["DirectoryIndex ", "index.html ", "welcome.html"]), - cline(["DefaultType ", "text/plain"]), - SSL, - mod_alias_config(ServerRoot), - - config_directory(filename:join([ServerRoot,"htdocs", - "open"]), - "Open Area", - filename:join(ServerRoot, "auth/passwd"), - filename:join(ServerRoot, "auth/group"), - plain, - "user one Aladdin", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join([ServerRoot,"htdocs", - "secret"]), - "Secret Area", - filename:join(ServerRoot, "auth/passwd"), - filename:join(ServerRoot, "auth/group"), - plain, - "group group1 group2", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join([ServerRoot,"htdocs", - "secret", - "top_secret"]), - "Top Secret Area", - filename:join(ServerRoot, "auth/passwd"), - filename:join(ServerRoot, "auth/group"), - plain, - "group group3", - filename:join(ServerRoot, "security_data")), - - config_directory(filename:join([ServerRoot,"htdocs", - "dets_open"]), - "Dets Open Area", - filename:join(ServerRoot, "passwd"), - filename:join(ServerRoot, "group"), - dets, - "user one Aladdin", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join([ServerRoot,"htdocs", - "dets_secret"]), - "Dets Secret Area", - filename:join(ServerRoot, "passwd"), - filename:join(ServerRoot, "group"), - dets, - "group group1 group2", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join([ServerRoot,"htdocs", - "dets_secret", - "top_secret"]), - "Dets Top Secret Area", - filename:join(ServerRoot, "passwd"), - filename:join(ServerRoot, "group"), - dets, - "group group3", - filename:join(ServerRoot, "security_data")), - - config_directory(filename:join([ServerRoot,"htdocs", - "mnesia_open"]), - "Mnesia Open Area", - false, - false, - mnesia, - "user one Aladdin", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join([ServerRoot,"htdocs", - "mnesia_secret"]), - "Mnesia Secret Area", - false, - false, - mnesia, - "group group1 group2", - filename:join(ServerRoot, "security_data")), - config_directory(filename:join( - [ServerRoot, "htdocs", "mnesia_secret", - "top_secret"]), - "Mnesia Top Secret Area", - false, - false, - mnesia, - "group group3", - filename:join(ServerRoot, "security_data")) - ], - ConfigFile = filename:join([TcTopDir, FileName]), - {ok, Fd} = file:open(ConfigFile, [write]), - ok = file:write(Fd, lists:flatten(HttpConfig)), - ok = file:close(Fd). - -config_directory(Dir, AuthName, AuthUserFile, AuthGroupFile, AuthDBType, - Require, SF) -> - file:delete(SF), - [ - cline(["<Directory ", Dir, ">"]), - cline(["SecurityDataFile ", SF]), - cline(["SecurityMaxRetries 3"]), - cline(["SecurityFailExpireTime ", integer_to_list(?FAIL_EXPIRE_TIME)]), - cline(["SecurityBlockTime 1"]), - cline(["SecurityAuthTimeout ", integer_to_list(?AUTH_TIMEOUT)]), - cline(["SecurityCallbackModule ", "httpd_mod"]), - cline_if_set("AuthUserFile", AuthUserFile), - cline_if_set("AuthGroupFile", AuthGroupFile), - cline_if_set("AuthName", AuthName), - cline_if_set("AuthDBType", AuthDBType), - cline(["require ", Require]), - cline(["</Directory>\r\n"]) - ]. - -mod_alias_config(Root) -> - [ - cline(["Alias /icons/ ", filename:join(Root,"icons"), "/"]), - cline(["Alias /pics/ ", filename:join(Root, "icons"), "/"]), - cline(["ScriptAlias /cgi-bin/ ", filename:join(Root, "cgi-bin"), "/"]), - cline(["ScriptAlias /htbin/ ", filename:join(Root, "cgi-bin"), "/"]), - cline(["ErlScriptAlias /cgi-bin/erl httpd_example io"]), - cline(["EvalScriptAlias /eval httpd_example io"]) - ]. - -cline(List) -> - lists:flatten([List, "\r\n"]). + inets_test_lib:copy_dirs(DocSrc, DocRoot), + inets_test_lib:copy_dirs(AuthSrc, AuthDir), + inets_test_lib:copy_dirs(CgiSrc, CgiDir), + inets_test_lib:copy_dirs(PicsSrc, PicsDir), + + Cgi = case test_server:os_type() of + {win32, _} -> + "cgi_echo.exe"; + _ -> + "cgi_echo" + end, + + inets_test_lib:copy_file(Cgi, DataDir, CgiDir), + AbsCgi = filename:join([CgiDir, Cgi]), + {ok, FileInfo} = file:read_file_info(AbsCgi), + ok = file:write_file_info(AbsCgi, FileInfo#file_info{mode = 8#00755}), + + EnvCGI = filename:join([ServerRoot, "cgi-bin", "printenv.sh"]), + {ok, FileInfo1} = file:read_file_info(EnvCGI), + ok = file:write_file_info(EnvCGI, + FileInfo1#file_info{mode = 8#00755}). + +start_apps(https) -> + inets_test_lib:start_apps([crypto, public_key, ssl]); +start_apps(_) -> + ok. -cline_if_set(_, false) -> - []; -cline_if_set(Name, Var) when is_list(Var) -> - cline([Name, " ", Var]); -cline_if_set(Name, Var) when is_atom(Var) -> - cline([Name, " ", atom_to_list(Var)]). +server_start(_, HttpdConfig) -> + {ok, Pid} = inets:start(httpd, HttpdConfig), + Serv = inets:services_info(), + {value, {_, _, Info}} = lists:keysearch(Pid, 2, Serv), + {Pid, proplists:get_value(port, Info)}. -getaddr() -> - {ok,HostName} = inet:gethostname(), - {ok,{A1,A2,A3,A4}} = inet:getaddr(HostName,inet), - lists:flatten(io_lib:format("~p.~p.~p.~p",[A1,A2,A3,A4])). +server_config(http, Config) -> + ServerRoot = ?config(server_root, Config), + [{port, 0}, + {server_name,"httpd_test"}, + {server_root, ServerRoot}, + {document_root, ?config(doc_root, Config)}, + {bind_address, any}, + {ipfamily, inet}, + {max_header_size, 256}, + {max_header_action, close}, + {mime_types, [{"html","text/html"},{"htm","text/html"}, {"shtml","text/html"}, + {"gif", "image/gif"}]}, + {alias, {"/icons/", filename:join(ServerRoot,"icons") ++ "/"}}, + {alias, {"/pics/", filename:join(ServerRoot,"icons") ++ "/"}}, + {script_alias, {"/cgi-bin/", filename:join(ServerRoot, "cgi-bin") ++ "/"}}, + {script_alias, {"/htbin/", filename:join(ServerRoot, "cgi-bin") ++ "/"}}, + {erl_script_alias, {"/cgi-bin/erl", [httpd_example, io]}}, + {eval_script_alias, {"/eval", [httpd_example, io]}} + ] ++ auth_conf(ServerRoot); +server_config(_, _) -> + []. + +http_request(Request, "HTTP/1.1" = Version, Host, {Headers, Body}) -> + Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n" ++ Headers ++ "\r\n" ++ Body; +http_request(Request, Version, _, {Headers, Body}) -> + Request ++ Version ++ "\r\n" ++ Headers ++ "\r\n" ++ Body. + +http_request(Request, "HTTP/1.1" = Version, Host) -> + Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n\r\n"; +http_request(Request, Version, _) -> + Request ++ Version ++ "\r\n\r\n". + +auth_request(Path, User, Passwd, "HTTP/1.1" = Version, Host) -> + "GET " ++ Path ++ " " ++ Version ++ "\r\nhost:" ++ Host ++ + "\r\nAuthorization: Basic " ++ + base64:encode_to_string(User++":"++Passwd) ++ + "\r\n\r\n"; +auth_request(Path, User, Passwd, Version, _Host) -> + "GET " ++ Path ++ " " ++ Version ++ + "\r\nAuthorization: Basic " ++ + base64:encode_to_string(User++":"++Passwd) ++ + "\r\n\r\n". + +head_status("HTTP/0.9") -> + 501; %% Not implemented in HTTP/0.9 +head_status(_) -> + 200. + +auth_conf(Root) -> + [{directory, {filename:join(Root, "htdocs/open"), + [{auth_type, plain}, + {auth_name, "Open Area"}, + {auth_user_file, filename:join(Root, "auth/passwd")}, + {auth_group_file, filename:join(Root, "auth/group")}, + {require_user, ["one", "Aladdin"]}]}}, + {directory, {filename:join(Root, "htdocs/secret"), + [{auth_type, plain}, + {auth_name, "Secret Area"}, + {auth_user_file, filename:join(Root, "auth/passwd")}, + {auth_group_file, filename:join(Root, "auth/group")}, + {require_group, ["group1", "group2"]}]}}, + {directory, {filename:join(Root, "htdocs/secret/top_secret"), + [{auth_type, plain}, + {auth_name, "Top Secret Area"}, + {auth_user_file, filename:join(Root, "auth/passwd")}, + {auth_group_file, filename:join(Root, "auth/group")}, + {require_group, ["group3"]}]}}, + {directory, {filename:join(Root, "htdocs/open"), + [{auth_type, mnesia}, + {auth_name, "Open Area"}, + {auth_user_file, filename:join(Root, "auth/passwd")}, + {auth_group_file, filename:join(Root, "auth/group")}, + {require_user, ["one", "Aladdin"]}]}}, + {directory, {filename:join(Root, "htdocs/secret"), + [{auth_type, mnesia}, + {auth_name, "Secret Area"}, + {auth_user_file, filename:join(Root, "auth/passwd")}, + {auth_group_file, filename:join(Root, "auth/group")}, + {require_group, ["group1", "group2"]}]}} + ]. + + +http_status(Request, Config, Expected) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request(Request, Version, Host), + Expected ++ [{version, Version}]). + +http_status(Request, HeadersAndBody, Config, Expected) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + http_request(Request, Version, Host, HeadersAndBody), + Expected ++ [{version, Version}]). + +auth_status(AuthRequest, Config, Expected) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + httpd_test_lib:verify_request(?config(type, Config), Host, + ?config(port, Config), ?config(node, Config), + AuthRequest, + Expected ++ [{version, Version}]). + +basic_auth_requiered(Config) -> + ok = http_status("GET /open/ ", Config, [{statuscode, 401}, + {header, "WWW-Authenticate"}]), + ok = http_status("GET /secret/ ", Config, [{statuscode, 401}, + {header, "WWW-Authenticate"}]), + ok = http_status("GET /secret/top_secret/ ", Config, [{statuscode, 401}, + {header, "WWW-Authenticate"}]). start_mnesia(Node) -> case rpc:call(Node, ?MODULE, cleanup_mnesia, []) of ok -> ok; Other -> - tsf({failed_to_cleanup_mnesia, Other}) + ct:fail({failed_to_cleanup_mnesia, Other}) end, case rpc:call(Node, ?MODULE, setup_mnesia, []) of {atomic, ok} -> ok; Other2 -> - tsf({failed_to_setup_mnesia, Other2}) + ct:fail({failed_to_setup_mnesia, Other2}) end, ok. @@ -2259,196 +791,3 @@ cleanup_mnesia() -> stopped = mnesia:stop(), mnesia:delete_schema([node()]), ok. - -create_htaccess_data(Path, IpAddress)-> - create_htaccess_dirs(Path), - - create_html_file(filename:join([Path,"ht/open/dummy.html"])), - create_html_file(filename:join([Path,"ht/blocknet/dummy.html"])), - create_html_file(filename:join([Path,"ht/secret/dummy.html"])), - create_html_file(filename:join([Path,"ht/secret/top_secret/dummy.html"])), - - create_htaccess_file(filename:join([Path,"ht/open/.htaccess"]), - Path, "user one Aladdin"), - create_htaccess_file(filename:join([Path,"ht/secret/.htaccess"]), - Path, "group group1 group2"), - create_htaccess_file(filename:join([Path, - "ht/secret/top_secret/.htaccess"]), - Path, "user four"), - create_htaccess_file(filename:join([Path,"ht/blocknet/.htaccess"]), - Path, nouser, IpAddress), - - create_user_group_file(filename:join([Path,"ht","users.file"]), - "one:OnePassword\ntwo:TwoPassword\nthree:" - "ThreePassword\nfour:FourPassword\nAladdin:" - "AladdinPassword"), - create_user_group_file(filename:join([Path,"ht","groups.file"]), - "group1: two one\ngroup2: two three"). - -create_html_file(PathAndFileName)-> - file:write_file(PathAndFileName,list_to_binary( - "<html><head><title>test</title></head> - <body>testar</body></html>")). - -create_htaccess_file(PathAndFileName, BaseDir, RequireData)-> - file:write_file(PathAndFileName, - list_to_binary( - "AuthUserFile "++ BaseDir ++ - "/ht/users.file\nAuthGroupFile "++ BaseDir - ++ "/ht/groups.file\nAuthName Test\nAuthType" - " Basic\n<Limit>\nrequire " ++ RequireData ++ - "\n</Limit>")). - -create_htaccess_file(PathAndFileName, BaseDir, nouser, IpAddress)-> - file:write_file(PathAndFileName,list_to_binary( - "AuthUserFile "++ BaseDir ++ - "/ht/users.file\nAuthGroupFile " ++ - BaseDir ++ "/ht/groups.file\nAuthName" - " Test\nAuthType" - " Basic\n<Limit GET>\n\tallow from " ++ - format_ip(IpAddress, - string:rchr(IpAddress,$.)) ++ - "\n</Limit>")). - -create_user_group_file(PathAndFileName, Data)-> - file:write_file(PathAndFileName, list_to_binary(Data)). - -create_htaccess_dirs(Path)-> - ok = file:make_dir(filename:join([Path,"ht"])), - ok = file:make_dir(filename:join([Path,"ht/open"])), - ok = file:make_dir(filename:join([Path,"ht/blocknet"])), - ok = file:make_dir(filename:join([Path,"ht/secret"])), - ok = file:make_dir(filename:join([Path,"ht/secret/top_secret"])). - -remove_htaccess_dirs(Path)-> - file:del_dir(filename:join([Path,"ht/secret/top_secret"])), - file:del_dir(filename:join([Path,"ht/secret"])), - file:del_dir(filename:join([Path,"ht/blocknet"])), - file:del_dir(filename:join([Path,"ht/open"])), - file:del_dir(filename:join([Path,"ht"])). - -format_ip(IpAddress,Pos)when Pos > 0-> - case lists:nth(Pos,IpAddress) of - $.-> - case lists:nth(Pos-2,IpAddress) of - $.-> - format_ip(IpAddress,Pos-3); - _-> - lists:sublist(IpAddress,Pos-2) ++ "." - end; - _ -> - format_ip(IpAddress,Pos-1) - end; - -format_ip(IpAddress, _Pos)-> - "1" ++ IpAddress. - -remove_htaccess(Path)-> - file:delete(filename:join([Path,"ht/open/dummy.html"])), - file:delete(filename:join([Path,"ht/secret/dummy.html"])), - file:delete(filename:join([Path,"ht/secret/top_secret/dummy.html"])), - file:delete(filename:join([Path,"ht/blocknet/dummy.html"])), - file:delete(filename:join([Path,"ht/blocknet/.htaccess"])), - file:delete(filename:join([Path,"ht/open/.htaccess"])), - file:delete(filename:join([Path,"ht/secret/.htaccess"])), - file:delete(filename:join([Path,"ht/secret/top_secret/.htaccess"])), - file:delete(filename:join([Path,"ht","users.file"])), - file:delete(filename:join([Path,"ht","groups.file"])), - remove_htaccess_dirs(Path). - - -dos_hostname_poll(Type, Host, Port, Node, Hosts) -> - [dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) - || {Host1,Code} <- Hosts]. - -dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) -> - ok = httpd_test_lib:verify_request(Type, Host, Port, Node, - dos_hostname_request(Host1), - [{statuscode, Code}, - {version, "HTTP/1.0"}]). - -dos_hostname_request(Host) -> - "GET / HTTP/1.0\r\n" ++ Host ++ "\r\n\r\n". - -get_nof_clients(Mode, Load) -> - get_nof_clients(test_server:os_type(), Mode, Load). - -get_nof_clients(_, ip_comm, light) -> 5; -get_nof_clients(_, ssl, light) -> 2; -get_nof_clients(_, ip_comm, medium) -> 10; -get_nof_clients(_, ssl, medium) -> 4; -get_nof_clients(_, ip_comm, heavy) -> 20; -get_nof_clients(_, ssl, heavy) -> 6. - -%% Make a file 100 bytes long containing 012...9*10 -create_range_data(Path) -> - PathAndFileName=filename:join([Path,"range.txt"]), - file:write_file(PathAndFileName,list_to_binary(["12345678901234567890", - "12345678901234567890", - "12345678901234567890", - "12345678901234567890", - "12345678901234567890"])). - -create_ipv6_config(Config, FileName, Ipv6Address) -> - ServerRoot = ?config(server_root, Config), - TcTopDir = ?config(tc_top_dir, Config), - Port = ?config(port, Config), - SockType = ?config(sock_type, Config), - Mods = io_lib:format("~p", [httpd_mod]), - Funcs = io_lib:format("~p", [ssl_password_cb]), - Host = ?config(ipv6_host, Config), - - MaxHdrSz = io_lib:format("~p", [256]), - MaxHdrAct = io_lib:format("~p", [close]), - - Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi" - " mod_include mod_dir mod_get mod_head" - " mod_log mod_disk_log mod_trace", - - SSL = - if - (SockType =:= ssl) orelse - (SockType =:= essl) -> - [cline(["SSLCertificateFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLCertificateKeyFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLCACertificateFile ", - filename:join(ServerRoot, "ssl/ssl_server.pem")]), - cline(["SSLPasswordCallbackModule ", Mods]), - cline(["SSLPasswordCallbackFunction ", Funcs]), - cline(["SSLVerifyClient 0"]), - cline(["SSLVerifyDepth 1"])]; - true -> - [] - end, - - BindAddress = "[" ++ Ipv6Address ++"]|inet6", - - HttpConfig = - [cline(["BindAddress ", BindAddress]), - cline(["Port ", integer_to_list(Port)]), - cline(["ServerName ", Host]), - cline(["SocketType ", atom_to_list(SockType)]), - cline([Mod_order]), - cline(["ServerRoot ", ServerRoot]), - cline(["DocumentRoot ", filename:join(ServerRoot, "htdocs")]), - cline(["MaxHeaderSize ",MaxHdrSz]), - cline(["MaxHeaderAction ",MaxHdrAct]), - cline(["DirectoryIndex ", "index.html "]), - cline(["DefaultType ", "text/plain"]), - SSL], - ConfigFile = filename:join([TcTopDir,FileName]), - {ok, Fd} = file:open(ConfigFile, [write]), - ok = file:write(Fd, lists:flatten(HttpConfig)), - ok = file:close(Fd). - - -tsp(F) -> - inets_test_lib:tsp("[~w]" ++ F, [?MODULE]). -tsp(F, A) -> - inets_test_lib:tsp("[~w]" ++ F, [?MODULE|A]). - -tsf(Reason) -> - inets_test_lib:tsf(Reason). - diff --git a/lib/inets/test/httpd_all.erl b/lib/inets/test/httpd_all.erl new file mode 100644 index 0000000000..9be02e3fd8 --- /dev/null +++ b/lib/inets/test/httpd_all.erl @@ -0,0 +1,240 @@ +alias(Version, Type, Port, Host, Node) -> + Opts = [], + ok = httpd_test_lib:verify_request(Type, Host, Port, Opts, Node, + "GET /pics/icon.sheet.gif " + ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {header, "Content-Type","image/gif"}, + {header, "Server"}, + {header, "Date"}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Opts, Node, + "GET / " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {header, "Content-Type","text/html"}, + {header, "Server"}, + {header, "Date"}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Opts, Node, + "GET /misc/ " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {header, "Content-Type","text/html"}, + {header, "Server"}, + {header, "Date"}, + {version, Version}]), + + %% Check redirection if trailing slash is missing. + ok = httpd_test_lib:verify_request(Type, Host, Port, Opts, Node, + "GET /misc "++ Version ++ "\r\n\r\n", + [{statuscode, 301}, + {header, "Location"}, + {header, "Content-Type","text/html"}, + {version, Version}]). + + +head(Version, Type, Port, Host, Node) -> + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "HEAD /index.html " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]). + + +get(Version, Type, Port, Host, Node) -> + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /index.html " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {header, "Content-Type", "text/html"}, + {header, "Date"}, + {header, "Server"}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /fsize.shtml " ++ Version ++ "\r\nHost:" + ++ Host ++ "\r\n\r\n", + [{statuscode, 200}, + {header, "Content-Type", "text/html"}, + {header, "Date"}, + {header, "Server"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /secret/dummy.html " + ++ Version ++ "\r\n\r\n", + [{statuscode, 401}, + {header, "WWW-Authenticate"}, + {version, Version}]). + +esi(Version, Type, Port, Host, Node) -> + %% Check "ErlScriptAlias" and "EvalScriptAlias" directives + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /eval?httpd_example:print(\"Hi!\") " + ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /eval?not_allowed:print(\"Hi!\") " + ++ Version ++ "\r\n\r\n", + [{statuscode, 403}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /eval?httpd_example:undef(\"Hi!\") " + ++ Version ++ "\r\n\r\n", + [{statuscode, 500}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example " + ++ Version ++ "\r\n\r\n", + [{statuscode, 400}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:get " + ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:" + "get?input=4711" + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:" + "post " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/not_allowed:post " + ++ Version ++ "\r\n\r\n", + [{statuscode, 403}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:undef " + ++ Version ++ "\r\n\r\n", + [{statuscode, 404}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example/yahoo " + ++ Version ++ "\r\n\r\n", + [{statuscode, 302}, + {version, Version}]), + %% Check "ErlScriptNoCache" directive (default: false) + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:get " + ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {no_header, "cache-control"}, + {version, "HTTP/1.0"}]). + +cgi(Version, Type, Port, Host, Node) -> + {Script, Script2, Script3} = + case test_server:os_type() of + {win32, _} -> + {"printenv.bat", "printenv.sh", "cgi_echo.exe"}; + _ -> + {"printenv.sh", "printenv.bat", "cgi_echo"} + end, + + %% The length (> 100) is intentional + ok = httpd_test_lib: + verify_request(Type, Host, Port, Node, + "POST /cgi-bin/" ++ Script3 ++ + Version ++ " \r\n" + "Content-Length:100 \r\n\r\n " + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + " \r\n\r\n", + [{statuscode, 200}, + {version, Version}, + {header, "content-type", "text/plain"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/"++ Script ++ + " " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/not_there " ++ + Version ++ "\r\n\r\n", + [{statuscode, 404},{statuscode, 500}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/"++ Script ++ + "?Nisse:kkk?sss/lll " ++ Version ++ "\r\n\r\n", + [{statuscode, 200}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "POST /cgi-bin/"++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /htbin/"++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /htbin/not_there " + "HTTP/1.0\r\n\r\n", + [{statuscode, 404},{statuscode, 500}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /htbin/"++ Script ++ + "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "POST /htbin/"++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "POST /htbin/"++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + %% Execute an existing, but bad CGI script.. + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "POST /htbin/"++ Script2 ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 404}, + {version, "HTTP/1.0"}]), + + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "POST /cgi-bin/"++ Script2 ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 404}, + {version, "HTTP/1.0"}]), + + %% Check "ScriptNoCache" directive (default: false) + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/" ++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {no_header, "cache-control"}, + {version, "HTTP/1.0"}]). + diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl index ac1bf43ff5..706d014bda 100644 --- a/lib/inets/test/httpd_block.erl +++ b/lib/inets/test/httpd_block.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% Copyright Ericsson AB 2005-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -19,8 +19,7 @@ %% -module(httpd_block). --include("test_server.hrl"). --include("test_server_line.hrl"). +-include_lib("common_test/include/ct.hrl"). %% General testcases bodies called from httpd_SUITE -export([block_disturbing_idle/4, block_non_disturbing_idle/4, @@ -88,7 +87,7 @@ block_503(Type, Port, Host, Node) -> block_disturbing_active(Type, Port, Host, Node) -> process_flag(trap_exit, true), Pid = long_poll(Type, Host, Port, Node, 200, 60000), - test_server:sleep(15000), + ct:sleep(15000), block_server(Node, Host, Port), await_suite_failed_process_exit(Pid, "poller", 60000, connection_closed), @@ -100,7 +99,7 @@ block_disturbing_active(Type, Port, Host, Node) -> block_non_disturbing_active(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 60000), - test_server:sleep(15000), + ct:sleep(15000), ok = block_nd_server(Node, Host, Port), await_normal_process_exit(Poller, "poller", 60000), blocked = get_admin_state(Node, Host, Port), @@ -111,7 +110,7 @@ block_non_disturbing_active(Type, Port, Host, Node) -> block_disturbing_active_timeout_not_released(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 60000), - test_server:sleep(15000), + ct:sleep(15000), Blocker = blocker(Node, Host, Port, 50000), await_normal_process_exit(Blocker, "blocker", 50000), await_normal_process_exit(Poller, "poller", 30000), @@ -123,7 +122,7 @@ block_disturbing_active_timeout_not_released(Type, Port, Host, Node) -> block_disturbing_active_timeout_released(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 40000), - test_server:sleep(5000), + ct:sleep(5000), Blocker = blocker(Node, Host, Port, 10000), await_normal_process_exit(Blocker, "blocker", 15000), await_suite_failed_process_exit(Poller, "poller", 40000, @@ -146,7 +145,7 @@ block_non_disturbing_active_timeout_not_released(Type, Port, Host, Node) -> block_non_disturbing_active_timeout_released(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 45000), - test_server:sleep(5000), + ct:sleep(5000), Blocker = blocker_nd(Node, Host, Port ,10000, {error,timeout}), await_normal_process_exit(Blocker, "blocker", 15000), await_normal_process_exit(Poller, "poller", 50000), @@ -157,9 +156,9 @@ block_non_disturbing_active_timeout_released(Type, Port, Host, Node) -> disturbing_blocker_dies(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 60000), - test_server:sleep(5000), + ct:sleep(5000), Blocker = blocker(Node, Host, Port, 10000), - test_server:sleep(5000), + ct:sleep(5000), exit(Blocker,simulate_blocker_crash), await_normal_process_exit(Poller, "poller", 60000), unblocked = get_admin_state(Node, Host, Port), @@ -170,9 +169,9 @@ disturbing_blocker_dies(Type, Port, Host, Node) -> non_disturbing_blocker_dies(Type, Port, Host, Node) -> process_flag(trap_exit, true), Poller = long_poll(Type, Host, Port, Node, 200, 60000), - test_server:sleep(5000), + ct:sleep(5000), Blocker = blocker_nd(Node, Host, Port, 10000, ok), - test_server:sleep(5000), + ct:sleep(5000), exit(Blocker, simulate_blocker_crash), await_normal_process_exit(Poller, "poller", 60000), unblocked = get_admin_state(Node, Host, Port), @@ -297,9 +296,12 @@ httpd_restart(Addr, Port) -> make_name(Addr, Port) -> httpd_util:make_name("httpd", Addr, Port). -get_admin_state(Node, _Host, Port) -> - Addr = undefined, - rpc:call(Node, httpd, get_admin_state, [Addr, Port]). +get_admin_state(_, _Host, Port) -> + Name = make_name(undefined, Port), + {status, _, _, StatusInfo} = sys:get_status(whereis(Name)), + [_, _,_, _, Prop] = StatusInfo, + State = state(Prop), + element(6, State). validate_admin_state(Node, Host, Port, Expect) -> io:format("try validating server admin state: ~p~n", [Expect]), @@ -323,15 +325,15 @@ await_normal_process_exit(Pid, Name, Timeout) -> io_lib:format("expected normal exit, " "unexpected exit of ~s process: ~p", [Name, Reason])), - test_server:fail(Err) + ct:fail(Err) after Timeout -> - test_server:fail("timeout while waiting for " ++ Name) + ct:fail("timeout while waiting for " ++ Name) end. await_suite_failed_process_exit(Pid, Name, Timeout, Why) -> receive - {'EXIT', Pid, {suite_failed, Why}} -> + {'EXIT', Pid, {test_failed, Why}} -> ok; {'EXIT', Pid, Reason} -> Err = @@ -339,9 +341,9 @@ await_suite_failed_process_exit(Pid, Name, Timeout, Why) -> io_lib:format("expected connection_closed, " "unexpected exit of ~s process: ~p", [Name, Reason])), - test_server:fail(Err) + ct:fail(Err) after Timeout -> - test_server:fail("timeout while waiting for " ++ Name) + ct:fail("timeout while waiting for " ++ Name) end. long_poll(Type, Host, Port, Node, StatusCode, Timeout) -> @@ -359,10 +361,13 @@ do_long_poll(Type, Host, Port, Node, StatusCode, Timeout) -> ok -> exit(normal); Reason -> - test_server:fail(Reason) + exit({test_failed, Reason}) end. - - - +state([{data,[{"State", State}]} | _]) -> + State; +state([{data,[{"StateData", State}]} | _]) -> + State; +state([_ | Rest]) -> + state(Rest). diff --git a/lib/inets/test/httpd_mod_SUITE.erl b/lib/inets/test/httpd_mod_SUITE.erl new file mode 100644 index 0000000000..d23cd22670 --- /dev/null +++ b/lib/inets/test/httpd_mod_SUITE.erl @@ -0,0 +1,76 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%% +%% ct:run("../inets_test", httpd_mod_SUITE). +-module(httpd_mod_SUITE). + +-include_lib("kernel/include/file.hrl"). +-include_lib("common_test/include/ct.hrl"). +-include("inets_test_lib.hrl"). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- +suite() -> + [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + {group, http}, + {group, https} + ]. + +groups() -> + [ + {http, [], all_version_groups()}, + {https, [], all_version_groups()} + {http_1_1, [], []}, + {http_1_0, [], []}, + {http_0_9, [], []}, + {mod_alias, [], []}, + {mod_actions, [], []}, + {mod_security, [], []}, + {mod_auth, [], []}, + {mod_htaccess, [], []}, + {mod_cgi, [], []}, + {mod_esi, [], []}, + {mod_head, [], []}, + {configure, [], []} + ]. + +all_version_groups ()-> + [ + {group, mod_alias}, + {group, mod_actions}, + {group, mod_security}, + {group, mod_auth}, + {group, mod_htaccess}, + {group, mod_cgi}, + {group, mod_esi}, + {group, mod_head} + ]. + +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl index 3e82324a30..6406eeae79 100644 --- a/lib/inets/test/httpd_test_lib.erl +++ b/lib/inets/test/httpd_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2013. All Rights Reserved. +%% Copyright Ericsson AB 2001-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -187,12 +187,12 @@ request(#state{mfa = {Module, Function, Args}, {tcp_closed, Socket} -> io:format("~p ~w[~w]request -> received (tcp) closed" "~n", [self(), ?MODULE, ?LINE]), - test_server:fail(connection_closed); + exit({test_failed, connection_closed}); {tcp_error, Socket, Reason} -> io:format("~p ~w[~w]request -> received (tcp) error" "~n Reason: ~p" "~n", [self(), ?MODULE, ?LINE, Reason]), - test_server:fail({tcp_error, Reason}); + ct:fail({tcp_error, Reason}); {ssl, Socket, Data} -> print(ssl, Data, State), case Module:Function([Data | Args]) of @@ -207,13 +207,13 @@ request(#state{mfa = {Module, Function, Args}, print(ssl, "closed", State), State#state{body = hd(Args)}; {ssl_closed, Socket} -> - test_server:fail(connection_closed); + exit({test_failed, connection_closed}); {ssl_error, Socket, Reason} -> - test_server:fail({ssl_error, Reason}) + ct:fail({ssl_error, Reason}) after TimeOut -> io:format("~p ~w[~w]request -> timeout" "~n", [self(), ?MODULE, ?LINE]), - test_server:fail(connection_timed_out) + ct:fail(connection_timed_out) end. handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body}, @@ -277,7 +277,7 @@ handle_http_body(Body, State = #state{headers = Headers, request(State#state{mfa = MFA}, 5000) end; false -> - test_server:fail(body_too_big) + ct:fail(body_too_big) end end. @@ -405,7 +405,7 @@ check_body(_, _, _, _,_) -> ok. print(Proto, Data, #state{print = true}) -> - test_server:format("Received ~p: ~p~n", [Proto, Data]); + ct:pal("Received ~p: ~p~n", [Proto, Data]); print(_, _, #state{print = false}) -> ok. diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl index 0ac940fd3e..12b85a816f 100644 --- a/lib/inets/test/inets_sup_SUITE.erl +++ b/lib/inets/test/inets_sup_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -21,7 +21,7 @@ -module(inets_sup_SUITE). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). + %% Note: This directive should only be used in test suites. -compile(export_all). @@ -297,13 +297,14 @@ httpd_subtree(Config) when is_list(Config) -> %% Check that we have the expected httpd instance children io:format("httpd_subtree -> verify httpd instance children " "(acceptor, misc and manager)~n", []), + {ok, _} = verify_child(Instance, httpd_connection_sup, supervisor), {ok, _} = verify_child(Instance, httpd_acceptor_sup, supervisor), {ok, _} = verify_child(Instance, httpd_misc_sup, supervisor), {ok, _} = verify_child(Instance, httpd_manager, worker), %% Check that the httpd instance acc supervisor has children io:format("httpd_subtree -> verify acc~n", []), - InstanceAcc = httpd_util:make_name("httpd_acc_sup", Addr, Port), + InstanceAcc = httpd_util:make_name("httpd_acceptor_sup", Addr, Port), case supervisor:which_children(InstanceAcc) of [_ | _] -> ok; diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index 6ccc7b0da1..4be9d9c8b3 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -287,7 +287,9 @@ print(F, A, Mod, Line) -> print("", F, A, Mod, Line). hostname() -> - from($@, atom_to_list(node())). + {ok, Name} = inet:gethostname(), + Name. + from(H, [H | T]) -> T; from(H, [_ | T]) -> from(H, T); from(_, []) -> []. @@ -545,14 +547,14 @@ tsp(F) -> tsp(F, []). tsp(F, A) -> Timestamp = formated_timestamp(), - test_server:format("*** ~s ~p ~p " ++ F ++ "~n", + ct:pal("*** ~s ~p ~p " ++ F ++ "~n", [Timestamp, node(), self() | A]). tsf(Reason) -> - test_server:fail(Reason). + ct:fail(Reason). tss(Time) -> - test_server:sleep(Time). + ct:sleep(Time). timestamp() -> http_util:timestamp(). diff --git a/lib/inets/test/old_httpd_SUITE.erl b/lib/inets/test/old_httpd_SUITE.erl new file mode 100644 index 0000000000..de9aa4562e --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE.erl @@ -0,0 +1,2445 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(old_httpd_SUITE). + +-include_lib("test_server/include/test_server.hrl"). +-include("test_server_line.hrl"). +-include("inets_test_lib.hrl"). + +-include_lib("kernel/include/file.hrl"). + +%% Test server specific exports +-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). +-export([init_per_testcase/2, end_per_testcase/2, + init_per_suite/1, end_per_suite/1]). + +%% Core Server tests +-export([ + ip_mod_alias/1, + ip_mod_actions/1, + ip_mod_security/1, + ip_mod_auth/1, + ip_mod_auth_api/1, + ip_mod_auth_mnesia_api/1, + ip_mod_htaccess/1, + ip_mod_cgi/1, + ip_mod_esi/1, + ip_mod_get/1, + ip_mod_head/1, + ip_mod_all/1, + ip_load_light/1, + ip_load_medium/1, + ip_load_heavy/1, + ip_dos_hostname/1, + ip_time_test/1, + ip_block_disturbing_idle/1, + ip_block_non_disturbing_idle/1, + ip_block_503/1, + ip_block_disturbing_active/1, + ip_block_non_disturbing_active/1, + ip_block_disturbing_active_timeout_not_released/1, + ip_block_disturbing_active_timeout_released/1, + ip_block_non_disturbing_active_timeout_not_released/1, + ip_block_non_disturbing_active_timeout_released/1, + ip_block_disturbing_blocker_dies/1, + ip_block_non_disturbing_blocker_dies/1, + ip_restart_no_block/1, + ip_restart_disturbing_block/1, + ip_restart_non_disturbing_block/1 + ]). + +-export([ + essl_mod_alias/1, + essl_mod_actions/1, + essl_mod_security/1, + essl_mod_auth/1, + essl_mod_auth_api/1, + essl_mod_auth_mnesia_api/1, + essl_mod_htaccess/1, + essl_mod_cgi/1, + essl_mod_esi/1, + essl_mod_get/1, + essl_mod_head/1, + essl_mod_all/1, + essl_load_light/1, + essl_load_medium/1, + essl_load_heavy/1, + essl_dos_hostname/1, + essl_time_test/1, + essl_restart_no_block/1, + essl_restart_disturbing_block/1, + essl_restart_non_disturbing_block/1, + essl_block_disturbing_idle/1, + essl_block_non_disturbing_idle/1, + essl_block_503/1, + essl_block_disturbing_active/1, + essl_block_non_disturbing_active/1, + essl_block_disturbing_active_timeout_not_released/1, + essl_block_disturbing_active_timeout_released/1, + essl_block_non_disturbing_active_timeout_not_released/1, + essl_block_non_disturbing_active_timeout_released/1, + essl_block_disturbing_blocker_dies/1, + essl_block_non_disturbing_blocker_dies/1 + ]). + +%%% HTTP 1.1 tests +-export([ip_host/1, ip_chunked/1, ip_expect/1, ip_range/1, + ip_if_test/1, ip_http_trace/1, ip_http1_1_head/1, + ip_mod_cgi_chunked_encoding_test/1]). + +%%% HTTP 1.0 tests +-export([ip_head_1_0/1, ip_get_1_0/1, ip_post_1_0/1]). + +%%% HTTP 0.9 tests +-export([ip_get_0_9/1]). + +%%% Ticket tests +-export([ticket_5775/1,ticket_5865/1,ticket_5913/1,ticket_6003/1, + ticket_7304/1]). + +%%% IPv6 tests +-export([ipv6_hostname_ipcomm/0, ipv6_hostname_ipcomm/1, + ipv6_address_ipcomm/0, ipv6_address_ipcomm/1, + ipv6_hostname_essl/0, ipv6_hostname_essl/1, + ipv6_address_essl/0, ipv6_address_essl/1]). + +%% Help functions +-export([cleanup_mnesia/0, setup_mnesia/0, setup_mnesia/1]). + +-define(IP_PORT, 8898). +-define(SSL_PORT, 8899). +-define(MAX_HEADER_SIZE, 256). +-define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1"). + +%% Minutes before failed auths timeout. +-define(FAIL_EXPIRE_TIME,1). + +%% Seconds before successful auths timeout. +-define(AUTH_TIMEOUT,5). + +-record(httpd_user, {user_name, password, user_data}). +-record(httpd_group, {group_name, userlist}). + + +%%-------------------------------------------------------------------- +%% all(Arg) -> [Doc] | [Case] | {skip, Comment} +%% Arg - doc | suite +%% Doc - string() +%% Case - atom() +%% Name of a test case function. +%% Comment - string() +%% Description: Returns documentation/test cases in this test suite +%% or a skip tuple if the platform is not supported. +%%-------------------------------------------------------------------- +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + {group, ip}, + {group, ssl}, + {group, http_1_1_ip}, + {group, http_1_0_ip}, + {group, http_0_9_ip}, + {group, ipv6}, + {group, tickets} + ]. + +groups() -> + [ + {ip, [], + [ip_mod_alias, ip_mod_actions, ip_mod_security, + ip_mod_auth, ip_mod_auth_api, ip_mod_auth_mnesia_api, + ip_mod_htaccess, ip_mod_cgi, ip_mod_esi, ip_mod_get, + ip_mod_head, ip_mod_all, ip_load_light, ip_load_medium, + ip_load_heavy, ip_dos_hostname, ip_time_test, + ip_restart_no_block, ip_restart_disturbing_block, + ip_restart_non_disturbing_block, + ip_block_disturbing_idle, ip_block_non_disturbing_idle, + ip_block_503, ip_block_disturbing_active, + ip_block_non_disturbing_active, + ip_block_disturbing_active_timeout_not_released, + ip_block_disturbing_active_timeout_released, + ip_block_non_disturbing_active_timeout_not_released, + ip_block_non_disturbing_active_timeout_released, + ip_block_disturbing_blocker_dies, + ip_block_non_disturbing_blocker_dies]}, + {ssl, [], [{group, essl}]}, + {essl, [], + [essl_mod_alias, essl_mod_actions, essl_mod_security, + essl_mod_auth, essl_mod_auth_api, + essl_mod_auth_mnesia_api, essl_mod_htaccess, + essl_mod_cgi, essl_mod_esi, essl_mod_get, essl_mod_head, + essl_mod_all, essl_load_light, essl_load_medium, + essl_load_heavy, essl_dos_hostname, essl_time_test, + essl_restart_no_block, essl_restart_disturbing_block, + essl_restart_non_disturbing_block, + essl_block_disturbing_idle, + essl_block_non_disturbing_idle, essl_block_503, + essl_block_disturbing_active, + essl_block_non_disturbing_active, + essl_block_disturbing_active_timeout_not_released, + essl_block_disturbing_active_timeout_released, + essl_block_non_disturbing_active_timeout_not_released, + essl_block_non_disturbing_active_timeout_released, + essl_block_disturbing_blocker_dies, + essl_block_non_disturbing_blocker_dies]}, + {http_1_1_ip, [], + [ip_host, ip_chunked, ip_expect, ip_range, ip_if_test, + ip_http_trace, ip_http1_1_head, + ip_mod_cgi_chunked_encoding_test]}, + {http_1_0_ip, [], + [ip_head_1_0, ip_get_1_0, ip_post_1_0]}, + {http_0_9_ip, [], [ip_get_0_9]}, + {ipv6, [], [ipv6_hostname_ipcomm, ipv6_address_ipcomm, + ipv6_hostname_essl, ipv6_address_essl]}, + {tickets, [], + [ticket_5775, ticket_5865, ticket_5913, ticket_6003, + ticket_7304]}]. + + +init_per_group(ipv6 = _GroupName, Config) -> + case inets_test_lib:has_ipv6_support() of + {ok, _} -> + Config; + _ -> + {skip, "Host does not support IPv6"} + end; +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + io:format(user, "init_per_suite -> entry with" + "~n Config: ~p" + "~n", [Config]), + + ?PRINT_SYSTEM_INFO([]), + + PrivDir = ?config(priv_dir, Config), + SuiteTopDir = filename:join(PrivDir, ?MODULE), + case file:make_dir(SuiteTopDir) of + ok -> + ok; + {error, eexist} -> + ok; + Error -> + throw({error, {failed_creating_suite_top_dir, Error}}) + end, + + [{has_ipv6_support, inets_test_lib:has_ipv6_support()}, + {suite_top_dir, SuiteTopDir}, + {node, node()}, + {host, inets_test_lib:hostname()}, + {address, getaddr()} | Config]. + + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- + +end_per_suite(_Config) -> + %% SuiteTopDir = ?config(suite_top_dir, Config), + %% inets_test_lib:del_dirs(SuiteTopDir), + ok. + + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(Case, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initiation before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(Case, Config) -> + NewConfig = init_per_testcase2(Case, Config), + init_per_testcase3(Case, NewConfig). + + +init_per_testcase2(Case, Config) -> + + %% tsp("init_per_testcase2 -> entry with" + %% "~n Config: ~p", [Config]), + + IpNormal = integer_to_list(?IP_PORT) ++ ".conf", + IpHtaccess = integer_to_list(?IP_PORT) ++ "htaccess.conf", + SslNormal = integer_to_list(?SSL_PORT) ++ ".conf", + SslHtaccess = integer_to_list(?SSL_PORT) ++ "htaccess.conf", + + DataDir = ?config(data_dir, Config), + SuiteTopDir = ?config(suite_top_dir, Config), + + %% tsp("init_per_testcase2 -> " + %% "~n SuiteDir: ~p" + %% "~n DataDir: ~p", [SuiteTopDir, DataDir]), + + TcTopDir = filename:join(SuiteTopDir, Case), + ?line ok = file:make_dir(TcTopDir), + + %% tsp("init_per_testcase2 -> " + %% "~n TcTopDir: ~p", [TcTopDir]), + + DataSrc = filename:join([DataDir, "server_root"]), + ServerRoot = filename:join([TcTopDir, "server_root"]), + + %% tsp("init_per_testcase2 -> " + %% "~n DataSrc: ~p" + %% "~n ServerRoot: ~p", [DataSrc, ServerRoot]), + + ok = file:make_dir(ServerRoot), + ok = file:make_dir(filename:join([TcTopDir, "logs"])), + + NewConfig = [{tc_top_dir, TcTopDir}, {server_root, ServerRoot} | Config], + + %% tsp("init_per_testcase2 -> copy DataSrc to ServerRoot"), + + inets_test_lib:copy_dirs(DataSrc, ServerRoot), + + %% tsp("init_per_testcase2 -> fix cgi"), + EnvCGI = filename:join([ServerRoot, "cgi-bin", "printenv.sh"]), + {ok, FileInfo} = file:read_file_info(EnvCGI), + ok = file:write_file_info(EnvCGI, + FileInfo#file_info{mode = 8#00755}), + + EchoCGI = case test_server:os_type() of + {win32, _} -> + "cgi_echo.exe"; + _ -> + "cgi_echo" + end, + CGIDir = filename:join([ServerRoot, "cgi-bin"]), + inets_test_lib:copy_file(EchoCGI, DataDir, CGIDir), + NewEchoCGI = filename:join([CGIDir, EchoCGI]), + {ok, FileInfo1} = file:read_file_info(NewEchoCGI), + ok = file:write_file_info(NewEchoCGI, + FileInfo1#file_info{mode = 8#00755}), + + %% To be used by IP test cases + %% tsp("init_per_testcase2 -> ip testcase setups"), + create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig], + normal_access, IpNormal), + create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig], + mod_htaccess, IpHtaccess), + + %% To be used by SSL test cases + %% tsp("init_per_testcase2 -> ssl testcase setups"), + SocketType = + case atom_to_list(Case) of + [X, $s, $s, $l | _] -> + case X of + $p -> ssl; + $e -> essl + end; + _ -> + ssl + end, + + create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], + normal_access, SslNormal), + create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], + mod_htaccess, SslHtaccess), + + %% To be used by IPv6 test cases. Case-clause is so that + %% you can do ts:run(inets, httpd_SUITE, <test case>) + %% for all cases except the ipv6 cases as they depend + %% on 'test_host_ipv6_only' that will only be present + %% when you run the whole test suite due to shortcomings + %% of the test server. + + tsp("init_per_testcase2 -> maybe generate IPv6 config file(s)"), + NewConfig2 = + case atom_to_list(Case) of + "ipv6_" ++ _ -> + case (catch inets_test_lib:has_ipv6_support(NewConfig)) of + {ok, IPv6Address0} -> + {ok, Hostname} = inet:gethostname(), + IPv6Address = http_transport:ipv6_name(IPv6Address0), + create_ipv6_config([{port, ?IP_PORT}, + {sock_type, ip_comm}, + {ipv6_host, IPv6Address} | + NewConfig], + "ipv6_hostname_ipcomm.conf", + Hostname), + create_ipv6_config([{port, ?IP_PORT}, + {sock_type, ip_comm}, + {ipv6_host, IPv6Address} | + NewConfig], + "ipv6_address_ipcomm.conf", + IPv6Address), + create_ipv6_config([{port, ?SSL_PORT}, + {sock_type, essl}, + {ipv6_host, IPv6Address} | + NewConfig], + "ipv6_hostname_essl.conf", + Hostname), + create_ipv6_config([{port, ?SSL_PORT}, + {sock_type, essl}, + {ipv6_host, IPv6Address} | + NewConfig], + "ipv6_address_essl.conf", + IPv6Address), + [{ipv6_host, IPv6Address} | NewConfig]; + _ -> + NewConfig + end; + + _ -> + NewConfig + end, + + %% tsp("init_per_testcase2 -> done when" + %% "~n NewConfig2: ~p", [NewConfig2]), + + NewConfig2. + + +init_per_testcase3(Case, Config) -> + tsp("init_per_testcase3(~w) -> entry with" + "~n Config: ~p", [Case, Config]), + + +%% %% Create a new fresh node to be used by the server in this test-case + +%% NodeName = list_to_atom(atom_to_list(Case) ++ "_httpd"), +%% Node = inets_test_lib:start_node(NodeName), + + %% Clean up (we do not want this clean up in end_per_testcase + %% if init_per_testcase crashes for some testcase it will + %% have contaminated the environment and there will be no clean up.) + %% This init can take a few different paths so that one crashes + %% does not mean that all invocations will. + + application:unset_env(inets, services), + application:stop(inets), + application:stop(ssl), + cleanup_mnesia(), + + %% Start initialization + tsp("init_per_testcase3(~w) -> start init", [Case]), + + Dog = test_server:timetrap(inets_test_lib:minutes(10)), + NewConfig = lists:keydelete(watchdog, 1, Config), + TcTopDir = ?config(tc_top_dir, Config), + + CaseRest = + case atom_to_list(Case) of + "ip_mod_htaccess" -> + inets_test_lib:start_http_server( + filename:join(TcTopDir, + integer_to_list(?IP_PORT) ++ + "htaccess.conf")), + "mod_htaccess"; + "ip_" ++ Rest -> + inets_test_lib:start_http_server( + filename:join(TcTopDir, + integer_to_list(?IP_PORT) ++ ".conf")), + Rest; + "ticket_5913" -> + HttpdOptions = + [{file, + filename:join(TcTopDir, + integer_to_list(?IP_PORT) ++ ".conf")}, + {accept_timeout,30000}, + {debug,[{exported_functions, + [httpd_manager,httpd_request_handler]}]}], + inets_test_lib:start_http_server(HttpdOptions); + "ticket_"++Rest -> + %% OTP-5913 use the new syntax of inets.config + inets_test_lib:start_http_server([{file, + filename:join(TcTopDir, + integer_to_list(?IP_PORT) ++ ".conf")}]), + Rest; + + [X, $s, $s, $l, $_, $m, $o, $d, $_, $h, $t, $a, $c, $c, $e, $s, $s] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), + SslTag = + case X of + $p -> ssl; % Plain + $e -> essl % Erlang based ssl + end, + case inets_test_lib:start_http_server_ssl( + filename:join(TcTopDir, + integer_to_list(?SSL_PORT) ++ + "htaccess.conf"), SslTag) of + ok -> + "mod_htaccess"; + Other -> + error_logger:info_msg("Other: ~p~n", [Other]), + {skip, "SSL does not seem to be supported"} + end; + [X, $s, $s, $l, $_ | Rest] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), + SslTag = + case X of + $p -> ssl; + $e -> essl + end, + case inets_test_lib:start_http_server_ssl( + filename:join(TcTopDir, + integer_to_list(?SSL_PORT) ++ + ".conf"), SslTag) of + ok -> + Rest; + Other -> + error_logger:info_msg("Other: ~p~n", [Other]), + {skip, "SSL does not seem to be supported"} + end; + "ipv6_" ++ _ = TestCaseStr -> + case inets_test_lib:has_ipv6_support() of + {ok, _} -> + inets_test_lib:start_http_server( + filename:join(TcTopDir, + TestCaseStr ++ ".conf")); + + _ -> + {skip, "Host does not support IPv6"} + end + end, + + InitRes = + case CaseRest of + {skip, _} = Skip -> + Skip; + "mod_auth_" ++ _ -> + start_mnesia(?config(node, Config)), + [{watchdog, Dog} | NewConfig]; + "mod_htaccess" -> + ServerRoot = ?config(server_root, Config), + Path = filename:join([ServerRoot, "htdocs"]), + catch remove_htaccess(Path), + create_htaccess_data(Path, ?config(address, Config)), + [{watchdog, Dog} | NewConfig]; + "range" -> + ServerRoot = ?config(server_root, Config), + Path = filename:join([ServerRoot, "htdocs"]), + create_range_data(Path), + [{watchdog, Dog} | NewConfig]; + _ -> + [{watchdog, Dog} | NewConfig] + end, + + tsp("init_per_testcase3(~w) -> done when" + "~n InitRes: ~p", [Case, InitRes]), + + InitRes. + + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(Case, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + end_per_testcase2(Case, lists:keydelete(watchdog, 1, Config)), + ok. + +end_per_testcase2(Case, Config) -> + tsp("end_per_testcase2(~w) -> entry with" + "~n Config: ~p", [Case, Config]), + application:unset_env(inets, services), + application:stop(inets), + application:stop(ssl), + application:stop(crypto), % used by the new ssl (essl test cases) + cleanup_mnesia(), + tsp("end_per_testcase2(~w) -> done", [Case]), + ok. + + +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- + +%%------------------------------------------------------------------------- +ip_mod_alias(doc) -> + ["Module test: mod_alias"]; +ip_mod_alias(suite) -> + []; +ip_mod_alias(Config) when is_list(Config) -> + httpd_mod:alias(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_actions(doc) -> + ["Module test: mod_actions"]; +ip_mod_actions(suite) -> + []; +ip_mod_actions(Config) when is_list(Config) -> + httpd_mod:actions(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_security(doc) -> + ["Module test: mod_security"]; +ip_mod_security(suite) -> + []; +ip_mod_security(Config) when is_list(Config) -> + ServerRoot = ?config(server_root, Config), + httpd_mod:security(ServerRoot, ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_auth(doc) -> + ["Module test: mod_auth"]; +ip_mod_auth(suite) -> + []; +ip_mod_auth(Config) when is_list(Config) -> + httpd_mod:auth(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_auth_api(doc) -> + ["Module test: mod_auth_api"]; +ip_mod_auth_api(suite) -> + []; +ip_mod_auth_api(Config) when is_list(Config) -> + ServerRoot = ?config(server_root, Config), + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_mod:auth_api(ServerRoot, "", ip_comm, ?IP_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "dets_", ip_comm, ?IP_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "mnesia_", ip_comm, ?IP_PORT, Host, Node), + ok. +%%------------------------------------------------------------------------- +ip_mod_auth_mnesia_api(doc) -> + ["Module test: mod_auth_mnesia_api"]; +ip_mod_auth_mnesia_api(suite) -> + []; +ip_mod_auth_mnesia_api(Config) when is_list(Config) -> + httpd_mod:auth_mnesia_api(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_mod_htaccess(doc) -> + ["Module test: mod_htaccess"]; +ip_mod_htaccess(suite) -> + []; +ip_mod_htaccess(Config) when is_list(Config) -> + httpd_mod:htaccess(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_mod_cgi(doc) -> + ["Module test: mod_cgi"]; +ip_mod_cgi(suite) -> + []; +ip_mod_cgi(Config) when is_list(Config) -> + httpd_mod:cgi(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_mod_esi(doc) -> + ["Module test: mod_esi"]; +ip_mod_esi(suite) -> + []; +ip_mod_esi(Config) when is_list(Config) -> + httpd_mod:esi(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_get(doc) -> + ["Module test: mod_get"]; +ip_mod_get(suite) -> + []; +ip_mod_get(Config) when is_list(Config) -> + httpd_mod:get(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_mod_head(doc) -> + ["Module test: mod_head"]; +ip_mod_head(suite) -> + []; +ip_mod_head(Config) when is_list(Config) -> + httpd_mod:head(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_mod_all(doc) -> + ["All modules test"]; +ip_mod_all(suite) -> + []; +ip_mod_all(Config) when is_list(Config) -> + httpd_mod:all(ip_comm, ?IP_PORT, + ?config(host, Config), ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_load_light(doc) -> + ["Test light load"]; +ip_load_light(suite) -> + []; +ip_load_light(Config) when is_list(Config) -> + httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config), + get_nof_clients(ip_comm, light)), + ok. +%%------------------------------------------------------------------------- +ip_load_medium(doc) -> + ["Test medium load"]; +ip_load_medium(suite) -> + []; +ip_load_medium(Config) when is_list(Config) -> + httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config), + get_nof_clients(ip_comm, medium)), + ok. +%%------------------------------------------------------------------------- +ip_load_heavy(doc) -> + ["Test heavy load"]; +ip_load_heavy(suite) -> + []; +ip_load_heavy(Config) when is_list(Config) -> + httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config), + get_nof_clients(ip_comm, heavy)), + ok. + + +%%------------------------------------------------------------------------- +ip_dos_hostname(doc) -> + ["Denial Of Service (DOS) attack test case"]; +ip_dos_hostname(suite) -> + []; +ip_dos_hostname(Config) when is_list(Config) -> + dos_hostname(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config), ?MAX_HEADER_SIZE), + ok. + + +%%------------------------------------------------------------------------- +ip_time_test(doc) -> + [""]; +ip_time_test(suite) -> + []; +ip_time_test(Config) when is_list(Config) -> + %% <CONDITIONAL-SKIP> + Skippable = [win32], + Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_time_test:t(ip_comm, ?config(host, Config), ?IP_PORT), + ok. + +%%------------------------------------------------------------------------- +ip_block_503(doc) -> + ["Check that you will receive status code 503 when the server" + " is blocked and 200 when its not blocked."]; +ip_block_503(suite) -> + []; +ip_block_503(Config) when is_list(Config) -> + httpd_block:block_503(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "distribing does not really make a difference in this case."]; +ip_block_disturbing_idle(suite) -> + []; +ip_block_disturbing_idle(Config) when is_list(Config) -> + httpd_block:block_disturbing_idle(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_non_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing does not really make a difference in this case."]; +ip_block_non_disturbing_idle(suite) -> + []; +ip_block_non_disturbing_idle(Config) when is_list(Config) -> + httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_disturbing_active(doc) -> + ["Check that you can block/unblock an active server. The strategy " + "distribing means ongoing requests should be terminated."]; +ip_block_disturbing_active(suite) -> + []; +ip_block_disturbing_active(Config) when is_list(Config) -> + httpd_block:block_disturbing_active(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_non_disturbing_active(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing means the ongoing requests should be compleated."]; +ip_block_non_disturbing_active(suite) -> + []; +ip_block_non_disturbing_active(Config) when is_list(Config) -> + httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_block_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be compleated" + "if the timeout does not occur."]; +ip_block_disturbing_active_timeout_not_released(suite) -> + []; +ip_block_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + httpd_block:block_disturbing_active_timeout_not_released(ip_comm, + ?IP_PORT, + ?config(host, + Config), + ?config(node, + Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be terminated when" + "the timeout occurs."]; +ip_block_disturbing_active_timeout_released(suite) -> + []; +ip_block_disturbing_active_timeout_released(Config) + when is_list(Config) -> + httpd_block:block_disturbing_active_timeout_released(ip_comm, + ?IP_PORT, + ?config(host, + Config), + ?config(node, + Config)), + ok. + +%%------------------------------------------------------------------------- +ip_block_non_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "non non distribing means ongoing requests should be completed."]; +ip_block_non_disturbing_active_timeout_not_released(suite) -> + []; +ip_block_non_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + httpd_block: + block_non_disturbing_active_timeout_not_released(ip_comm, + ?IP_PORT, + ?config(host, + Config), + ?config(node, + Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_non_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "non non distribing means ongoing requests should be completed. " + "When the timeout occurs the block operation sohould be canceled." ]; +ip_block_non_disturbing_active_timeout_released(suite) -> + []; +ip_block_non_disturbing_active_timeout_released(Config) + when is_list(Config) -> + httpd_block: + block_non_disturbing_active_timeout_released(ip_comm, + ?IP_PORT, + ?config(host, + Config), + ?config(node, + Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_disturbing_blocker_dies(doc) -> + []; +ip_block_disturbing_blocker_dies(suite) -> + []; +ip_block_disturbing_blocker_dies(Config) when is_list(Config) -> + httpd_block:disturbing_blocker_dies(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_block_non_disturbing_blocker_dies(doc) -> + []; +ip_block_non_disturbing_blocker_dies(suite) -> + []; +ip_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> + httpd_block:non_disturbing_blocker_dies(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_restart_no_block(doc) -> + [""]; +ip_restart_no_block(suite) -> + []; +ip_restart_no_block(Config) when is_list(Config) -> + httpd_block:restart_no_block(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_restart_disturbing_block(doc) -> + [""]; +ip_restart_disturbing_block(suite) -> + []; +ip_restart_disturbing_block(Config) when is_list(Config) -> + %% <CONDITIONAL-SKIP> + Condition = + fun() -> + case os:type() of + {unix, linux} -> + HW = string:strip(os:cmd("uname -m"), right, $\n), + case HW of + "ppc" -> + case inet:gethostname() of + {ok, "peach"} -> + true; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end + end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_block:restart_disturbing_block(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_restart_non_disturbing_block(doc) -> + [""]; +ip_restart_non_disturbing_block(suite) -> + []; +ip_restart_non_disturbing_block(Config) when is_list(Config) -> + %% <CONDITIONAL-SKIP> + Condition = + fun() -> + case os:type() of + {unix, linux} -> + HW = string:strip(os:cmd("uname -m"), right, $\n), + case HW of + "ppc" -> + case inet:gethostname() of + {ok, "peach"} -> + true; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end + end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_block:restart_non_disturbing_block(ip_comm, ?IP_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- + +essl_mod_alias(doc) -> + ["Module test: mod_alias - using new of configure new SSL"]; +essl_mod_alias(suite) -> + []; +essl_mod_alias(Config) when is_list(Config) -> + ssl_mod_alias(essl, Config). + + +ssl_mod_alias(Tag, Config) -> + httpd_mod:alias(Tag, ?SSL_PORT, + ?config(host, Config), ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_actions(doc) -> + ["Module test: mod_actions - using new of configure new SSL"]; +essl_mod_actions(suite) -> + []; +essl_mod_actions(Config) when is_list(Config) -> + ssl_mod_actions(essl, Config). + + +ssl_mod_actions(Tag, Config) -> + httpd_mod:actions(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_security(doc) -> + ["Module test: mod_security - using new of configure new SSL"]; +essl_mod_security(suite) -> + []; +essl_mod_security(Config) when is_list(Config) -> + ssl_mod_security(essl, Config). + +ssl_mod_security(Tag, Config) -> + ServerRoot = ?config(server_root, Config), + httpd_mod:security(ServerRoot, + Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_auth(doc) -> + ["Module test: mod_auth - using new of configure new SSL"]; +essl_mod_auth(suite) -> + []; +essl_mod_auth(Config) when is_list(Config) -> + ssl_mod_auth(essl, Config). + +ssl_mod_auth(Tag, Config) -> + httpd_mod:auth(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + + +essl_mod_auth_api(doc) -> + ["Module test: mod_auth - using new of configure new SSL"]; +essl_mod_auth_api(suite) -> + []; +essl_mod_auth_api(Config) when is_list(Config) -> + ssl_mod_auth_api(essl, Config). + +ssl_mod_auth_api(Tag, Config) -> + ServerRoot = ?config(server_root, Config), + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_mod:auth_api(ServerRoot, "", Tag, ?SSL_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "dets_", Tag, ?SSL_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "mnesia_", Tag, ?SSL_PORT, Host, Node), + ok. + + +%%------------------------------------------------------------------------- + + +essl_mod_auth_mnesia_api(doc) -> + ["Module test: mod_auth_mnesia_api - using new of configure new SSL"]; +essl_mod_auth_mnesia_api(suite) -> + []; +essl_mod_auth_mnesia_api(Config) when is_list(Config) -> + ssl_mod_auth_mnesia_api(essl, Config). + +ssl_mod_auth_mnesia_api(Tag, Config) -> + httpd_mod:auth_mnesia_api(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_htaccess(doc) -> + ["Module test: mod_htaccess - using new of configure new SSL"]; +essl_mod_htaccess(suite) -> + []; +essl_mod_htaccess(Config) when is_list(Config) -> + ssl_mod_htaccess(essl, Config). + +ssl_mod_htaccess(Tag, Config) -> + httpd_mod:htaccess(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_cgi(doc) -> + ["Module test: mod_cgi - using new of configure new SSL"]; +essl_mod_cgi(suite) -> + []; +essl_mod_cgi(Config) when is_list(Config) -> + ssl_mod_cgi(essl, Config). + +ssl_mod_cgi(Tag, Config) -> + httpd_mod:cgi(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_esi(doc) -> + ["Module test: mod_esi - using new of configure new SSL"]; +essl_mod_esi(suite) -> + []; +essl_mod_esi(Config) when is_list(Config) -> + ssl_mod_esi(essl, Config). + +ssl_mod_esi(Tag, Config) -> + httpd_mod:esi(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_get(doc) -> + ["Module test: mod_get - using new of configure new SSL"]; +essl_mod_get(suite) -> + []; +essl_mod_get(Config) when is_list(Config) -> + ssl_mod_get(essl, Config). + +ssl_mod_get(Tag, Config) -> + httpd_mod:get(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_head(doc) -> + ["Module test: mod_head - using new of configure new SSL"]; +essl_mod_head(suite) -> + []; +essl_mod_head(Config) when is_list(Config) -> + ssl_mod_head(essl, Config). + +ssl_mod_head(Tag, Config) -> + httpd_mod:head(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_mod_all(doc) -> + ["All modules test - using new of configure new SSL"]; +essl_mod_all(suite) -> + []; +essl_mod_all(Config) when is_list(Config) -> + ssl_mod_all(essl, Config). + +ssl_mod_all(Tag, Config) -> + httpd_mod:all(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_load_light(doc) -> + ["Test light load - using new of configure new SSL"]; +essl_load_light(suite) -> + []; +essl_load_light(Config) when is_list(Config) -> + ssl_load_light(essl, Config). + +ssl_load_light(Tag, Config) -> + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config), + get_nof_clients(ssl, light)), + ok. + + +%%------------------------------------------------------------------------- + +essl_load_medium(doc) -> + ["Test medium load - using new of configure new SSL"]; +essl_load_medium(suite) -> + []; +essl_load_medium(Config) when is_list(Config) -> + ssl_load_medium(essl, Config). + +ssl_load_medium(Tag, Config) -> + %% <CONDITIONAL-SKIP> + Skippable = [win32], + Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config), + get_nof_clients(ssl, medium)), + ok. + + +%%------------------------------------------------------------------------- + +essl_load_heavy(doc) -> + ["Test heavy load - using new of configure new SSL"]; +essl_load_heavy(suite) -> + []; +essl_load_heavy(Config) when is_list(Config) -> + ssl_load_heavy(essl, Config). + +ssl_load_heavy(Tag, Config) -> + %% <CONDITIONAL-SKIP> + Skippable = [win32], + Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config), + get_nof_clients(ssl, heavy)), + ok. + + +%%------------------------------------------------------------------------- + + +essl_dos_hostname(doc) -> + ["Denial Of Service (DOS) attack test case - using new of configure new SSL"]; +essl_dos_hostname(suite) -> + []; +essl_dos_hostname(Config) when is_list(Config) -> + ssl_dos_hostname(essl, Config). + +ssl_dos_hostname(Tag, Config) -> + dos_hostname(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config), + ?MAX_HEADER_SIZE), + ok. + + +%%------------------------------------------------------------------------- + + +essl_time_test(doc) -> + ["using new of configure new SSL"]; +essl_time_test(suite) -> + []; +essl_time_test(Config) when is_list(Config) -> + ssl_time_test(essl, Config). + +ssl_time_test(Tag, Config) when is_list(Config) -> + %% <CONDITIONAL-SKIP> + FreeBSDVersionVerify = + fun() -> + case os:version() of + {7, 1, _} -> % We only have one such machine, so... + true; + _ -> + false + end + end, + Skippable = [win32, {unix, [{freebsd, FreeBSDVersionVerify}]}], + Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_time_test:t(Tag, + ?config(host, Config), + ?SSL_PORT), + ok. + + +%%------------------------------------------------------------------------- + + +essl_block_503(doc) -> + ["Check that you will receive status code 503 when the server" + " is blocked and 200 when its not blocked - using new of configure new SSL."]; +essl_block_503(suite) -> + []; +essl_block_503(Config) when is_list(Config) -> + ssl_block_503(essl, Config). + +ssl_block_503(Tag, Config) -> + httpd_block:block_503(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "distribing does not really make a difference in this case." + "Using new of configure new SSL"]; +essl_block_disturbing_idle(suite) -> + []; +essl_block_disturbing_idle(Config) when is_list(Config) -> + ssl_block_disturbing_idle(essl, Config). + +ssl_block_disturbing_idle(Tag, Config) -> + httpd_block:block_disturbing_idle(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_non_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing does not really make a difference in this case." + "Using new of configure new SSL"]; +essl_block_non_disturbing_idle(suite) -> + []; +essl_block_non_disturbing_idle(Config) when is_list(Config) -> + ssl_block_non_disturbing_idle(essl, Config). + +ssl_block_non_disturbing_idle(Tag, Config) -> + httpd_block:block_non_disturbing_idle(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_disturbing_active(doc) -> + ["Check that you can block/unblock an active server. The strategy " + "distribing means ongoing requests should be terminated." + "Using new of configure new SSL"]; +essl_block_disturbing_active(suite) -> + []; +essl_block_disturbing_active(Config) when is_list(Config) -> + ssl_block_disturbing_active(essl, Config). + +ssl_block_disturbing_active(Tag, Config) -> + httpd_block:block_disturbing_active(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_non_disturbing_active(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing means the ongoing requests should be compleated." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active(suite) -> + []; +essl_block_non_disturbing_active(Config) when is_list(Config) -> + ssl_block_non_disturbing_active(essl, Config). + +ssl_block_non_disturbing_active(Tag, Config) -> + httpd_block:block_non_disturbing_idle(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be compleated" + "if the timeout does not occur." + "Using new of configure new SSL"]; +essl_block_disturbing_active_timeout_not_released(suite) -> + []; +essl_block_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_not_released(essl, Config). + +ssl_block_disturbing_active_timeout_not_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_disturbing_active_timeout_not_released(Tag, + Port, Host, Node), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be terminated when" + "the timeout occurs." + "Using new of configure new SSL"]; +essl_block_disturbing_active_timeout_released(suite) -> + []; +essl_block_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_released(essl, Config). + +ssl_block_disturbing_active_timeout_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_disturbing_active_timeout_released(Tag, + Port, + Host, + Node), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_non_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "non non distribing means ongoing requests should be completed." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active_timeout_not_released(suite) -> + []; +essl_block_non_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_not_released(essl, Config). + +ssl_block_non_disturbing_active_timeout_not_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_non_disturbing_active_timeout_not_released(Tag, + Port, + Host, + Node), + ok. + + +%%------------------------------------------------------------------------- + + +essl_block_non_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "non distribing means ongoing requests should be completed. " + "When the timeout occurs the block operation sohould be canceled." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active_timeout_released(suite) -> + []; +essl_block_non_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_released(essl, Config). + +ssl_block_non_disturbing_active_timeout_released(Tag, Config) + when is_list(Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_non_disturbing_active_timeout_released(Tag, + Port, + Host, + Node), + + ok. + + +%%------------------------------------------------------------------------- + + +essl_block_disturbing_blocker_dies(doc) -> + ["using new of configure new SSL"]; +essl_block_disturbing_blocker_dies(suite) -> + []; +essl_block_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_disturbing_blocker_dies(essl, Config). + +ssl_block_disturbing_blocker_dies(Tag, Config) -> + httpd_block:disturbing_blocker_dies(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + +essl_block_non_disturbing_blocker_dies(doc) -> + ["using new of configure new SSL"]; +essl_block_non_disturbing_blocker_dies(suite) -> + []; +essl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_non_disturbing_blocker_dies(essl, Config). + +ssl_block_non_disturbing_blocker_dies(Tag, Config) -> + httpd_block:non_disturbing_blocker_dies(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + + +essl_restart_no_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_no_block(suite) -> + []; +essl_restart_no_block(Config) when is_list(Config) -> + ssl_restart_no_block(essl, Config). + +ssl_restart_no_block(Tag, Config) -> + httpd_block:restart_no_block(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + + +essl_restart_disturbing_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_disturbing_block(suite) -> + []; +essl_restart_disturbing_block(Config) when is_list(Config) -> + ssl_restart_disturbing_block(essl, Config). + +ssl_restart_disturbing_block(Tag, Config) -> + %% <CONDITIONAL-SKIP> + Condition = + fun() -> + case os:type() of + {unix, linux} -> + case ?OSCMD("uname -m") of + "ppc" -> + case file:read_file_info("/etc/fedora-release") of + {ok, _} -> + case ?OSCMD("awk '{print $2}' /etc/fedora-release") of + "release" -> + %% Fedora 7 and later + case ?OSCMD("awk '{print $3}' /etc/fedora-release") of + "7" -> + true; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end + end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_block:restart_disturbing_block(Tag, ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- + + +essl_restart_non_disturbing_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_non_disturbing_block(suite) -> + []; +essl_restart_non_disturbing_block(Config) when is_list(Config) -> + ssl_restart_non_disturbing_block(essl, Config). + +ssl_restart_non_disturbing_block(Tag, Config) -> + %% <CONDITIONAL-SKIP> + Condition = + fun() -> + case os:type() of + {unix, linux} -> + HW = string:strip(os:cmd("uname -m"), right, $\n), + case HW of + "ppc" -> + case inet:gethostname() of + {ok, "peach"} -> + true; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end + end, + ?NON_PC_TC_MAYBE_SKIP(Config, Condition), + %% </CONDITIONAL-SKIP> + + httpd_block:restart_non_disturbing_block(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), + ok. + + +%%------------------------------------------------------------------------- +ip_host(doc) -> + ["Control that the server accepts/rejects requests with/ without host"]; +ip_host(suite)-> + []; +ip_host(Config) when is_list(Config) -> + httpd_1_1:host(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_chunked(doc) -> + ["Control that the server accepts chunked requests"]; +ip_chunked(suite) -> + []; +ip_chunked(Config) when is_list(Config) -> + httpd_1_1:chunked(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_expect(doc) -> + ["Control that the server handles request with the expect header " + "field appropiate"]; +ip_expect(suite)-> + []; +ip_expect(Config) when is_list(Config) -> + httpd_1_1:expect(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_range(doc) -> + ["Control that the server can handle range requests to plain files"]; +ip_range(suite)-> + []; +ip_range(Config) when is_list(Config) -> + httpd_1_1:range(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_if_test(doc) -> + ["Test that the if - request header fields is handled correclty"]; +ip_if_test(suite) -> + []; +ip_if_test(Config) when is_list(Config) -> + ServerRoot = ?config(server_root, Config), + DocRoot = filename:join([ServerRoot, "htdocs"]), + httpd_1_1:if_test(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config), DocRoot), + ok. +%%------------------------------------------------------------------------- +ip_http_trace(doc) -> + ["Test the trace module "]; +ip_http_trace(suite) -> + []; +ip_http_trace(Config) when is_list(Config) -> + httpd_1_1:http_trace(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. +%%------------------------------------------------------------------------- +ip_http1_1_head(doc) -> + ["Test the trace module "]; +ip_http1_1_head(suite)-> + []; +ip_http1_1_head(Config) when is_list(Config) -> + httpd_1_1:head(ip_comm, ?IP_PORT, ?config(host, Config), + ?config(node, Config)), + ok. + +%%------------------------------------------------------------------------- +ip_get_0_9(doc) -> + ["Test simple HTTP/0.9 GET"]; +ip_get_0_9(suite)-> + []; +ip_get_0_9(Config) when is_list(Config) -> + Host = ?config(host, Config), + Node = ?config(node, Config), + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "GET / \r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/0.9"} ]), + %% Without space after uri + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "GET /\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/0.9"} ]), + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "GET / HTTP/0.9\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/0.9"}]), + + ok. +%%------------------------------------------------------------------------- +ip_head_1_0(doc) -> + ["Test HTTP/1.0 HEAD"]; +ip_head_1_0(suite)-> + []; +ip_head_1_0(Config) when is_list(Config) -> + Host = ?config(host, Config), + Node = ?config(node, Config), + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "HEAD / HTTP/1.0\r\n\r\n", [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok. +%%------------------------------------------------------------------------- +ip_get_1_0(doc) -> + ["Test HTTP/1.0 GET"]; +ip_get_1_0(suite)-> + []; +ip_get_1_0(Config) when is_list(Config) -> + Host = ?config(host, Config), + Node = ?config(node, Config), + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "GET / HTTP/1.0\r\n\r\n", [{statuscode, 200}, + {version, "HTTP/1.0"}]), + + ok. +%%------------------------------------------------------------------------- +ip_post_1_0(doc) -> + ["Test HTTP/1.0 POST"]; +ip_post_1_0(suite)-> + []; +ip_post_1_0(Config) when is_list(Config) -> + Host = ?config(host, Config), + Node = ?config(node, Config), + %% Test the post message formatin 1.0! Real post are testes elsewhere + ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node, + "POST / HTTP/1.0\r\n\r\n " + "Content-Length:6 \r\n\r\nfoobar", + [{statuscode, 500}, {version, "HTTP/1.0"}]), + + ok. +%%------------------------------------------------------------------------- +ip_mod_cgi_chunked_encoding_test(doc) -> + ["Test the trace module "]; +ip_mod_cgi_chunked_encoding_test(suite)-> + []; +ip_mod_cgi_chunked_encoding_test(Config) when is_list(Config) -> + Host = ?config(host, Config), + Script = + case test_server:os_type() of + {win32, _} -> + "/cgi-bin/printenv.bat"; + _ -> + "/cgi-bin/printenv.sh" + end, + Requests = + ["GET " ++ Script ++ " HTTP/1.1\r\nHost:"++ Host ++"\r\n\r\n", + "GET /cgi-bin/erl/httpd_example/newformat HTTP/1.1\r\nHost:" + ++ Host ++"\r\n\r\n"], + httpd_1_1:mod_cgi_chunked_encoding_test(ip_comm, ?IP_PORT, + Host, + ?config(node, Config), + Requests), + ok. + +%------------------------------------------------------------------------- + +ipv6_hostname_ipcomm() -> + [{require, ipv6_hosts}]. +ipv6_hostname_ipcomm(X) -> + SocketType = ip_comm, + Port = ?IP_PORT, + ipv6_hostname(SocketType, Port, X). + +ipv6_hostname_essl() -> + [{require, ipv6_hosts}]. +ipv6_hostname_essl(X) -> + SocketType = essl, + Port = ?SSL_PORT, + ipv6_hostname(SocketType, Port, X). + +ipv6_hostname(_SocketType, _Port, doc) -> + ["Test standard ipv6 address"]; +ipv6_hostname(_SocketType, _Port, suite)-> + []; +ipv6_hostname(SocketType, Port, Config) when is_list(Config) -> + tsp("ipv6_hostname -> entry with" + "~n SocketType: ~p" + "~n Port: ~p" + "~n Config: ~p", [SocketType, Port, Config]), + Host = ?config(host, Config), + URI = "GET HTTP://" ++ + Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n", + tsp("ipv6_hostname -> Host: ~p", [Host]), + httpd_test_lib:verify_request(SocketType, Host, Port, [inet6], + node(), + URI, + [{statuscode, 200}, {version, "HTTP/1.1"}]), + ok. + +%%------------------------------------------------------------------------- + +ipv6_address_ipcomm() -> + [{require, ipv6_hosts}]. +ipv6_address_ipcomm(X) -> + SocketType = ip_comm, + Port = ?IP_PORT, + ipv6_address(SocketType, Port, X). + +ipv6_address_essl() -> + [{require, ipv6_hosts}]. +ipv6_address_essl(X) -> + SocketType = essl, + Port = ?SSL_PORT, + ipv6_address(SocketType, Port, X). + +ipv6_address(_SocketType, _Port, doc) -> + ["Test standard ipv6 address"]; +ipv6_address(_SocketType, _Port, suite)-> + []; +ipv6_address(SocketType, Port, Config) when is_list(Config) -> + tsp("ipv6_address -> entry with" + "~n SocketType: ~p" + "~n Port: ~p" + "~n Config: ~p", [SocketType, Port, Config]), + Host = ?config(host, Config), + tsp("ipv6_address -> Host: ~p", [Host]), + URI = "GET HTTP://" ++ + Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n", + httpd_test_lib:verify_request(SocketType, Host, Port, [inet6], + node(), + URI, + [{statuscode, 200}, {version, "HTTP/1.1"}]), + ok. + + +%%-------------------------------------------------------------------- +ticket_5775(doc) -> + ["Tests that content-length is correct"]; +ticket_5775(suite) -> + []; +ticket_5775(Config) -> + ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config), + ?IP_PORT, ?config(node, Config), + "GET /cgi-bin/erl/httpd_example:get_bin " + "HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + ok. +ticket_5865(doc) -> + ["Tests that a header without last-modified is handled"]; +ticket_5865(suite) -> + []; +ticket_5865(Config) -> + ?SKIP(as_of_r15_behaviour_of_calendar_has_changed), + Host = ?config(host,Config), + ServerRoot = ?config(server_root, Config), + DocRoot = filename:join([ServerRoot, "htdocs"]), + File = filename:join([DocRoot,"last_modified.html"]), + + Bad_mtime = case test_server:os_type() of + {win32, _} -> + {{1600,12,31},{23,59,59}}; + {unix, _} -> + {{1969,12,31},{23,59,59}} + end, + + {ok,FI}=file:read_file_info(File), + + case file:write_file_info(File,FI#file_info{mtime=Bad_mtime}) of + ok -> + ok = httpd_test_lib:verify_request(ip_comm, Host, + ?IP_PORT, ?config(node, Config), + "GET /last_modified.html" + " HTTP/1.1\r\nHost:" + ++Host++"\r\n\r\n", + [{statuscode, 200}, + {no_header, + "last-modified"}]), + ok; + {error, Reason} -> + Fault = + io_lib:format("Attempt to change the file info to set the" + " preconditions of the test case failed ~p~n", + [Reason]), + {skip, Fault} + end. + +ticket_5913(doc) -> + ["Tests that a header without last-modified is handled"]; +ticket_5913(suite) -> []; +ticket_5913(Config) -> + ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), + ?IP_PORT, ?config(node, Config), + "GET /cgi-bin/erl/httpd_example:get_bin " + "HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + ok. + +ticket_6003(doc) -> + ["Tests that a URI with a bad hexadecimal code is handled"]; +ticket_6003(suite) -> []; +ticket_6003(Config) -> + ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), + ?IP_PORT, ?config(node, Config), + "GET http://www.erlang.org/%skalle " + "HTTP/1.0\r\n\r\n", + [{statuscode, 400}, + {version, "HTTP/1.0"}]), + ok. + +ticket_7304(doc) -> + ["Tests missing CR in delimiter"]; +ticket_7304(suite) -> + []; +ticket_7304(Config) -> + ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config), + ?IP_PORT, ?config(node, Config), + "GET / HTTP/1.0\r\n\n", + [{statuscode, 200}, + {version, "HTTP/1.0"}]), + ok. + +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- +dos_hostname(Type, Port, Host, Node, Max) -> + H1 = {"", 200}, + H2 = {"dummy-host.ericsson.se", 200}, + TooLongHeader = lists:append(lists:duplicate(Max + 1, "a")), + H3 = {TooLongHeader, 403}, + Hosts = [H1,H2,H3], + dos_hostname_poll(Type, Host, Port, Node, Hosts). + +%% make_ipv6(T) when is_tuple(T) andalso (size(T) =:= 8) -> +%% make_ipv6(tuple_to_list(T)); + +%% make_ipv6([_, _, _, _, _, _, _, _] = IPV6) -> +%% lists:flatten(io_lib:format("~s:~s:~s:~s:~s:~s:~s:~s", IPV6)). + + +%%-------------------------------------------------------------------- +%% Other help functions +create_config(Config, Access, FileName) -> + ServerRoot = ?config(server_root, Config), + TcTopDir = ?config(tc_top_dir, Config), + Port = ?config(port, Config), + Type = ?config(sock_type, Config), + Host = ?config(host, Config), + Mods = io_lib:format("~p", [httpd_mod]), + Funcs = io_lib:format("~p", [ssl_password_cb]), + MaxHdrSz = io_lib:format("~p", [256]), + MaxHdrAct = io_lib:format("~p", [close]), + + io:format(user, + "create_config -> " + "~n ServerRoot: ~p" + "~n TcTopDir: ~p" + "~n Type: ~p" + "~n Port: ~p" + "~n Host: ~p" + "~n", [ServerRoot, TcTopDir, Type, Port, Host]), + + SSL = + if + (Type =:= ssl) orelse + (Type =:= essl) -> + [cline(["SSLCertificateFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLCertificateKeyFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLCACertificateFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLPasswordCallbackModule ", Mods]), + cline(["SSLPasswordCallbackFunction ", Funcs]), + cline(["SSLVerifyClient 0"]), + cline(["SSLVerifyDepth 1"])]; + true -> + [] + end, + ModOrder = + case Access of + mod_htaccess -> + "Modules mod_alias mod_htaccess mod_auth " + "mod_security " + "mod_responsecontrol mod_trace mod_esi " + "mod_actions mod_cgi mod_include mod_dir " + "mod_range mod_get " + "mod_head mod_log mod_disk_log"; + _ -> + "Modules mod_alias mod_auth mod_security " + "mod_responsecontrol mod_trace mod_esi " + "mod_actions mod_cgi mod_include mod_dir " + "mod_range mod_get " + "mod_head mod_log mod_disk_log" + end, + + %% The test suite currently does not handle an explicit BindAddress. + %% They assume any has been used, that is Addr is always set to undefined! + + %% {ok, Hostname} = inet:gethostname(), + %% {ok, Addr} = inet:getaddr(Hostname, inet6), + %% AddrStr = make_ipv6(Addr), + %% BindAddress = lists:flatten(io_lib:format("~s|inet6", [AddrStr])), + + BindAddress = "*|inet", + %% BindAddress = "*", + + HttpConfig = [ + cline(["Port ", integer_to_list(Port)]), + cline(["ServerName ", Host]), + cline(["SocketType ", atom_to_list(Type)]), + cline([ModOrder]), + %% cline(["LogFormat ", "erlang"]), + cline(["ServerAdmin [email protected]"]), + cline(["BindAddress ", BindAddress]), + cline(["ServerRoot ", ServerRoot]), + cline(["ErrorLog ", TcTopDir, + "/logs/error_log_", integer_to_list(Port)]), + cline(["TransferLog ", TcTopDir, + "/logs/access_log_", integer_to_list(Port)]), + cline(["SecurityLog ", TcTopDir, + "/logs/security_log_", integer_to_list(Port)]), + cline(["ErrorDiskLog ", TcTopDir, + "/logs/error_disk_log_", integer_to_list(Port)]), + cline(["ErrorDiskLogSize ", "190000 ", "11"]), + cline(["TransferDiskLog ", TcTopDir, + "/logs/access_disk_log_", integer_to_list(Port)]), + cline(["TransferDiskLogSize ", "200000 ", "10"]), + cline(["SecurityDiskLog ", TcTopDir, + "/logs/security_disk_log_", integer_to_list(Port)]), + cline(["SecurityDiskLogSize ", "210000 ", "9"]), + cline(["MaxClients 10"]), + cline(["MaxHeaderSize ", MaxHdrSz]), + cline(["MaxHeaderAction ", MaxHdrAct]), + cline(["DocumentRoot ", + filename:join(ServerRoot, "htdocs")]), + cline(["DirectoryIndex ", "index.html ", "welcome.html"]), + cline(["DefaultType ", "text/plain"]), + SSL, + mod_alias_config(ServerRoot), + + config_directory(filename:join([ServerRoot,"htdocs", + "open"]), + "Open Area", + filename:join(ServerRoot, "auth/passwd"), + filename:join(ServerRoot, "auth/group"), + plain, + "user one Aladdin", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join([ServerRoot,"htdocs", + "secret"]), + "Secret Area", + filename:join(ServerRoot, "auth/passwd"), + filename:join(ServerRoot, "auth/group"), + plain, + "group group1 group2", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join([ServerRoot,"htdocs", + "secret", + "top_secret"]), + "Top Secret Area", + filename:join(ServerRoot, "auth/passwd"), + filename:join(ServerRoot, "auth/group"), + plain, + "group group3", + filename:join(ServerRoot, "security_data")), + + config_directory(filename:join([ServerRoot,"htdocs", + "dets_open"]), + "Dets Open Area", + filename:join(ServerRoot, "passwd"), + filename:join(ServerRoot, "group"), + dets, + "user one Aladdin", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join([ServerRoot,"htdocs", + "dets_secret"]), + "Dets Secret Area", + filename:join(ServerRoot, "passwd"), + filename:join(ServerRoot, "group"), + dets, + "group group1 group2", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join([ServerRoot,"htdocs", + "dets_secret", + "top_secret"]), + "Dets Top Secret Area", + filename:join(ServerRoot, "passwd"), + filename:join(ServerRoot, "group"), + dets, + "group group3", + filename:join(ServerRoot, "security_data")), + + config_directory(filename:join([ServerRoot,"htdocs", + "mnesia_open"]), + "Mnesia Open Area", + false, + false, + mnesia, + "user one Aladdin", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join([ServerRoot,"htdocs", + "mnesia_secret"]), + "Mnesia Secret Area", + false, + false, + mnesia, + "group group1 group2", + filename:join(ServerRoot, "security_data")), + config_directory(filename:join( + [ServerRoot, "htdocs", "mnesia_secret", + "top_secret"]), + "Mnesia Top Secret Area", + false, + false, + mnesia, + "group group3", + filename:join(ServerRoot, "security_data")) + ], + ConfigFile = filename:join([TcTopDir, FileName]), + {ok, Fd} = file:open(ConfigFile, [write]), + ok = file:write(Fd, lists:flatten(HttpConfig)), + ok = file:close(Fd). + +config_directory(Dir, AuthName, AuthUserFile, AuthGroupFile, AuthDBType, + Require, SF) -> + file:delete(SF), + [ + cline(["<Directory ", Dir, ">"]), + cline(["SecurityDataFile ", SF]), + cline(["SecurityMaxRetries 3"]), + cline(["SecurityFailExpireTime ", integer_to_list(?FAIL_EXPIRE_TIME)]), + cline(["SecurityBlockTime 1"]), + cline(["SecurityAuthTimeout ", integer_to_list(?AUTH_TIMEOUT)]), + cline(["SecurityCallbackModule ", "httpd_mod"]), + cline_if_set("AuthUserFile", AuthUserFile), + cline_if_set("AuthGroupFile", AuthGroupFile), + cline_if_set("AuthName", AuthName), + cline_if_set("AuthDBType", AuthDBType), + cline(["require ", Require]), + cline(["</Directory>\r\n"]) + ]. + +mod_alias_config(Root) -> + [ + cline(["Alias /icons/ ", filename:join(Root,"icons"), "/"]), + cline(["Alias /pics/ ", filename:join(Root, "icons"), "/"]), + cline(["ScriptAlias /cgi-bin/ ", filename:join(Root, "cgi-bin"), "/"]), + cline(["ScriptAlias /htbin/ ", filename:join(Root, "cgi-bin"), "/"]), + cline(["ErlScriptAlias /cgi-bin/erl httpd_example io"]), + cline(["EvalScriptAlias /eval httpd_example io"]) + ]. + +cline(List) -> + lists:flatten([List, "\r\n"]). + +cline_if_set(_, false) -> + []; +cline_if_set(Name, Var) when is_list(Var) -> + cline([Name, " ", Var]); +cline_if_set(Name, Var) when is_atom(Var) -> + cline([Name, " ", atom_to_list(Var)]). + +getaddr() -> + {ok,HostName} = inet:gethostname(), + {ok,{A1,A2,A3,A4}} = inet:getaddr(HostName,inet), + lists:flatten(io_lib:format("~p.~p.~p.~p",[A1,A2,A3,A4])). + +start_mnesia(Node) -> + case rpc:call(Node, ?MODULE, cleanup_mnesia, []) of + ok -> + ok; + Other -> + tsf({failed_to_cleanup_mnesia, Other}) + end, + case rpc:call(Node, ?MODULE, setup_mnesia, []) of + {atomic, ok} -> + ok; + Other2 -> + tsf({failed_to_setup_mnesia, Other2}) + end, + ok. + +setup_mnesia() -> + setup_mnesia([node()]). + +setup_mnesia(Nodes) -> + ok = mnesia:create_schema(Nodes), + ok = mnesia:start(), + {atomic, ok} = mnesia:create_table(httpd_user, + [{attributes, + record_info(fields, httpd_user)}, + {disc_copies,Nodes}, {type, set}]), + {atomic, ok} = mnesia:create_table(httpd_group, + [{attributes, + record_info(fields, + httpd_group)}, + {disc_copies,Nodes}, {type,bag}]). + +cleanup_mnesia() -> + mnesia:start(), + mnesia:delete_table(httpd_user), + mnesia:delete_table(httpd_group), + stopped = mnesia:stop(), + mnesia:delete_schema([node()]), + ok. + +create_htaccess_data(Path, IpAddress)-> + create_htaccess_dirs(Path), + + create_html_file(filename:join([Path,"ht/open/dummy.html"])), + create_html_file(filename:join([Path,"ht/blocknet/dummy.html"])), + create_html_file(filename:join([Path,"ht/secret/dummy.html"])), + create_html_file(filename:join([Path,"ht/secret/top_secret/dummy.html"])), + + create_htaccess_file(filename:join([Path,"ht/open/.htaccess"]), + Path, "user one Aladdin"), + create_htaccess_file(filename:join([Path,"ht/secret/.htaccess"]), + Path, "group group1 group2"), + create_htaccess_file(filename:join([Path, + "ht/secret/top_secret/.htaccess"]), + Path, "user four"), + create_htaccess_file(filename:join([Path,"ht/blocknet/.htaccess"]), + Path, nouser, IpAddress), + + create_user_group_file(filename:join([Path,"ht","users.file"]), + "one:OnePassword\ntwo:TwoPassword\nthree:" + "ThreePassword\nfour:FourPassword\nAladdin:" + "AladdinPassword"), + create_user_group_file(filename:join([Path,"ht","groups.file"]), + "group1: two one\ngroup2: two three"). + +create_html_file(PathAndFileName)-> + file:write_file(PathAndFileName,list_to_binary( + "<html><head><title>test</title></head> + <body>testar</body></html>")). + +create_htaccess_file(PathAndFileName, BaseDir, RequireData)-> + file:write_file(PathAndFileName, + list_to_binary( + "AuthUserFile "++ BaseDir ++ + "/ht/users.file\nAuthGroupFile "++ BaseDir + ++ "/ht/groups.file\nAuthName Test\nAuthType" + " Basic\n<Limit>\nrequire " ++ RequireData ++ + "\n</Limit>")). + +create_htaccess_file(PathAndFileName, BaseDir, nouser, IpAddress)-> + file:write_file(PathAndFileName,list_to_binary( + "AuthUserFile "++ BaseDir ++ + "/ht/users.file\nAuthGroupFile " ++ + BaseDir ++ "/ht/groups.file\nAuthName" + " Test\nAuthType" + " Basic\n<Limit GET>\n\tallow from " ++ + format_ip(IpAddress, + string:rchr(IpAddress,$.)) ++ + "\n</Limit>")). + +create_user_group_file(PathAndFileName, Data)-> + file:write_file(PathAndFileName, list_to_binary(Data)). + +create_htaccess_dirs(Path)-> + ok = file:make_dir(filename:join([Path,"ht"])), + ok = file:make_dir(filename:join([Path,"ht/open"])), + ok = file:make_dir(filename:join([Path,"ht/blocknet"])), + ok = file:make_dir(filename:join([Path,"ht/secret"])), + ok = file:make_dir(filename:join([Path,"ht/secret/top_secret"])). + +remove_htaccess_dirs(Path)-> + file:del_dir(filename:join([Path,"ht/secret/top_secret"])), + file:del_dir(filename:join([Path,"ht/secret"])), + file:del_dir(filename:join([Path,"ht/blocknet"])), + file:del_dir(filename:join([Path,"ht/open"])), + file:del_dir(filename:join([Path,"ht"])). + +format_ip(IpAddress,Pos)when Pos > 0-> + case lists:nth(Pos,IpAddress) of + $.-> + case lists:nth(Pos-2,IpAddress) of + $.-> + format_ip(IpAddress,Pos-3); + _-> + lists:sublist(IpAddress,Pos-2) ++ "." + end; + _ -> + format_ip(IpAddress,Pos-1) + end; + +format_ip(IpAddress, _Pos)-> + "1" ++ IpAddress. + +remove_htaccess(Path)-> + file:delete(filename:join([Path,"ht/open/dummy.html"])), + file:delete(filename:join([Path,"ht/secret/dummy.html"])), + file:delete(filename:join([Path,"ht/secret/top_secret/dummy.html"])), + file:delete(filename:join([Path,"ht/blocknet/dummy.html"])), + file:delete(filename:join([Path,"ht/blocknet/.htaccess"])), + file:delete(filename:join([Path,"ht/open/.htaccess"])), + file:delete(filename:join([Path,"ht/secret/.htaccess"])), + file:delete(filename:join([Path,"ht/secret/top_secret/.htaccess"])), + file:delete(filename:join([Path,"ht","users.file"])), + file:delete(filename:join([Path,"ht","groups.file"])), + remove_htaccess_dirs(Path). + + +dos_hostname_poll(Type, Host, Port, Node, Hosts) -> + [dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) + || {Host1,Code} <- Hosts]. + +dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) -> + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + dos_hostname_request(Host1), + [{statuscode, Code}, + {version, "HTTP/1.0"}]). + +dos_hostname_request(Host) -> + "GET / HTTP/1.0\r\n" ++ Host ++ "\r\n\r\n". + +get_nof_clients(Mode, Load) -> + get_nof_clients(test_server:os_type(), Mode, Load). + +get_nof_clients(_, ip_comm, light) -> 5; +get_nof_clients(_, ssl, light) -> 2; +get_nof_clients(_, ip_comm, medium) -> 10; +get_nof_clients(_, ssl, medium) -> 4; +get_nof_clients(_, ip_comm, heavy) -> 20; +get_nof_clients(_, ssl, heavy) -> 6. + +%% Make a file 100 bytes long containing 012...9*10 +create_range_data(Path) -> + PathAndFileName=filename:join([Path,"range.txt"]), + file:write_file(PathAndFileName,list_to_binary(["12345678901234567890", + "12345678901234567890", + "12345678901234567890", + "12345678901234567890", + "12345678901234567890"])). + +create_ipv6_config(Config, FileName, Ipv6Address) -> + ServerRoot = ?config(server_root, Config), + TcTopDir = ?config(tc_top_dir, Config), + Port = ?config(port, Config), + SockType = ?config(sock_type, Config), + Mods = io_lib:format("~p", [httpd_mod]), + Funcs = io_lib:format("~p", [ssl_password_cb]), + Host = ?config(ipv6_host, Config), + + MaxHdrSz = io_lib:format("~p", [256]), + MaxHdrAct = io_lib:format("~p", [close]), + + Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi" + " mod_include mod_dir mod_get mod_head" + " mod_log mod_disk_log mod_trace", + + SSL = + if + (SockType =:= ssl) orelse + (SockType =:= essl) -> + [cline(["SSLCertificateFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLCertificateKeyFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLCACertificateFile ", + filename:join(ServerRoot, "ssl/ssl_server.pem")]), + cline(["SSLPasswordCallbackModule ", Mods]), + cline(["SSLPasswordCallbackFunction ", Funcs]), + cline(["SSLVerifyClient 0"]), + cline(["SSLVerifyDepth 1"])]; + true -> + [] + end, + + BindAddress = "[" ++ Ipv6Address ++"]|inet6", + + HttpConfig = + [cline(["BindAddress ", BindAddress]), + cline(["Port ", integer_to_list(Port)]), + cline(["ServerName ", Host]), + cline(["SocketType ", atom_to_list(SockType)]), + cline([Mod_order]), + cline(["ServerRoot ", ServerRoot]), + cline(["DocumentRoot ", filename:join(ServerRoot, "htdocs")]), + cline(["MaxHeaderSize ",MaxHdrSz]), + cline(["MaxHeaderAction ",MaxHdrAct]), + cline(["DirectoryIndex ", "index.html "]), + cline(["DefaultType ", "text/plain"]), + SSL], + ConfigFile = filename:join([TcTopDir,FileName]), + {ok, Fd} = file:open(ConfigFile, [write]), + ok = file:write(Fd, lists:flatten(HttpConfig)), + ok = file:close(Fd). + + +tsp(F) -> + inets_test_lib:tsp("[~w]" ++ F, [?MODULE]). +tsp(F, A) -> + inets_test_lib:tsp("[~w]" ++ F, [?MODULE|A]). + +tsf(Reason) -> + inets_test_lib:tsf(Reason). + diff --git a/lib/inets/test/old_httpd_SUITE_data/Makefile.src b/lib/inets/test/old_httpd_SUITE_data/Makefile.src new file mode 100644 index 0000000000..b0fdb43d8d --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/Makefile.src @@ -0,0 +1,14 @@ +CC = @CC@ +LD = @LD@ +CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@ +CROSSLDFLAGS = @CROSSLDFLAGS@ + +PROGS = cgi_echo@exe@ + +all: $(PROGS) + +cgi_echo@exe@: cgi_echo@obj@ + $(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@ + +cgi_echo@obj@: cgi_echo.c + $(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c diff --git a/lib/inets/test/old_httpd_SUITE_data/cgi_echo.c b/lib/inets/test/old_httpd_SUITE_data/cgi_echo.c new file mode 100644 index 0000000000..580f860e96 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/cgi_echo.c @@ -0,0 +1,97 @@ +#include <stdlib.h> +#include <stdio.h> + +#if defined __WIN32__ +#include <windows.h> +#include <fcntl.h> +#endif + +static int read_exact(char *buffer, int len); +static int write_exact(char *buffer, int len); + +int main(void) +{ + char msg[100]; + int msg_len; +#ifdef __WIN32__ + _setmode(_fileno( stdin), _O_BINARY); + _setmode(_fileno( stdout), _O_BINARY); +#endif + msg_len = read_exact(msg, 100); + + write_exact("Content-type: text/plain\r\n\r\n", 28); + write_exact(msg, msg_len); + exit(EXIT_SUCCESS); +} + + +/* read from stdin */ +#ifdef __WIN32__ +static int read_exact(char *buffer, int len) +{ + HANDLE standard_input = GetStdHandle(STD_INPUT_HANDLE); + + unsigned read_result; + unsigned sofar = 0; + + if (!len) { /* Happens for "empty packages */ + return 0; + } + for (;;) { + if (!ReadFile(standard_input, buffer + sofar, + len - sofar, &read_result, NULL)) { + return -1; /* EOF */ + } + if (!read_result) { + return -2; /* Interrupted while reading? */ + } + sofar += read_result; + if (sofar == len) { + return len; + } + } +} +#else +static int read_exact(char *buffer, int len) { + int i, got = 0; + + do { + if ((i = read(0, buffer + got, len - got)) <= 0) + return(i); + got += i; + } while (got < len); + return len; + +} +#endif + +/* write to stdout */ +#ifdef __WIN32__ + static int write_exact(char *buffer, int len) + { + HANDLE standard_output = GetStdHandle(STD_OUTPUT_HANDLE); + unsigned written; + + if (!WriteFile(standard_output, buffer, len, &written, NULL)) { + return -1; /* Broken Pipe */ + } + if (written < ((unsigned) len)) { + /* This should not happen, standard output is not blocking? */ + return -2; + } + + return (int) written; +} + +#else + static int write_exact(char *buffer, int len) { + int i, wrote = 0; + + do { + if ((i = write(1, buffer + wrote, len - wrote)) <= 0) + return i; + wrote += i; + } while (wrote < len); + return len; + } +#endif diff --git a/lib/inets/test/httpd_SUITE_data/server_root/Makefile b/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile index d7a3231068..d7a3231068 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/Makefile +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/auth/group b/lib/inets/test/old_httpd_SUITE_data/server_root/auth/group new file mode 100644 index 0000000000..b3da0ccbd3 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/auth/group @@ -0,0 +1,3 @@ +group1: one two +group2: two three +group3: three Aladdin diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/auth/passwd b/lib/inets/test/old_httpd_SUITE_data/server_root/auth/passwd new file mode 100644 index 0000000000..8c980ff547 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/auth/passwd @@ -0,0 +1,4 @@ +one:onePassword +two:twoPassword +three:threePassword +Aladdin:AladdinPassword diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.bat b/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.bat new file mode 100644 index 0000000000..25a49a1536 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.bat @@ -0,0 +1,9 @@ +@echo off +echo tomrad > c:\cygwin\tmp\hej +echo Content-type: text/html +echo. +echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^> +set +echo ^</PRE^>^</BODY^>^</HTML^> + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.sh b/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.sh new file mode 100755 index 0000000000..de81de9bde --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.sh @@ -0,0 +1,6 @@ +#!/bin/sh +echo "Content-type: text/html" +echo "" +echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>" +env +echo "</PRE></BODY></HTML>"
\ No newline at end of file diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/8080.conf index 48e66f0114..48e66f0114 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/8080.conf diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/8888.conf index 79bb7fcca4..79bb7fcca4 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/8888.conf diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf index ceb94237d2..ceb94237d2 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/mime.types index d2f81e4e5e..d2f81e4e5e 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/mime.types diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/ssl.conf index 8b8c57a98b..8b8c57a98b 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/ssl.conf diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/config.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/config.shtml new file mode 100644 index 0000000000..107e3ff610 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/config.shtml @@ -0,0 +1,70 @@ +<HTML> +<HEAD> +<TITLE>/ssi.html (17-Apr-1997)</TITLE> +</HEAD> +<BODY> +<H1>/ssi.html</H1> + +<!-- ************* CONFIG ************* --> + +<!--#config timefmt="%a %b %e %T %Z %Y" sizefmt="abbrev"--> +<!--#config errmsg="[an especially ugly error occurred while processing this directive]"--> + +<!-- ************* INCLUDE ************* --> + +<P>Include /misc/friedrich.html: +<!--#include virtual="/misc/friedrich.html"--> +<P>Include /misc/not_defined.html: <!--#include virtual="/misc/not_defined.html"--> +<P>Include misc/friedrich.html: +<!--#include file="misc/friedrich.html"--> +<P>Include not_defined.html: <!--#include file="not_defined.html"--> + +<P><HR> + +<!-- ************* ECHO ************* --> + +<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"--> +<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"--> +<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"--> +<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"--> +<P>DATE_GMT: <!--#echo var="DATE_GMT"--> +<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"--> +<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"--> + +<P><HR> + +<!-- ************* FSIZE ************* --> + +<P>Size of index.html: <!--#fsize file="index.html"--> +<P>Size of not_defined.html: <!--#fsize file="not_defined.html"--> +<!--#config sizefmt="bytes"--> +<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"--> +<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"--> + +<P><HR> + +<!-- ************* FLASTMOD ************* --> + +<P>Last modification of index.html: <!--#flastmod file="index.html"--> +<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"--> +<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"--> +<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"--> + +<!--#exec cmd="ls"--> +<!--#exec cmd="printenv"--> +<!--#exec cmd="sunemaja"--> + +<!--#exec cgi="/cgi-bin/printenv.sh"--> + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html new file mode 100644 index 0000000000..a6e8a35a04 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/open/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/open/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html new file mode 100644 index 0000000000..016b04e540 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/secret/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html new file mode 100644 index 0000000000..34db3d5d1a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html @@ -0,0 +1,9 @@ +<HTML> +<HEAD> +<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE> +<!-- Created by: Mattias Nilsson, 04-Feb-1998 --> +</HEAD> +<BODY> +<H1>/secret/top_secret/index.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/echo.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/echo.shtml new file mode 100644 index 0000000000..141db5be59 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/echo.shtml @@ -0,0 +1,35 @@ +<HTML> +<HEAD> +<TITLE>/echo.shtml</TITLE> +</HEAD> +<BODY> +<H1>/echo.shtml</H1> + +<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"--> + +<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"--> + +<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"--> + +<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"--> + +<P>DATE_GMT: <!--#echo var="DATE_GMT"--> + +<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"--> + +<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"--> + +<P>[<A HREF="ssi.html">Back</A>] + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/exec.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/exec.shtml new file mode 100644 index 0000000000..97333da898 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/exec.shtml @@ -0,0 +1,30 @@ +<HTML> +<HEAD> +<TITLE>/exec.shtml</TITLE> +</HEAD> +<BODY> +<H1>/exec.shtml</H1> +<PRE> +<!--#exec cmd="ls"--> +<HR> +<!--#exec cmd="printenv"--> +<HR> +<!--#exec cmd="sunemaja"--> +<HR> +<!--#exec cgi="/cgi-bin/printenv.sh"--> +</PRE> + +<P>[<A HREF="ssi.html">Back</A>] + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/flastmod.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/flastmod.shtml new file mode 100644 index 0000000000..d54c36fe50 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/flastmod.shtml @@ -0,0 +1,29 @@ +<HTML> +<HEAD> +<TITLE>/flastmod.shtml</TITLE> +</HEAD> +<BODY> +<H1>/flastmod.shtml</H1> + +<P>Last modification of index.html: <!--#flastmod file="index.html"--> + +<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"--> + +<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"--> + +<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"--> + +<P>[<A HREF="ssi.html">Back</A>] + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/fsize.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/fsize.shtml new file mode 100644 index 0000000000..570ee9cf6d --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/fsize.shtml @@ -0,0 +1,29 @@ +<HTML> +<HEAD> +<TITLE>/fsize.shtml</TITLE> +</HEAD> +<BODY> +<H1>/fsize.shtml</H1> + +<P>Size of index.html: <!--#fsize file="index.html"--> + +<P>Size of not_defined.html: <!--#fsize file="not_defined.html"--> + +<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"--> + +<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"--> + +<P>[<A HREF="ssi.html">Back</A>] + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/include.shtml b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/include.shtml new file mode 100644 index 0000000000..529aad0437 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/include.shtml @@ -0,0 +1,33 @@ +<HTML> +<HEAD> +<TITLE>/include.shtml</TITLE> +</HEAD> +<BODY> +<H1>/include.shtml</H1> + +<P>Include /misc/friedrich.html: +<!--#include virtual="/misc/friedrich.html"--> + +<P>Include /misc/not_defined.html: +<!--#include virtual="/misc/not_defined.html"--> + +<P>Include misc/friedrich.html: +<!--#include file="misc/friedrich.html"--> + +<P>Include not_defined.html: +<!--#include file="not_defined.html"--> + +<P>[<A HREF="ssi.html">Back</A>] + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/index.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/index.html new file mode 100644 index 0000000000..cfdc9f9ab7 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/index.html @@ -0,0 +1,25 @@ +<HTML> +<HEAD> +<TITLE>/index.html</TITLE> +</HEAD> +<BODY> +<H1>/index.html</H1> + +<STRONG>Server-Side Include (SSI) commands:</STRONG><BR> +<A HREF="config.shtml">config</A><BR> +<A HREF="echo.shtml">echo</A><BR> +<A HREF="exec.shtml">exec</A><BR> +<A HREF="flastmod.shtml">flastmod</A><BR> +<A HREF="fsize.shtml">fsize</A><BR> +<A HREF="include.shtml">include</A><BR> + +<BR> +<BR> + +<STRONG>ESI callback:</STRING><BR> +<A HREF="cgi-bin/erl/httpd_example/get">cgi-bin/erl/httpd_example/get</A><BR> +<A HREF="cgi-bin/erl/httpd_example/yahoo">cgi-bin/erl/httpd_example/yahoo</A><BR> +<A HREF="cgi-bin/erl/httpd_example/test1">cgi-bin/erl/httpd_example/test1</A><BR> + +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/last_modified.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/last_modified.html new file mode 100644 index 0000000000..65c1790813 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/last_modified.html @@ -0,0 +1,22 @@ +<HTML> +<HEAD> +<TITLE>/last_modified.html</TITLE> +</HEAD> +<BODY> +<H1>/last_modified.html</H1> + +<P>This document is only used for test of illegal last-modified date.</P> + + +</BODY> +</HTML> + + + + + + + + + + diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/friedrich.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/friedrich.html new file mode 100644 index 0000000000..d7953d5df4 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/friedrich.html @@ -0,0 +1,7 @@ +<P><CITE> +Talking much about oneself can also be a means to conceal oneself.<BR> +-- Friedrich Nietzsche +</CITE> + +<P>Nested Include: +<!--#include file="misc/oech.html"--> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/oech.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/oech.html new file mode 100644 index 0000000000..506064bf04 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/oech.html @@ -0,0 +1,4 @@ +<P><CITE> +What excuses stand in your way? How can you eliminate them?<BR> +-- Roger von Oech +</CITE> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/welcome.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/welcome.html new file mode 100644 index 0000000000..8c17451f91 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/welcome.html @@ -0,0 +1 @@ +<HTML></HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html new file mode 100644 index 0000000000..a6e8a35a04 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/open/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/open/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html new file mode 100644 index 0000000000..016b04e540 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/secret/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html new file mode 100644 index 0000000000..2d17e8b596 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html @@ -0,0 +1,9 @@ +<HTML> +<HEAD> +<TITLE>/mnesia_secret/top_secret/index.html (04-Feb-1998)</TITLE> +<!-- Created by: Mattias Nilsson, 04-Feb-1998 --> +</HEAD> +<BODY> +<H1>/mnesia_secret/top_secret/index.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/open/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/open/dummy.html new file mode 100644 index 0000000000..a6e8a35a04 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/open/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/open/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/open/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/dummy.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/dummy.html new file mode 100644 index 0000000000..016b04e540 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/dummy.html @@ -0,0 +1,10 @@ +<HTML> +<HEAD> +<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE> +<!-- Created by: Joakim Greben�, 17-Apr-1997 --> +<!-- Changed by: Joakim Greben�, 17-Apr-1997 --> +</HEAD> +<BODY> +<H1>/secret/dummy.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html new file mode 100644 index 0000000000..34db3d5d1a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html @@ -0,0 +1,9 @@ +<HTML> +<HEAD> +<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE> +<!-- Created by: Mattias Nilsson, 04-Feb-1998 --> +</HEAD> +<BODY> +<H1>/secret/top_secret/index.html</H1> +</BODY> +</HTML> diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/README b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/README index a1fc5a5a9c..a1fc5a5a9c 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/icons/README +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/README diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/a.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/a.gif Binary files differnew file mode 100644 index 0000000000..bb23d971f4 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/a.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.black.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.black.gif Binary files differnew file mode 100644 index 0000000000..eaecd2172a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.black.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.red.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.red.gif Binary files differnew file mode 100644 index 0000000000..a423894043 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.red.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/apache_pb.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/apache_pb.gif Binary files differnew file mode 100644 index 0000000000..3a1c139fc4 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/apache_pb.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/back.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/back.gif Binary files differnew file mode 100644 index 0000000000..a694ae1ec3 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/back.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.gray.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.gray.gif Binary files differnew file mode 100644 index 0000000000..eb84268c4c --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.gray.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.red.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.red.gif Binary files differnew file mode 100644 index 0000000000..a8425cb574 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.red.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binary.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binary.gif Binary files differnew file mode 100644 index 0000000000..9a15cbae04 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binary.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binhex.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binhex.gif Binary files differnew file mode 100644 index 0000000000..62d0363108 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binhex.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/blank.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/blank.gif Binary files differnew file mode 100644 index 0000000000..0ccf01e198 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/blank.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/bomb.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/bomb.gif Binary files differnew file mode 100644 index 0000000000..270fdb1c06 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/bomb.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box1.gif Binary files differnew file mode 100644 index 0000000000..65dcd002ea --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box2.gif Binary files differnew file mode 100644 index 0000000000..c43bc4faec --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/broken.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/broken.gif Binary files differnew file mode 100644 index 0000000000..9f8cbe9f76 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/broken.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/burst.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/burst.gif Binary files differnew file mode 100644 index 0000000000..fbdcf575f7 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/burst.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button1.gif Binary files differnew file mode 100644 index 0000000000..eb97cb7333 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button10.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button10.gif Binary files differnew file mode 100644 index 0000000000..fe0c97998c --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button10.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button2.gif Binary files differnew file mode 100644 index 0000000000..7698455bf9 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button3.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button3.gif Binary files differnew file mode 100644 index 0000000000..a8b8319232 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button3.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button4.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button4.gif Binary files differnew file mode 100644 index 0000000000..0fd15a0d7f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button4.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button5.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button5.gif Binary files differnew file mode 100644 index 0000000000..64241e5c5d --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button5.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button6.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button6.gif Binary files differnew file mode 100644 index 0000000000..867cfd1212 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button6.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button7.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button7.gif Binary files differnew file mode 100644 index 0000000000..b3f5fb248f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button7.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button8.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button8.gif Binary files differnew file mode 100644 index 0000000000..7a308be8f6 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button8.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button9.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button9.gif Binary files differnew file mode 100644 index 0000000000..9acba576c0 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button9.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonl.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonl.gif Binary files differnew file mode 100644 index 0000000000..3883088e7a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonl.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonr.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonr.gif Binary files differnew file mode 100644 index 0000000000..c4dc3887db --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonr.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/c.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/c.gif Binary files differnew file mode 100644 index 0000000000..7555b6c164 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/c.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.blue.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.blue.gif Binary files differnew file mode 100644 index 0000000000..f8d76a8c23 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.blue.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.gray.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.gray.gif Binary files differnew file mode 100644 index 0000000000..7664cd0364 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.gray.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/compressed.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/compressed.gif Binary files differnew file mode 100644 index 0000000000..39e732739f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/compressed.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/continued.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/continued.gif Binary files differnew file mode 100644 index 0000000000..b0ffb7e0cc --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/continued.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dir.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dir.gif Binary files differnew file mode 100644 index 0000000000..48264601ae --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dir.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/down.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/down.gif Binary files differnew file mode 100644 index 0000000000..a354c871cd --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/down.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dvi.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dvi.gif Binary files differnew file mode 100644 index 0000000000..791be33105 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dvi.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/f.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/f.gif Binary files differnew file mode 100644 index 0000000000..fbe353c282 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/f.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.gif Binary files differnew file mode 100644 index 0000000000..48264601ae --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.open.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.open.gif Binary files differnew file mode 100644 index 0000000000..30979cb528 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.open.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.sec.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.sec.gif Binary files differnew file mode 100644 index 0000000000..75332d9e59 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.sec.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/forward.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/forward.gif Binary files differnew file mode 100644 index 0000000000..b2959b4c85 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/forward.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.gif Binary files differnew file mode 100644 index 0000000000..de60b2940f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.red.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.red.gif Binary files differnew file mode 100644 index 0000000000..94743981d9 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.red.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.sec.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.sec.gif Binary files differnew file mode 100644 index 0000000000..88d5240c3c --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.sec.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.right.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.right.gif Binary files differnew file mode 100644 index 0000000000..5cdbc7206d --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.right.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.up.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.up.gif Binary files differnew file mode 100644 index 0000000000..85a5d68317 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.up.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/htdig.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/htdig.gif Binary files differnew file mode 100644 index 0000000000..35443fb63a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/htdig.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/icon.sheet.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/icon.sheet.gif Binary files differnew file mode 100644 index 0000000000..ad1686e448 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/icon.sheet.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image1.gif Binary files differnew file mode 100644 index 0000000000..01e442bfa9 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image2.gif Binary files differnew file mode 100644 index 0000000000..751faeea36 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image3.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image3.gif Binary files differnew file mode 100644 index 0000000000..4f30484ff6 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image3.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/index.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/index.gif Binary files differnew file mode 100644 index 0000000000..162478fb3a --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/index.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/layout.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/layout.gif Binary files differnew file mode 100644 index 0000000000..c96338a152 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/layout.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/left.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/left.gif Binary files differnew file mode 100644 index 0000000000..279e6710d4 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/left.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/link.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/link.gif Binary files differnew file mode 100644 index 0000000000..c5b6889a76 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/link.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/movie.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/movie.gif Binary files differnew file mode 100644 index 0000000000..0035183774 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/movie.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/p.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/p.gif Binary files differnew file mode 100644 index 0000000000..7b917b4e91 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/p.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/patch.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/patch.gif Binary files differnew file mode 100644 index 0000000000..39bc90e795 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/patch.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pdf.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pdf.gif Binary files differnew file mode 100644 index 0000000000..c88fd777c4 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pdf.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie0.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie0.gif Binary files differnew file mode 100644 index 0000000000..6f7a0ae7a7 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie0.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie1.gif Binary files differnew file mode 100644 index 0000000000..03aa6be71e --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie2.gif Binary files differnew file mode 100644 index 0000000000..b04c5e0908 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie3.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie3.gif Binary files differnew file mode 100644 index 0000000000..4db9d023ed --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie3.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie4.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie4.gif Binary files differnew file mode 100644 index 0000000000..93471fdd88 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie4.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie5.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie5.gif Binary files differnew file mode 100644 index 0000000000..57aee93f07 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie5.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie6.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie6.gif Binary files differnew file mode 100644 index 0000000000..0dc327b569 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie6.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie7.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie7.gif Binary files differnew file mode 100644 index 0000000000..8661337f06 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie7.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie8.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie8.gif Binary files differnew file mode 100644 index 0000000000..59ddb34ce0 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie8.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/portal.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/portal.gif Binary files differnew file mode 100644 index 0000000000..0e6e506e00 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/portal.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/poweredby.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/poweredby.gif Binary files differnew file mode 100644 index 0000000000..d324ab80ea --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/poweredby.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ps.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ps.gif Binary files differnew file mode 100644 index 0000000000..0f565bc1db --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ps.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/quill.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/quill.gif Binary files differnew file mode 100644 index 0000000000..818a5cdc7e --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/quill.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/right.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/right.gif Binary files differnew file mode 100644 index 0000000000..b256e5f75f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/right.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw1.gif Binary files differnew file mode 100644 index 0000000000..af6ba2b097 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw2.gif Binary files differnew file mode 100644 index 0000000000..06dccb3e44 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/script.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/script.gif Binary files differnew file mode 100644 index 0000000000..d8a853bc58 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/script.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound1.gif Binary files differnew file mode 100644 index 0000000000..8efb49f55d --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound2.gif Binary files differnew file mode 100644 index 0000000000..48e6a7fb2f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere1.gif Binary files differnew file mode 100644 index 0000000000..7067070da2 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere2.gif Binary files differnew file mode 100644 index 0000000000..a9e462a377 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere2.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star.gif Binary files differnew file mode 100644 index 0000000000..4cfe0a5e0f --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star_blank.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star_blank.gif Binary files differnew file mode 100644 index 0000000000..a0c83cb85b --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star_blank.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tar.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tar.gif Binary files differnew file mode 100644 index 0000000000..617e779efa --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tar.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tex.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tex.gif Binary files differnew file mode 100644 index 0000000000..45e43233b8 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tex.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/text.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/text.gif Binary files differnew file mode 100644 index 0000000000..4c623909fb --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/text.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/transfer.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/transfer.gif Binary files differnew file mode 100644 index 0000000000..33697dbb66 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/transfer.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/unknown.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/unknown.gif Binary files differnew file mode 100644 index 0000000000..32b1ea23fb --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/unknown.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/up.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/up.gif Binary files differnew file mode 100644 index 0000000000..6d6d6d1ebf --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/up.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uu.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uu.gif Binary files differnew file mode 100644 index 0000000000..4387d529f6 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uu.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uuencoded.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uuencoded.gif Binary files differnew file mode 100644 index 0000000000..4387d529f6 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uuencoded.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world1.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world1.gif Binary files differnew file mode 100644 index 0000000000..05b4ec2058 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world1.gif diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world2.gif b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world2.gif Binary files differnew file mode 100644 index 0000000000..e3203f7a88 --- /dev/null +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world2.gif diff --git a/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip b/lib/inets/test/old_httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip index 8d1c8b69c3..8d1c8b69c3 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem index 427447958d..427447958d 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem index 4aac86db49..4aac86db49 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem +++ b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 3c20348322..cccfb7a44f 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2013. All Rights Reserved. +# Copyright Ericsson AB 2001-2014. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -18,7 +18,7 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 5.9.7 +INETS_VSN = 5.9.8 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/test/jitu.erl b/lib/jinterface/test/jitu.erl index a029c063bc..46b8cb3ac2 100644 --- a/lib/jinterface/test/jitu.erl +++ b/lib/jinterface/test/jitu.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -133,7 +133,7 @@ es(L,Quote,EscSpace) -> cmd(Cmd) -> PortOpts = [{line,80},eof,exit_status,stderr_to_stdout], - io:format("cmd: ~s~n", [Cmd]), + io:format("cmd: ~ts~n", [Cmd]), case catch open_port({spawn,Cmd}, PortOpts) of Port when is_port(Port) -> case erlang:port_info(Port,os_pid) of diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index 8de81a30ae..b4655ce373 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -98,6 +98,7 @@ /* ----------------------------- INCLUDES ------------------------------*/ +#include <ctype.h> #include <stdlib.h> #include <string.h> #include <stdio.h> diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in index 531ad84fb9..fa81f36e98 100644 --- a/lib/odbc/configure.in +++ b/lib/odbc/configure.in @@ -1,7 +1,7 @@ dnl dnl %CopyrightBegin% dnl -dnl Copyright Ericsson AB 2005-2013. All Rights Reserved. +dnl Copyright Ericsson AB 2005-2014. All Rights Reserved. dnl dnl The contents of this file are subject to the Erlang Public License, dnl Version 1.1, (the "License"); you may not use this file except in @@ -105,7 +105,12 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])) dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h winsock2.h]) -AC_CHECK_HEADERS([sql.h, sqlext.h], [odbc_required_headers=yes], [odbc_required_headers=no]) +AC_CHECK_HEADERS([windows.h]) +AC_CHECK_HEADERS([sql.h sqlext.h], [odbc_required_headers=yes], [odbc_required_headers=no], +[[#ifdef HAVE_WINDOWS_H + # include <windows.h> + #endif + ]]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile index a4e36c7293..c1b3bc866d 100644 --- a/lib/public_key/asn1/Makefile +++ b/lib/public_key/asn1/Makefile @@ -41,7 +41,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/public_key-$(VSN) ASN_TOP = OTP-PUB-KEY PKCS-FRAME ASN_MODULES = PKIX1Explicit88 PKIX1Implicit88 PKIX1Algorithms88 \ PKIXAttributeCertificate PKCS-1 PKCS-3 PKCS-7 PKCS-8 PKCS-10 PKCS5v2-0 OTP-PKIX \ - InformationFramework + InformationFramework RFC5639 ASN_ASNS = $(ASN_MODULES:%=%.asn1) ASN_ERLS = $(ASN_TOP:%=%.erl) ASN_HRLS = $(ASN_TOP:%=%.hrl) @@ -116,7 +116,8 @@ OTP-PUB-KEY.asn1db: PKIX1Algorithms88.asn1 \ PKCS-7.asn1\ PKCS-10.asn1\ InformationFramework.asn1\ - OTP-PKIX.asn1 + OTP-PKIX.asn1 \ + RFC5639.asn1 $(EBIN)/PKCS-FRAME.beam: PKCS-FRAME.erl PKCS-FRAME.hrl PKCS-FRAME.erl PKCS-FRAME.hrl: PKCS-FRAME.asn1db diff --git a/lib/public_key/asn1/OTP-PUB-KEY.set.asn b/lib/public_key/asn1/OTP-PUB-KEY.set.asn index e94f428e4b..b3f3ccdb77 100644 --- a/lib/public_key/asn1/OTP-PUB-KEY.set.asn +++ b/lib/public_key/asn1/OTP-PUB-KEY.set.asn @@ -9,3 +9,4 @@ DSS.asn1 ECPrivateKey.asn1 PKCS-7.asn1 PKCS-10.asn1 +RFC5639.asn1 diff --git a/lib/public_key/asn1/RFC5639.asn1 b/lib/public_key/asn1/RFC5639.asn1 new file mode 100644 index 0000000000..85b8533132 --- /dev/null +++ b/lib/public_key/asn1/RFC5639.asn1 @@ -0,0 +1,27 @@ +RFC5639 {iso(1) identified-organization(3) teletrust(36) algorithm(3) signature-algorithm(3) ecSign(2) 8} DEFINITIONS EXPLICIT TAGS ::= + +BEGIN + +ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) + identified-organization(3) teletrust(36) algorithm(3) signature-algorithm(3) ecSign(2) 8} + +ellipticCurveRFC5639 OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1} + +versionOne OBJECT IDENTIFIER ::= {ellipticCurveRFC5639 1} + +brainpoolP160r1 OBJECT IDENTIFIER ::= {versionOne 1} +brainpoolP160t1 OBJECT IDENTIFIER ::= {versionOne 2} +brainpoolP192r1 OBJECT IDENTIFIER ::= {versionOne 3} +brainpoolP192t1 OBJECT IDENTIFIER ::= {versionOne 4} +brainpoolP224r1 OBJECT IDENTIFIER ::= {versionOne 5} +brainpoolP224t1 OBJECT IDENTIFIER ::= {versionOne 6} +brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} +brainpoolP256t1 OBJECT IDENTIFIER ::= {versionOne 8} +brainpoolP320r1 OBJECT IDENTIFIER ::= {versionOne 9} +brainpoolP320t1 OBJECT IDENTIFIER ::= {versionOne 10} +brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} +brainpoolP384t1 OBJECT IDENTIFIER ::= {versionOne 12} +brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} +brainpoolP512t1 OBJECT IDENTIFIER ::= {versionOne 14} + +END diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl index fdd89aa70d..f7a361d5a8 100644 --- a/lib/public_key/src/pubkey_cert_records.erl +++ b/lib/public_key/src/pubkey_cert_records.erl @@ -147,6 +147,20 @@ namedCurves(?'sect163r1') -> sect163r1; namedCurves(?'sect163k1') -> sect163k1; namedCurves(?'secp256r1') -> secp256r1; namedCurves(?'secp192r1') -> secp192r1; +namedCurves(?'brainpoolP160r1') -> brainpoolP160r1; +namedCurves(?'brainpoolP160t1') -> brainpoolP160t1; +namedCurves(?'brainpoolP192r1') -> brainpoolP192r1; +namedCurves(?'brainpoolP192t1') -> brainpoolP192t1; +namedCurves(?'brainpoolP224r1') -> brainpoolP224r1; +namedCurves(?'brainpoolP224t1') -> brainpoolP224t1; +namedCurves(?'brainpoolP256r1') -> brainpoolP256r1; +namedCurves(?'brainpoolP256t1') -> brainpoolP256t1; +namedCurves(?'brainpoolP320r1') -> brainpoolP320r1; +namedCurves(?'brainpoolP320t1') -> brainpoolP320t1; +namedCurves(?'brainpoolP384r1') -> brainpoolP384r1; +namedCurves(?'brainpoolP384t1') -> brainpoolP384t1; +namedCurves(?'brainpoolP512r1') -> brainpoolP512r1; +namedCurves(?'brainpoolP512t1') -> brainpoolP512t1; namedCurves(sect571r1) -> ?'sect571r1'; namedCurves(sect571k1) -> ?'sect571k1'; @@ -180,7 +194,21 @@ namedCurves(sect239k1) -> ?'sect239k1'; namedCurves(sect163r1) -> ?'sect163r1'; namedCurves(sect163k1) -> ?'sect163k1'; namedCurves(secp256r1) -> ?'secp256r1'; -namedCurves(secp192r1) -> ?'secp192r1'. +namedCurves(secp192r1) -> ?'secp192r1'; +namedCurves(brainpoolP160r1) -> ?'brainpoolP160r1'; +namedCurves(brainpoolP160t1) -> ?'brainpoolP160t1'; +namedCurves(brainpoolP192r1) -> ?'brainpoolP192r1'; +namedCurves(brainpoolP192t1) -> ?'brainpoolP192t1'; +namedCurves(brainpoolP224r1) -> ?'brainpoolP224r1'; +namedCurves(brainpoolP224t1) -> ?'brainpoolP224t1'; +namedCurves(brainpoolP256r1) -> ?'brainpoolP256r1'; +namedCurves(brainpoolP256t1) -> ?'brainpoolP256t1'; +namedCurves(brainpoolP320r1) -> ?'brainpoolP320r1'; +namedCurves(brainpoolP320t1) -> ?'brainpoolP320t1'; +namedCurves(brainpoolP384r1) -> ?'brainpoolP384r1'; +namedCurves(brainpoolP384t1) -> ?'brainpoolP384t1'; +namedCurves(brainpoolP512r1) -> ?'brainpoolP512r1'; +namedCurves(brainpoolP512t1) -> ?'brainpoolP512t1'. %%-------------------------------------------------------------------- %%% Internal functions diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl index 9af8f6bae8..5a3f34506d 100644 --- a/lib/reltool/src/reltool_utils.erl +++ b/lib/reltool/src/reltool_utils.erl @@ -589,6 +589,8 @@ throw_error(Format, Args) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +decode_regexps(Key, Regexps, undefined) -> + decode_regexps(Key, Regexps, []); decode_regexps(Key, {add, Regexps}, Old) when is_list(Regexps) -> do_decode_regexps(Key, Regexps, Old); decode_regexps(_Key, {del, Regexps}, Old) when is_list(Regexps) -> diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index feeac9e099..bfe5d39d53 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -143,7 +143,8 @@ all() -> mod_incl_cond_derived, use_selected_vsn, use_selected_vsn_relative_path, - non_standard_vsn_id]. + non_standard_vsn_id, + undefined_regexp]. groups() -> []. @@ -2506,6 +2507,12 @@ non_standard_vsn_id(Config) -> reltool_server:get_app(Pid2,b)), ok. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +undefined_regexp(_Config) -> + ?msym({ok,_}, + reltool:get_config([{sys,[{app,asn1,[{excl_app_filters, + {add, ["^priv"]}}]}]}])), + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Library functions diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl index 3485365ed9..530d0a9985 100644 --- a/lib/reltool/test/reltool_test_lib.erl +++ b/lib/reltool/test/reltool_test_lib.erl @@ -258,8 +258,8 @@ run_test([{Module, TC} | Rest], Config) -> true -> [do_run_test(Module, TC, NewConfig)] end, - Module:end_per_suite(NewConfig), - Res ++ run_test(Rest, NewConfig); + CommonTestRes = worst_res(Res), + Res ++ run_test(Rest, [{tc_status,CommonTestRes}|NewConfig]); Error -> ?error("Test suite skipped: ~w~n", [Error]), [{skipped, Error}] @@ -267,6 +267,36 @@ run_test([{Module, TC} | Rest], Config) -> run_test([], _Config) -> []. +worst_res(Res) -> + NewRes = [{dummy, {ok,dummy, dummy}} | Res], + [{_,WorstRes}|_] = lists:sort(fun compare_res/2, NewRes), + common_test_res(WorstRes). + +common_test_res(ok) -> + ok; +common_test_res({Res,_,Reason}) -> + common_test_res({Res,Reason}); +common_test_res({Res,Reason}) -> + case Res of + ok -> ok; + skip -> {skipped, Reason}; + skipped -> {skipped, Reason}; + failed -> {failed, Reason}; + crash -> {failed, Reason} + end. + +% crash < failed < skip < ok +compare_res({_,{ResA,_,_}},{_,{ResB,_,_}}) -> + res_to_int(ResA) < res_to_int(ResB). + +res_to_int(Res) -> + case Res of + ok -> 4; + skip -> 3; + failed -> 2; + crash -> 1 + end. + do_run_test(Module, all, Config) -> All = [{Module, Test} || Test <- Module:all()], run_test(All, Config); @@ -290,9 +320,10 @@ eval_test_case(Mod, Fun, Config) -> test_case_evaluator(Mod, Fun, [Config]) -> NewConfig = Mod:init_per_testcase(Fun, Config), - R = apply(Mod, Fun, [NewConfig]), - Mod:end_per_testcase(Fun, NewConfig), - exit({test_case_ok, R}). + Res = apply(Mod, Fun, [NewConfig]), + CommonTestRes = common_test_res(Res), + Mod:end_per_testcase(Fun, [{tc_status,CommonTestRes}|NewConfig]), + exit({test_case_ok, Res}). wait_for_evaluator(Pid, Mod, Fun, Config) -> receive @@ -307,13 +338,17 @@ wait_for_evaluator(Pid, Mod, Fun, Config) -> {'EXIT', Pid, {skipped, Reason}} -> log("<WARNING> Test case ~w skipped, because ~p~n", [{Mod, Fun}, Reason]), - Mod:end_per_testcase(Fun, Config), - {skip, {Mod, Fun}, Reason}; + Res = {skipped, {Mod, Fun}, Reason}, + CommonTestRes = common_test_res(Res), + Mod:end_per_testcase(Fun, [{tc_status,CommonTestRes}|Config]), + Res; {'EXIT', Pid, Reason} -> log("<ERROR> Eval process ~w exited, because\n\t~p~n", [{Mod, Fun}, Reason]), - Mod:end_per_testcase(Fun, Config), - {crash, {Mod, Fun}, Reason} + Res = {crash, {Mod, Fun}, Reason}, + CommonTestRes = common_test_res(Res), + Mod:end_per_testcase(Fun, [{tc_status,CommonTestRes}|Config]), + Res end. flush() -> diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl index 2c8e515a14..41febf9707 100644 --- a/lib/ssh/src/ssh_cli.erl +++ b/lib/ssh/src/ssh_cli.erl @@ -349,7 +349,7 @@ delete_chars(N, {Buf, BufTail, Col}, Tty) when N > 0 -> {Buf, NewBufTail, Col}}; delete_chars(N, {Buf, BufTail, Col}, Tty) -> % N < 0 NewBuf = nthtail(-N, Buf), - NewCol = Col + N, + NewCol = case Col + N of V when V >= 0 -> V; _ -> 0 end, M1 = move_cursor(Col, NewCol, Tty), M2 = move_cursor(NewCol + length(BufTail) - N, NewCol, Tty), {[M1, BufTail, lists:duplicate(-N, $ ) | M2], diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index c090b6ebfb..3a64841976 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,7 +1,11 @@ %% -*- erlang -*- {"%VSN%", [ - {<<"5.3\\*">>, [{restart_application, ssl}]}, + {<<"5.3.2">>, [{load_module, ssl, soft_purge, soft_purge, []}, + {load_module, ssl_connection, soft_purge, soft_purge, []}, + {load_module, ssl_handshake, soft_purge, soft_purge, []}, + {load_module, tls_connection, soft_purge, soft_purge, []}]}, + {<<"5.3.1">>, [{restart_application, ssl}]}, {<<"5.2\\*">>, [{restart_application, ssl}]}, {<<"5.1\\*">>, [{restart_application, ssl}]}, {<<"5.0\\*">>, [{restart_application, ssl}]}, @@ -9,7 +13,11 @@ {<<"3\\.*">>, [{restart_application, ssl}]} ], [ - {<<"5.3\\*">>, [{restart_application, ssl}]}, + {<<"5.3.2">>, [{load_module, ssl, soft_purge, soft_purge, []}, + {load_module, ssl_connection, soft_purge, soft_purge, []}, + {load_module, ssl_handshake, soft_purge, soft_purge, []}, + {load_module, tls_connection, soft_purge, soft_purge, []}]}, + {<<"5.3.1">>, [{restart_application, ssl}]}, {<<"5.2\\*">>, [{restart_application, ssl}]}, {<<"5.1\\*">>, [{restart_application, ssl}]}, {<<"5.0\\*">>, [{restart_application, ssl}]}, diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index cff842cb2f..a7fd9f5f81 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2013. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -608,39 +608,40 @@ handle_options(Opts0, _Role) -> end, SSLOptions = #ssl_options{ - versions = Versions, - verify = validate_option(verify, Verify), - verify_fun = VerifyFun, - fail_if_no_peer_cert = FailIfNoPeerCert, - verify_client_once = handle_option(verify_client_once, Opts, false), - depth = handle_option(depth, Opts, 1), - cert = handle_option(cert, Opts, undefined), - certfile = CertFile, - key = handle_option(key, Opts, undefined), - keyfile = handle_option(keyfile, Opts, CertFile), - password = handle_option(password, Opts, ""), - cacerts = CaCerts, - cacertfile = handle_option(cacertfile, Opts, CaCertDefault), - dh = handle_option(dh, Opts, undefined), - dhfile = handle_option(dhfile, Opts, undefined), - user_lookup_fun = handle_option(user_lookup_fun, Opts, undefined), - psk_identity = handle_option(psk_identity, Opts, undefined), - srp_identity = handle_option(srp_identity, Opts, undefined), - ciphers = handle_option(ciphers, Opts, []), - %% Server side option - reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun), - reuse_sessions = handle_option(reuse_sessions, Opts, true), - secure_renegotiate = handle_option(secure_renegotiate, Opts, false), - renegotiate_at = handle_option(renegotiate_at, Opts, ?DEFAULT_RENEGOTIATE_AT), - hibernate_after = handle_option(hibernate_after, Opts, undefined), - erl_dist = handle_option(erl_dist, Opts, false), - next_protocols_advertised = + versions = Versions, + verify = validate_option(verify, Verify), + verify_fun = VerifyFun, + fail_if_no_peer_cert = FailIfNoPeerCert, + verify_client_once = handle_option(verify_client_once, Opts, false), + depth = handle_option(depth, Opts, 1), + cert = handle_option(cert, Opts, undefined), + certfile = CertFile, + key = handle_option(key, Opts, undefined), + keyfile = handle_option(keyfile, Opts, CertFile), + password = handle_option(password, Opts, ""), + cacerts = CaCerts, + cacertfile = handle_option(cacertfile, Opts, CaCertDefault), + dh = handle_option(dh, Opts, undefined), + dhfile = handle_option(dhfile, Opts, undefined), + user_lookup_fun = handle_option(user_lookup_fun, Opts, undefined), + psk_identity = handle_option(psk_identity, Opts, undefined), + srp_identity = handle_option(srp_identity, Opts, undefined), + ciphers = handle_option(ciphers, Opts, []), + %% Server side option + reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun), + reuse_sessions = handle_option(reuse_sessions, Opts, true), + secure_renegotiate = handle_option(secure_renegotiate, Opts, false), + renegotiate_at = handle_option(renegotiate_at, Opts, ?DEFAULT_RENEGOTIATE_AT), + hibernate_after = handle_option(hibernate_after, Opts, undefined), + erl_dist = handle_option(erl_dist, Opts, false), + next_protocols_advertised = handle_option(next_protocols_advertised, Opts, undefined), - next_protocol_selector = + next_protocol_selector = make_next_protocol_selector( handle_option(client_preferred_next_protocols, Opts, undefined)), - log_alert = handle_option(log_alert, Opts, true) - }, + log_alert = handle_option(log_alert, Opts, true), + server_name_indication = handle_option(server_name_indication, Opts, undefined) + }, CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}), SslOptions = [protocol, versions, verify, verify_fun, @@ -651,7 +652,7 @@ handle_options(Opts0, _Role) -> reuse_session, reuse_sessions, ssl_imp, cb_info, renegotiate_at, secure_renegotiate, hibernate_after, erl_dist, next_protocols_advertised, - client_preferred_next_protocols, log_alert], + client_preferred_next_protocols, log_alert, server_name_indication], SockOpts = lists:foldl(fun(Key, PropList) -> proplists:delete(Key, PropList) @@ -833,6 +834,12 @@ validate_option(next_protocols_advertised = Opt, Value) when is_list(Value) -> validate_option(next_protocols_advertised, undefined) -> undefined; +validate_option(server_name_indication, Value) when is_list(Value) -> + Value; +validate_option(server_name_indication, disable) -> + disable; +validate_option(server_name_indication, undefined) -> + undefined; validate_option(Opt, Value) -> throw({error, {options, {Opt, Value}}}). diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index b7c1b9e8d0..82106935cb 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1597,7 +1597,7 @@ default_hashsign(_Version, KeyExchange) select_curve(#state{client_ecc = {[Curve|_], _}}) -> {namedCurve, Curve}; select_curve(_) -> - {namedCurve, ?secp256k1}. + {namedCurve, ?secp256r1}. is_anonymous(Algo) when Algo == dh_anon; Algo == ecdh_anon; diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index da72ffc043..f5c0034f1b 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -1287,7 +1287,7 @@ select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, select_curve(undefined, _) -> %% Client did not send ECC extension use default curve if %% ECC cipher is negotiated - {namedCurve, ?secp256k1}; + {namedCurve, ?secp256r1}; select_curve(_, []) -> no_curve; select_curve(Curves, [Curve| Rest]) -> diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 8e6f80da1e..ffa04ee8ba 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -199,7 +199,9 @@ hello(start, #state{host = Host, port = Port, role = client, next_state(hello, hello, Record, State); hello(Hello = #client_hello{client_version = ClientVersion, - extensions = #hello_extensions{hash_signs = HashSigns}}, + extensions = #hello_extensions{hash_signs = HashSigns, + ec_point_formats = EcPointFormats, + elliptic_curves = EllipticCurves}}, State = #state{connection_states = ConnectionStates0, port = Port, session = #session{own_certificate = Cert} = Session0, renegotiation = {Renegotiation, _}, @@ -210,9 +212,7 @@ hello(Hello = #client_hello{client_version = ClientVersion, case tls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) of {Version, {Type, Session}, - ConnectionStates, - #hello_extensions{ec_point_formats = EcPointFormats, - elliptic_curves = EllipticCurves} = ServerHelloExt} -> + ConnectionStates, ServerHelloExt} -> ssl_connection:hello({common_client_hello, Type, ServerHelloExt, HashSign}, State#state{connection_states = ConnectionStates, negotiated_version = Version, diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl index 2395e98642..7c7fdd64c3 100644 --- a/lib/ssl/src/tls_v1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -368,11 +368,19 @@ finished_label(server) -> %% list ECC curves in prefered order ecc_curves(_Minor) -> - [?sect571r1,?sect571k1,?secp521r1,?sect409k1,?sect409r1, - ?secp384r1,?sect283k1,?sect283r1,?secp256k1,?secp256r1, - ?sect239k1,?sect233k1,?sect233r1,?secp224k1,?secp224r1, - ?sect193r1,?sect193r2,?secp192k1,?secp192r1,?sect163k1, - ?sect163r1,?sect163r2,?secp160k1,?secp160r1,?secp160r2]. + TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1, + sect409k1,sect409r1,brainpoolP384r1,secp384r1, + sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1, + sect239k1,sect233k1,sect233r1,secp224k1,secp224r1, + sect193r1,sect193r2,secp192k1,secp192r1,sect163k1, + sect163r1,sect163r2,secp160k1,secp160r1,secp160r2], + CryptoCurves = crypto:ec_curves(), + lists:foldr(fun(Curve, Curves) -> + case proplists:get_bool(Curve, CryptoCurves) of + true -> [pubkey_cert_records:namedCurves(Curve)|Curves]; + false -> Curves + end + end, [], TLSCurves). %% ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) oid_to_enum(?sect163k1) -> 1; @@ -399,7 +407,10 @@ oid_to_enum(?secp224r1) -> 21; oid_to_enum(?secp256k1) -> 22; oid_to_enum(?secp256r1) -> 23; oid_to_enum(?secp384r1) -> 24; -oid_to_enum(?secp521r1) -> 25. +oid_to_enum(?secp521r1) -> 25; +oid_to_enum(?brainpoolP256r1) -> 26; +oid_to_enum(?brainpoolP384r1) -> 27; +oid_to_enum(?brainpoolP512r1) -> 28. enum_to_oid(1) -> ?sect163k1; enum_to_oid(2) -> ?sect163r1; @@ -425,7 +436,10 @@ enum_to_oid(21) -> ?secp224r1; enum_to_oid(22) -> ?secp256k1; enum_to_oid(23) -> ?secp256r1; enum_to_oid(24) -> ?secp384r1; -enum_to_oid(25) -> ?secp521r1. +enum_to_oid(25) -> ?secp521r1; +enum_to_oid(26) -> ?brainpoolP256r1; +enum_to_oid(27) -> ?brainpoolP384r1; +enum_to_oid(28) -> ?brainpoolP512r1. sufficent_ec_support() -> CryptoSupport = crypto:supports(), diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 54029ebe6d..bc7e68a86c 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% Copyright Ericsson AB 2007-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -130,7 +130,8 @@ api_tests() -> listen_socket, ssl_accept_timeout, ssl_recv_timeout, - versions_option + versions_option, + server_name_indication_option ]. session_tests() -> @@ -2804,6 +2805,47 @@ versions_option(Config) when is_list(Config) -> end, ssl_test_lib:check_result(ErrClient, {error, {tls_alert, "protocol version"}}). + + +%%-------------------------------------------------------------------- + +server_name_indication_option() -> + [{doc,"Test API server_name_indication option to connect."}]. +server_name_indication_option(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, + [{server_name_indication, disable} | + ClientOpts]} + ]), + + ssl_test_lib:check_result(Server, ok, Client0, ok), + Server ! listen, + + Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, + [{server_name_indication, Hostname} | ClientOpts] + }]), + ssl_test_lib:check_result(Server, ok, Client1, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client0), + ssl_test_lib:close(Client1). + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index a2dd3f5930..a6e0efed25 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 5.3.2 +SSL_VSN = 5.3.3 diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index fb6b8c8661..f23b5d4fe9 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -330,13 +330,18 @@ choice(F) -> end. get_line(P, Default) -> - case io:get_line(P) of + case line_string(io:get_line(P)) of "\n" -> Default; L -> L end. +%% If the standard input is set to binary mode +%% convert it to a list so we can properly match. +line_string(Binary) when is_binary(Binary) -> unicode:characters_to_list(Binary); +line_string(Other) -> Other. + mfa_string(Fun) when is_function(Fun) -> {module,M} = erlang:fun_info(Fun, module), {name,F} = erlang:fun_info(Fun, name), diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in index 3815027721..067663feb4 100644 --- a/lib/test_server/src/configure.in +++ b/lib/test_server/src/configure.in @@ -38,6 +38,35 @@ AC_ARG_ENABLE(debug-mode, *) CFLAGS=$DEBUG_FLAGS ;; esac ], ) +AC_ARG_ENABLE(m64-build, +AS_HELP_STRING([--enable-m64-build], + [build 64-bit binaries using the -m64 flag to (g)cc]), +[ case "$enableval" in + no) enable_m64_build=no ;; + *) enable_m64_build=yes ;; + esac +],enable_m64_build=no) + +AC_ARG_ENABLE(m32-build, +AS_HELP_STRING([--enable-m32-build], + [build 32-bit binaries using the -m32 flag to (g)cc]), +[ case "$enableval" in + no) enable_m32_build=no ;; + *) enable_m32_build=yes ;; + esac +],enable_m32_build=no) + +no_mXX_LDFLAGS="$LDFLAGS" + +if test X${enable_m64_build} = Xyes; then + CFLAGS="-m64 $CFLAGS" + LDFLAGS="-m64 $LDFLAGS" +fi +if test X${enable_m32_build} = Xyes; then + CFLAGS="-m32 $CFLAGS" + LDFLAGS="-m32 $LDFLAGS" +fi + AC_CHECK_LIB(m, sin) #-------------------------------------------------------------------- @@ -132,6 +161,12 @@ case $system in AC_CHECK_HEADER(dld.h, [ SHLIB_LD="ld" SHLIB_LDFLAGS="-shared"]) + if test X${enable_m64_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers) + fi + if test X${enable_m32_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers) + fi fi SHLIB_EXTRACT_ALL="" ;; @@ -142,11 +177,17 @@ case $system in SHLIB_LD="ld" SHLIB_LDFLAGS="$LDFLAGS -Bshareable -x" SHLIB_SUFFIX=".so" + if test X${enable_m64_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers) + fi + if test X${enable_m32_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers) + fi ], [ # No dynamic loading. SHLIB_CFLAGS="" SHLIB_LD="ld" - SHLIB_LDFLAGS="$LDFLAGS" + SHLIB_LDFLAGS="" SHLIB_SUFFIX="" AC_MSG_ERROR(don't know how to compile and link dynamic drivers) ]) @@ -155,7 +196,13 @@ case $system in *-solaris2*|*-sysv4*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="/usr/ccs/bin/ld" - SHLIB_LDFLAGS="$LDFLAGS -G -z text" + SHLIB_LDFLAGS="$no_mXX_LDFLAGS -G -z text" + if test X${enable_m64_build} = Xyes; then + SHLIB_LDFLAGS="-64 $SHLIB_LDFLAGS" + fi + if test X${enable_m32_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers) + fi SHLIB_SUFFIX=".so" SHLIB_EXTRACT_ALL="-z allextract" ;; @@ -170,6 +217,12 @@ case $system in SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld" SHLIB_LDFLAGS="$LDFLAGS -shared" + if test X${enable_m64_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers) + fi + if test X${enable_m32_build} = Xyes; then + AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers) + fi SHLIB_SUFFIX=".so" SHLIB_EXTRACT_ALL="" ;; diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl index e9e559df5d..bc62015ac3 100644 --- a/lib/test_server/src/ts_install.erl +++ b/lib/test_server/src/ts_install.erl @@ -112,6 +112,12 @@ get_vars([], name, [], Result) -> get_vars(_, _, _, _) -> {error, fatal_bad_conf_vars}. +config_flags() -> + case os:getenv("CONFIG_FLAGS") of + false -> []; + CF -> string:tokens(CF, " \t\n") + end. + unix_autoconf(XConf) -> Configure = filename:absname("configure"), Flags = proplists:get_value(crossflags,XConf,[]), @@ -122,11 +128,14 @@ unix_autoconf(XConf) -> erlang:system_info(threads) /= false], Debug = [" --enable-debug-mode" || string:str(erlang:system_info(system_version),"debug") > 0], - Args = Host ++ Build ++ Threads ++ Debug, + MXX_Build = [Y || Y <- config_flags(), + Y == "--enable-m64-build" + orelse Y == "--enable-m32-build"], + Args = Host ++ Build ++ Threads ++ Debug ++ " " ++ MXX_Build, case filelib:is_file(Configure) of true -> OSXEnv = macosx_cflags(), - io:format("Running ~sEnv: ~p~n", + io:format("Running ~s~nEnv: ~p~n", [lists:flatten(Configure ++ Args),Env++OSXEnv]), Port = open_port({spawn, lists:flatten(["\"",Configure,"\"",Args])}, [stream, eof, {env,Env++OSXEnv}]), @@ -135,7 +144,6 @@ unix_autoconf(XConf) -> {error, no_configure_script} end. - get_xcomp_flag(Flag, Flags) -> get_xcomp_flag(Flag, Flag, Flags). get_xcomp_flag(Flag, Tag, Flags) -> diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index c1e9bec6ae..fd90e3a870 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -620,7 +620,6 @@ resulting regexp is surrounded by \\_< and \\_>." "if" "let" "of" - "query" "receive" "try" "when") @@ -2608,7 +2607,7 @@ Value is list (stack token-start token-type in-what)." (erlang-skip-blank to))) (eq (following-char) ?\()) (erlang-push (list 'fun token (current-column)) stack))) - ((looking-at "\\(begin\\|query\\)[^_a-zA-Z0-9]") + ((looking-at "\\(begin\\)[^_a-zA-Z0-9]") (erlang-push (list 'begin token (current-column)) stack)) ;; Normal when case ;;((looking-at "when\\s ") @@ -3118,7 +3117,7 @@ This assumes that the preceding expression is either simple (defun erlang-at-keyword () "Are we looking at an Erlang keyword which will increase indentation?" - (looking-at (concat "\\(when\\|if\\|fun\\|case\\|begin\\|query\\|" + (looking-at (concat "\\(when\\|if\\|fun\\|case\\|begin\\|" "of\\|receive\\|after\\|catch\\|try\\)[^_a-zA-Z0-9]"))) (defun erlang-at-operator () @@ -1310,7 +1310,7 @@ determine_version_controller # Unset ERL_FLAGS and ERL_OTP<Major-VSN>_FLAGS during bootstrap to # prevent potential problems -otp_major_vsn=`cat erts/vsn.mk | grep SYSTEM_VSN | sed "s|SYSTEM_VSN[^=]*=[^0-9]*\([0-9]*\).*|\1|"` +otp_major_vsn=`cat erts/vsn.mk | grep SYSTEM_VSN | sed "s|SYSTEM_VSN[^=]*=[^0-9]*\([0-9]*\).*|\1|g"` erl_otp_flags="ERL_OTP${otp_major_vsn}_FLAGS" unset ERL_FLAGS unset ${erl_otp_flags} |